From f341086bcee3b9d5d847d17e16bcf3c887e8bcf4 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Wed, 25 Nov 2015 15:27:48 +0100 Subject: [PATCH] Removed php-di MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit ​Originally intended to phase out SingletonFactory and get rid of its downsides, there are a few issues that effectively prevent us from using DI right now: * There are a rather large amount of current singletons that impose a circular dependency on runtime, resolving these would require more changes to the API and the behavior than we're comfortable with * Being able to replace classes with a derived one is a great feature, but unfortunately the event system isn't exactly aware of this and unless one explicitly opts-in for inheritance, event listeners would not be executed. This could lead to rather unpredictable behaviors and debugging issues could be rather challenging * Only some classes qualify for DI, for instance SingletonFactory has a locked constructor that can be overriden without breaking BC. This leads to a mixture of "real" DI classes (using constructor injection) and others that explicitly invoke the DI container to fetch dependencies on runtime, negating one key aspect of DI (knowledge about dependencies w/o examining the class source) These are the major issues with the current implementation and we rather chose to ditch DI for now until we have proper solutions for all issues. Most likely this will mean that we won't see DI in the 2.x tree of WCF at all. --- .../files/lib/form/MessageForm.class.php | 2 +- .../lib/system/SingletonFactory.class.php | 35 +- .../install/files/lib/system/WCF.class.php | 33 +- .../install/files/lib/system/WCFACP.class.php | 4 - .../files/lib/system/WCFSetup.class.php | 9 +- .../files/lib/system/api/composer.json | 3 +- .../files/lib/system/api/composer.lock | 61 +--- .../system/api/composer/autoload_files.php | 1 - .../lib/system/api/composer/autoload_psr4.php | 1 - .../lib/system/api/composer/installed.json | 59 --- .../container-interop/.gitignore | 3 - .../container-interop/LICENSE | 20 - .../container-interop/README.md | 85 ----- .../container-interop/composer.json | 11 - .../docs/ContainerInterface-meta.md | 114 ------ .../docs/ContainerInterface.md | 153 -------- .../docs/Delegate-lookup-meta.md | 259 ------------- .../container-interop/docs/Delegate-lookup.md | 60 --- .../docs/images/interoperating_containers.png | Bin 35971 -> 0 bytes .../docs/images/priority.png | Bin 22949 -> 0 bytes .../docs/images/side_by_side_containers.png | Bin 22519 -> 0 bytes .../Interop/Container/ContainerInterface.php | 37 -- .../Exception/ContainerException.php | 13 - .../Container/Exception/NotFoundException.php | 13 - .../system/api/php-di/invoker/CONTRIBUTING.md | 15 - .../lib/system/api/php-di/invoker/LICENSE | 21 -- .../lib/system/api/php-di/invoker/README.md | 234 ------------ .../system/api/php-di/invoker/composer.json | 25 -- .../php-di/invoker/doc/parameter-resolvers.md | 109 ------ .../php-di/invoker/src/CallableResolver.php | 131 ------- .../src/Exception/InvocationException.php | 12 - .../src/Exception/NotCallableException.php | 12 - .../NotEnoughParametersException.php | 12 - .../system/api/php-di/invoker/src/Invoker.php | 122 ------- .../php-di/invoker/src/InvokerInterface.php | 29 -- .../AssociativeArrayResolver.php | 39 -- .../ParameterNameContainerResolver.php | 51 --- .../Container/TypeHintContainerResolver.php | 51 --- .../DefaultValueResolver.php | 40 -- .../NumericArrayResolver.php | 39 -- .../ParameterResolver/ParameterResolver.php | 33 -- .../src/ParameterResolver/ResolverChain.php | 69 ---- .../src/Reflection/CallableReflection.php | 57 --- .../system/api/php-di/php-di/.coveralls.yml | 2 - .../system/api/php-di/php-di/.gitattributes | 8 - .../lib/system/api/php-di/php-di/.gitignore | 9 - .../lib/system/api/php-di/php-di/.travis.yml | 26 -- .../files/lib/system/api/php-di/php-di/404.md | 3 - .../system/api/php-di/php-di/CONTRIBUTING.md | 52 --- .../lib/system/api/php-di/php-di/LICENSE | 18 - .../lib/system/api/php-di/php-di/README.md | 21 -- .../system/api/php-di/php-di/change-log.md | 303 ---------------- .../system/api/php-di/php-di/composer.json | 43 --- .../lib/system/api/php-di/php-di/couscous.yml | 110 ------ .../system/api/php-di/php-di/phpunit.xml.dist | 30 -- .../php-di/src/DI/Annotation/Inject.php | 95 ----- .../php-di/src/DI/Annotation/Injectable.php | 74 ---- .../php-di/php-di/src/DI/Cache/ArrayCache.php | 79 ---- .../api/php-di/php-di/src/DI/Container.php | 341 ------------------ .../php-di/php-di/src/DI/ContainerBuilder.php | 258 ------------- .../system/api/php-di/php-di/src/DI/Debug.php | 39 -- .../src/DI/Definition/AliasDefinition.php | 66 ---- .../src/DI/Definition/ArrayDefinition.php | 66 ---- .../Definition/ArrayDefinitionExtension.php | 61 ---- .../src/DI/Definition/CacheableDefinition.php | 19 - .../src/DI/Definition/DecoratorDefinition.php | 48 --- .../php-di/src/DI/Definition/Definition.php | 32 -- .../Dumper/AliasDefinitionDumper.php | 48 --- .../Dumper/ArrayDefinitionDumper.php | 65 ---- .../Dumper/DecoratorDefinitionDumper.php | 37 -- .../DI/Definition/Dumper/DefinitionDumper.php | 30 -- .../Dumper/DefinitionDumperDispatcher.php | 68 ---- .../EnvironmentVariableDefinitionDumper.php | 63 ---- .../Dumper/FactoryDefinitionDumper.php | 37 -- .../Dumper/ObjectDefinitionDumper.php | 158 -------- .../Dumper/StringDefinitionDumper.php | 37 -- .../Dumper/ValueDefinitionDumper.php | 44 --- .../src/DI/Definition/EntryReference.php | 52 --- .../EnvironmentVariableDefinition.php | 116 ------ .../Exception/AnnotationException.php | 19 - .../Exception/DefinitionException.php | 30 -- .../src/DI/Definition/FactoryDefinition.php | 75 ---- .../src/DI/Definition/HasSubDefinition.php | 28 -- .../Helper/ArrayDefinitionExtensionHelper.php | 46 --- .../DI/Definition/Helper/DefinitionHelper.php | 24 -- .../EnvironmentVariableDefinitionHelper.php | 64 ---- .../Helper/FactoryDefinitionHelper.php | 72 ---- .../Helper/ObjectDefinitionHelper.php | 279 -------------- .../Helper/StringDefinitionHelper.php | 39 -- .../Helper/ValueDefinitionHelper.php | 42 --- .../src/DI/Definition/InstanceDefinition.php | 76 ---- .../src/DI/Definition/ObjectDefinition.php | 337 ----------------- .../ObjectDefinition/MethodInjection.php | 94 ----- .../ObjectDefinition/PropertyInjection.php | 74 ---- .../DI/Definition/Resolver/AliasResolver.php | 63 ---- .../DI/Definition/Resolver/ArrayResolver.php | 91 ----- .../Definition/Resolver/DecoratorResolver.php | 93 ----- .../Resolver/DefinitionResolver.php | 44 --- .../Resolver/EnvironmentVariableResolver.php | 81 ----- .../Definition/Resolver/FactoryResolver.php | 82 ----- .../Definition/Resolver/InstanceInjector.php | 53 --- .../DI/Definition/Resolver/ObjectCreator.php | 258 ------------- .../Definition/Resolver/ParameterResolver.php | 140 ------- .../Resolver/ResolverDispatcher.php | 138 ------- .../DI/Definition/Resolver/StringResolver.php | 81 ----- .../DI/Definition/Resolver/ValueResolver.php | 44 --- .../DI/Definition/Source/AnnotationReader.php | 280 -------------- .../src/DI/Definition/Source/Autowiring.php | 68 ---- .../Source/CachedDefinitionSource.php | 104 ------ .../DI/Definition/Source/DefinitionArray.php | 142 -------- .../DI/Definition/Source/DefinitionFile.php | 74 ---- .../DI/Definition/Source/DefinitionSource.php | 31 -- .../Source/MutableDefinitionSource.php | 15 - .../src/DI/Definition/Source/SourceChain.php | 108 ------ .../src/DI/Definition/StringDefinition.php | 66 ---- .../src/DI/Definition/ValueDefinition.php | 67 ---- .../php-di/src/DI/DependencyException.php | 19 - .../php-di/php-di/src/DI/FactoryInterface.php | 34 -- .../Invoker/DefinitionParameterResolver.php | 66 ---- .../php-di/php-di/src/DI/InvokerInterface.php | 19 - .../php-di/src/DI/NotFoundException.php | 19 - .../php-di/src/DI/Proxy/ProxyFactory.php | 88 ----- .../Reflection/CallableReflectionFactory.php | 51 --- .../system/api/php-di/php-di/src/DI/Scope.php | 54 --- .../api/php-di/php-di/src/DI/functions.php | 181 ---------- .../api/php-di/phpdoc-reader/.gitattributes | 7 - .../api/php-di/phpdoc-reader/.gitignore | 5 - .../system/api/php-di/phpdoc-reader/LICENSE | 16 - .../system/api/php-di/phpdoc-reader/README.md | 59 --- .../api/php-di/phpdoc-reader/composer.json | 23 -- .../src/PhpDocReader/AnnotationException.php | 10 - .../src/PhpDocReader/PhpDocReader.php | 270 -------------- .../PhpDocReader/PhpParser/TokenParser.php | 159 -------- .../PhpParser/UseStatementParser.php | 68 ---- .../application/ApplicationHandler.class.php | 17 +- .../lib/system/event/EventHandler.class.php | 21 +- .../html/input/HtmlInputProcessor.class.php | 7 +- .../node/HtmlInputNodeProcessor.class.php | 3 +- .../HtmlInputNodeWoltlabMention.class.php | 11 - .../output/HtmlOutputNodeProcessor.class.php | 5 +- .../node/HtmlOutputNodeBlockquote.class.php | 11 +- .../HtmlOutputNodeWoltlabMention.class.php | 18 +- .../system/request/ControllerMap.class.php | 5 +- .../lib/system/request/LinkHandler.class.php | 44 +-- .../system/request/RequestHandler.class.php | 61 +--- .../lib/system/request/RouteHandler.class.php | 52 +-- .../route/DynamicRequestRoute.class.php | 54 +-- .../route/LookupRequestRoute.class.php | 13 +- .../route/StaticRequestRoute.class.php | 30 +- .../session/ACPSessionFactory.class.php | 29 +- .../system/session/SessionHandler.class.php | 4 +- 151 files changed, 103 insertions(+), 9487 deletions(-) delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/.gitignore delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/LICENSE delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/README.md delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/composer.json delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface-meta.md delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface.md delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/Delegate-lookup-meta.md delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/Delegate-lookup.md delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/interoperating_containers.png delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/priority.png delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/side_by_side_containers.png delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/src/Interop/Container/ContainerInterface.php delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php delete mode 100644 wcfsetup/install/files/lib/system/api/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/CONTRIBUTING.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/LICENSE delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/README.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/composer.json delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/doc/parameter-resolvers.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/CallableResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/InvocationException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotCallableException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotEnoughParametersException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/Invoker.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/InvokerInterface.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/AssociativeArrayResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/ParameterNameContainerResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/TypeHintContainerResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/DefaultValueResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/NumericArrayResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ParameterResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ResolverChain.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/invoker/src/Reflection/CallableReflection.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/.coveralls.yml delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/.gitattributes delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/.gitignore delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/.travis.yml delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/404.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/CONTRIBUTING.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/LICENSE delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/README.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/change-log.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/composer.json delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/couscous.yml delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/phpunit.xml.dist delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Inject.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Injectable.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Cache/ArrayCache.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Container.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/ContainerBuilder.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Debug.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/AliasDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinitionExtension.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/CacheableDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/DecoratorDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Definition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/AliasDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ArrayDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DecoratorDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumperDispatcher.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/EnvironmentVariableDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/FactoryDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ObjectDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/StringDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ValueDefinitionDumper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EntryReference.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EnvironmentVariableDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/AnnotationException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/DefinitionException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/FactoryDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/HasSubDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ArrayDefinitionExtensionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/DefinitionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/EnvironmentVariableDefinitionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/FactoryDefinitionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ObjectDefinitionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/StringDefinitionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ValueDefinitionHelper.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/InstanceDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/MethodInjection.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/PropertyInjection.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/AliasResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ArrayResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DecoratorResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DefinitionResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/EnvironmentVariableResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/FactoryResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/InstanceInjector.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ObjectCreator.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ParameterResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ResolverDispatcher.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/StringResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ValueResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/AnnotationReader.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/Autowiring.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/CachedDefinitionSource.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionArray.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionFile.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionSource.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/MutableDefinitionSource.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/SourceChain.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/StringDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ValueDefinition.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/DependencyException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/FactoryInterface.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Invoker/DefinitionParameterResolver.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/InvokerInterface.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/NotFoundException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Proxy/ProxyFactory.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Reflection/CallableReflectionFactory.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Scope.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/functions.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitattributes delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitignore delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/LICENSE delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/README.md delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/composer.json delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/AnnotationException.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpDocReader.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/TokenParser.php delete mode 100644 wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/UseStatementParser.php diff --git a/wcfsetup/install/files/lib/form/MessageForm.class.php b/wcfsetup/install/files/lib/form/MessageForm.class.php index ac4be97594..1a69b681ad 100644 --- a/wcfsetup/install/files/lib/form/MessageForm.class.php +++ b/wcfsetup/install/files/lib/form/MessageForm.class.php @@ -302,7 +302,7 @@ abstract class MessageForm extends AbstractCaptchaForm { public function save() { parent::save(); - $htmlInputProcessor = WCF::getDIContainer()->make(HtmlInputProcessor::class); + $htmlInputProcessor = new HtmlInputProcessor(); $this->text = $htmlInputProcessor->process($this->text); // parse URLs diff --git a/wcfsetup/install/files/lib/system/SingletonFactory.class.php b/wcfsetup/install/files/lib/system/SingletonFactory.class.php index 69ac610654..677178321c 100644 --- a/wcfsetup/install/files/lib/system/SingletonFactory.class.php +++ b/wcfsetup/install/files/lib/system/SingletonFactory.class.php @@ -4,21 +4,26 @@ use wcf\system\exception\SystemException; /** * Basis class for singleton classes. - * + * * @author Alexander Ebert * @copyright 2001-2015 WoltLab GmbH * @license GNU Lesser General Public License * @package com.woltlab.wcf * @subpackage system * @category Community Framework - * @deprecated 2.2 */ abstract class SingletonFactory { + /** + * list of singletons + * @var SingletonFactory[] + */ + protected static $__singletonObjects = array(); + /** * Singletons do not support a public constructor. Override init() if * your class needs to initialize components on creation. */ - public function __construct() { + protected final function __construct() { $this->init(); } @@ -41,10 +46,30 @@ abstract class SingletonFactory { /** * Returns an unique instance of current child class. - * + * * @return static */ public static final function getInstance() { - return WCF::getDIContainer()->get(get_called_class()); + $className = get_called_class(); + if (!array_key_exists($className, self::$__singletonObjects)) { + self::$__singletonObjects[$className] = null; + self::$__singletonObjects[$className] = new $className(); + } + else if (self::$__singletonObjects[$className] === null) { + throw new SystemException("Infinite loop detected while trying to retrieve object for '".$className."'"); + } + + return self::$__singletonObjects[$className]; + } + + /** + * Returns whether this singleton is already initialized. + * + * @return boolean + */ + public static final function isInitialized() { + $className = get_called_class(); + + return isset(self::$__singletonObjects[$className]); } } diff --git a/wcfsetup/install/files/lib/system/WCF.class.php b/wcfsetup/install/files/lib/system/WCF.class.php index 17bbb79dbc..385c5e4797 100644 --- a/wcfsetup/install/files/lib/system/WCF.class.php +++ b/wcfsetup/install/files/lib/system/WCF.class.php @@ -1,12 +1,12 @@ + * @var Application[] */ protected static $applications = array(); @@ -96,12 +96,6 @@ class WCF { */ protected static $dbObj = null; - /** - * dependency injection container - * @var \DI\Container - */ - protected static $diContainer = null; - /** * language object * @var \wcf\data\language\Language @@ -142,9 +136,6 @@ class WCF { // define tmp directory if (!defined('TMP_DIR')) define('TMP_DIR', FileUtil::getTempFolder()); - $builder = new ContainerBuilder(); - self::$diContainer = $builder->build(); - // start initialization $this->initDB(); $this->loadOptions(); @@ -159,15 +150,6 @@ class WCF { EventHandler::getInstance()->fireAction($this, 'initialized'); } - /** - * Returns the dependency injection container. - * - * @return \DI\Container - */ - public static final function getDIContainer() { - return self::$diContainer; - } - /** * Flushes the output, closes the session, performs background tasks and more. * @@ -325,10 +307,10 @@ class WCF { * Starts the session system. */ protected function initSession() { - $factory = self::$diContainer->get(SessionFactory::class); + $factory = new SessionFactory(); $factory->load(); - self::$sessionObj = self::$diContainer->get(SessionHandler::class); + self::$sessionObj = SessionHandler::getInstance(); self::$sessionObj->setHasValidCookie($factory->hasValidCookie()); } @@ -346,14 +328,14 @@ class WCF { mb_language('uni'); // get language - self::$languageObj = self::$diContainer->get(LanguageFactory::class)->getUserLanguage(self::getSession()->getLanguageID()); + self::$languageObj = LanguageFactory::getInstance()->getUserLanguage(self::getSession()->getLanguageID()); } /** * Initialises the template engine. */ protected function initTPL() { - self::$tplObj = self::$diContainer->get(TemplateEngine::class); + self::$tplObj = TemplateEngine::getInstance(); self::getTPL()->setLanguageID(self::getLanguage()->languageID); $this->assignDefaultTemplateVariables(); @@ -368,7 +350,7 @@ class WCF { self::getSession()->setStyleID(intval($_REQUEST['styleID'])); } - $styleHandler = self::$diContainer->get(StyleHandler::class); + $styleHandler = StyleHandler::getInstance(); $styleHandler->changeStyle(self::getSession()->getStyleID()); } @@ -458,6 +440,7 @@ class WCF { // step 2) run each application if (!class_exists('wcf\system\WCFACP', false)) { + /** @var IApplication $application */ foreach ($loadedApplications as $application) { $application->__run(); } diff --git a/wcfsetup/install/files/lib/system/WCFACP.class.php b/wcfsetup/install/files/lib/system/WCFACP.class.php index 6eab8d5e53..109adac4e9 100644 --- a/wcfsetup/install/files/lib/system/WCFACP.class.php +++ b/wcfsetup/install/files/lib/system/WCFACP.class.php @@ -1,6 +1,5 @@ build(); - // start initialization $this->initDB(); $this->loadOptions(); diff --git a/wcfsetup/install/files/lib/system/WCFSetup.class.php b/wcfsetup/install/files/lib/system/WCFSetup.class.php index 9e0b2c8bf3..8880721ba6 100644 --- a/wcfsetup/install/files/lib/system/WCFSetup.class.php +++ b/wcfsetup/install/files/lib/system/WCFSetup.class.php @@ -1,6 +1,5 @@ build(); - $this->getDeveloperMode(); $this->getLanguageSelection(); $this->getWCFDir(); @@ -1159,7 +1152,7 @@ class WCFSetup extends WCF { } // login as admin - $factory = WCF::getDIContainer()->make(ACPSessionFactory::class); + $factory = new ACPSessionFactory(); $factory->load(); SessionHandler::getInstance()->changeUser($admin); diff --git a/wcfsetup/install/files/lib/system/api/composer.json b/wcfsetup/install/files/lib/system/api/composer.json index 0a75819c0b..19d6b352a0 100644 --- a/wcfsetup/install/files/lib/system/api/composer.json +++ b/wcfsetup/install/files/lib/system/api/composer.json @@ -3,7 +3,6 @@ "vendor-dir": "./" }, "require": { - "ezyang/htmlpurifier": "4.7.*", - "php-di/php-di": "5.1.*" + "ezyang/htmlpurifier": "4.7.*" } } diff --git a/wcfsetup/install/files/lib/system/api/composer.lock b/wcfsetup/install/files/lib/system/api/composer.lock index 83cb812555..81c8f294c5 100644 --- a/wcfsetup/install/files/lib/system/api/composer.lock +++ b/wcfsetup/install/files/lib/system/api/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "cd00e4c8e538bb4769bfed7eddcb4e28", - "content-hash": "6867afc3a51e9cdeb9a855131601864e", + "hash": "7364a2d47c47ff382d4617f4ac22e35c", + "content-hash": "02969f5fb096600e5baaf84af039646e", "packages": [ { "name": "container-interop/container-interop", @@ -121,63 +121,6 @@ ], "time": "2015-10-22 19:49:23" }, - { - "name": "php-di/php-di", - "version": "5.1.0", - "source": { - "type": "git", - "url": "https://github.com/PHP-DI/PHP-DI.git", - "reference": "f4a8088fa4eb480ee66c51b5ee4e4e30cce78489" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/f4a8088fa4eb480ee66c51b5ee4e4e30cce78489", - "reference": "f4a8088fa4eb480ee66c51b5ee4e4e30cce78489", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "~1.0", - "php": ">=5.4.0", - "php-di/invoker": "^1.0.1", - "php-di/phpdoc-reader": "~2.0" - }, - "replace": { - "mnapoli/php-di": "*" - }, - "require-dev": { - "doctrine/annotations": "~1.2", - "doctrine/cache": "~1.4", - "mnapoli/phpunit-easymock": "~0.1.4", - "ocramius/proxy-manager": "~1.0", - "phpunit/phpunit": "~4.5" - }, - "suggest": { - "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", - "doctrine/cache": "Install it if you want to use the cache (version ~1.4)", - "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~1.0)" - }, - "type": "library", - "autoload": { - "psr-4": { - "DI\\": "src/DI/" - }, - "files": [ - "src/DI/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The dependency injection container for humans", - "homepage": "http://php-di.org/", - "keywords": [ - "container", - "dependency injection", - "di" - ], - "time": "2015-09-08 08:56:29" - }, { "name": "php-di/phpdoc-reader", "version": "2.0.0", diff --git a/wcfsetup/install/files/lib/system/api/composer/autoload_files.php b/wcfsetup/install/files/lib/system/api/composer/autoload_files.php index 5bf8a74f35..682ac2e2b4 100644 --- a/wcfsetup/install/files/lib/system/api/composer/autoload_files.php +++ b/wcfsetup/install/files/lib/system/api/composer/autoload_files.php @@ -6,6 +6,5 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = $vendorDir; return array( - $vendorDir . '/php-di/php-di/src/DI/functions.php', $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', ); diff --git a/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php b/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php index 127166e239..2ccd01ea12 100644 --- a/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php +++ b/wcfsetup/install/files/lib/system/api/composer/autoload_psr4.php @@ -9,5 +9,4 @@ return array( 'PhpDocReader\\' => array($vendorDir . '/php-di/phpdoc-reader/src/PhpDocReader'), 'Invoker\\' => array($vendorDir . '/php-di/invoker/src'), 'Interop\\Container\\' => array($vendorDir . '/container-interop/container-interop/src/Interop/Container'), - 'DI\\' => array($vendorDir . '/php-di/php-di/src/DI'), ); diff --git a/wcfsetup/install/files/lib/system/api/composer/installed.json b/wcfsetup/install/files/lib/system/api/composer/installed.json index f812749ca8..24c222c2b0 100644 --- a/wcfsetup/install/files/lib/system/api/composer/installed.json +++ b/wcfsetup/install/files/lib/system/api/composer/installed.json @@ -112,65 +112,6 @@ "invoker" ] }, - { - "name": "php-di/php-di", - "version": "5.1.0", - "version_normalized": "5.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/PHP-DI/PHP-DI.git", - "reference": "f4a8088fa4eb480ee66c51b5ee4e4e30cce78489" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/f4a8088fa4eb480ee66c51b5ee4e4e30cce78489", - "reference": "f4a8088fa4eb480ee66c51b5ee4e4e30cce78489", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "~1.0", - "php": ">=5.4.0", - "php-di/invoker": "^1.0.1", - "php-di/phpdoc-reader": "~2.0" - }, - "replace": { - "mnapoli/php-di": "*" - }, - "require-dev": { - "doctrine/annotations": "~1.2", - "doctrine/cache": "~1.4", - "mnapoli/phpunit-easymock": "~0.1.4", - "ocramius/proxy-manager": "~1.0", - "phpunit/phpunit": "~4.5" - }, - "suggest": { - "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", - "doctrine/cache": "Install it if you want to use the cache (version ~1.4)", - "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~1.0)" - }, - "time": "2015-09-08 08:56:29", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "DI\\": "src/DI/" - }, - "files": [ - "src/DI/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The dependency injection container for humans", - "homepage": "http://php-di.org/", - "keywords": [ - "container", - "dependency injection", - "di" - ] - }, { "name": "ezyang/htmlpurifier", "version": "v4.7.0", diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/.gitignore b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/.gitignore deleted file mode 100644 index b2395aa055..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -composer.lock -composer.phar -/vendor/ diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/LICENSE b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/LICENSE deleted file mode 100644 index 7671d9020f..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 container-interop - -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/wcfsetup/install/files/lib/system/api/container-interop/container-interop/README.md b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/README.md deleted file mode 100644 index ec434d0f26..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# Container Interoperability - -[![Latest Stable Version](https://poser.pugx.org/container-interop/container-interop/v/stable.png)](https://packagist.org/packages/container-interop/container-interop) - -*container-interop* tries to identify and standardize features in *container* objects (service locators, -dependency injection containers, etc.) to achieve interopererability. - -Through discussions and trials, we try to create a standard, made of common interfaces but also recommendations. - -If PHP projects that provide container implementations begin to adopt these common standards, then PHP -applications and projects that use containers can depend on the common interfaces instead of specific -implementations. This facilitates a high-level of interoperability and flexibility that allows users to consume -*any* container implementation that can be adapted to these interfaces. - -The work done in this project is not officially endorsed by the [PHP-FIG](http://www.php-fig.org/), but it is being -worked on by members of PHP-FIG and other good developers. We adhere to the spirit and ideals of PHP-FIG, and hope -this project will pave the way for one or more future PSRs. - - -## Installation - -You can install this package through Composer: - -```json -{ - "require": { - "container-interop/container-interop": "~1.0" - } -} -``` - -The packages adheres to the [SemVer](http://semver.org/) specification, and there will be full backward compatibility -between minor versions. - -## Standards - -### Available - -- [`ContainerInterface`](src/Interop/Container/ContainerInterface.php). -[Description](docs/ContainerInterface.md) [Meta Document](docs/ContainerInterface-meta.md). -Describes the interface of a container that exposes methods to read its entries. -- [*Delegate lookup feature*](docs/Delegate-lookup.md). -[Meta Document](docs/Delegate-lookup-meta.md). -Describes the ability for a container to delegate the lookup of its dependencies to a third-party container. This -feature lets several containers work together in a single application. - -### Proposed - -View open [request for comments](https://github.com/container-interop/container-interop/labels/RFC) - -## Compatible projects - -### Projects implementing `ContainerInterface` - -- [Acclimate](https://github.com/jeremeamia/acclimate-container) -- [dcp-di](https://github.com/estelsmith/dcp-di) -- [Mouf](http://mouf-php.com) -- [Njasm Container](https://github.com/njasm/container) -- [PHP-DI](http://php-di.org) -- [PimpleInterop](https://github.com/moufmouf/pimple-interop) -- [XStatic](https://github.com/jeremeamia/xstatic) - -### Projects implementing the *delegate lookup* feature - -- [Mouf](http://mouf-php.com) -- [PHP-DI](http://php-di.org) -- [PimpleInterop](https://github.com/moufmouf/pimple-interop) - -## Workflow - -Everyone is welcome to join and contribute. - -The general workflow looks like this: - -1. Someone opens a discussion (GitHub issue) to suggest an interface -1. Feedback is gathered -1. The interface is added to a development branch -1. We release alpha versions so that the interface can be experimented with -1. Discussions and edits ensue until the interface is deemed stable by a general consensus -1. A new minor version of the package is released - -We try to not break BC by creating new interfaces instead of editing existing ones. - -While we currently work on interfaces, we are open to anything that might help towards interoperability, may that -be code, best practices, etc. diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/composer.json b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/composer.json deleted file mode 100644 index 84f3875282..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/composer.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "container-interop/container-interop", - "type": "library", - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "license": "MIT", - "autoload": { - "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" - } - } -} diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface-meta.md b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface-meta.md deleted file mode 100644 index 90711c9051..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface-meta.md +++ /dev/null @@ -1,114 +0,0 @@ -# ContainerInterface Meta Document - -## Introduction - -This document describes the process and discussions that lead to the `ContainerInterface`. -Its goal is to explain the reasons behind each decision. - -## Goal - -The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a -container to obtain objects and parameters. - -By standardizing such a behavior, frameworks and libraries using the `ContainerInterface` -could work with any compatible container. -That would allow end users to choose their own container based on their own preferences. - -It is important to distinguish the two usages of a container: - -- configuring entries -- fetching entries - -Most of the time, those two sides are not used by the same party. -While it is often end users who tend to configure entries, it is generally the framework that fetch -entries to build the application. - -This is why this interface focuses only on how entries can be fetched from a container. - -## Interface name - -The interface name has been thoroughly discussed and was decided by a vote. - -The list of options considered with their respective votes are: - -- `ContainerInterface`: +8 -- `ProviderInterface`: +2 -- `LocatorInterface`: 0 -- `ReadableContainerInterface`: -5 -- `ServiceLocatorInterface`: -6 -- `ObjectFactory`: -6 -- `ObjectStore`: -8 -- `ConsumerInterface`: -9 - -[Full results of the vote](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote) - -The complete discussion can be read in [the issue #1](https://github.com/container-interop/container-interop/issues/1). - -## Interface methods - -The choice of which methods the interface would contain was made after a statistical analysis of existing containers. -The results of this analysis are available [in this document](https://gist.github.com/mnapoli/6159681). - -The summary of the analysis showed that: - -- all containers offer a method to get an entry by its id -- a large majority name such method `get()` -- for all containers, the `get()` method has 1 mandatory parameter of type string -- some containers have an optional additional argument for `get()`, but it doesn't same the same purpose between containers -- a large majority of the containers offer a method to test if it can return an entry by its id -- a majority name such method `has()` -- for all containers offering `has()`, the method has exactly 1 parameter of type string -- a large majority of the containers throw an exception rather than returning null when an entry is not found in `get()` -- a large majority of the containers don't implement `ArrayAccess` - -The question of whether to include methods to define entries has been discussed in -[issue #1](https://github.com/container-interop/container-interop/issues/1). -It has been judged that such methods do not belong in the interface described here because it is out of its scope -(see the "Goal" section). - -As a result, the `ContainerInterface` contains two methods: - -- `get()`, returning anything, with one mandatory string parameter. Should throw an exception if the entry is not found. -- `has()`, returning a boolean, with one mandatory string parameter. - -### Number of parameters in `get()` method - -While `ContainerInterface` only defines one mandatory parameter in `get()`, it is not incompatible with -existing containers that have additional optional parameters. PHP allows an implementation to offer more parameters -as long as they are optional, because the implementation *does* satisfy the interface. - -This issue has been discussed in [issue #6](https://github.com/container-interop/container-interop/issues/6). - -### Type of the `$id` parameter - -The type of the `$id` parameter in `get()` and `has()` has been discussed in -[issue #6](https://github.com/container-interop/container-interop/issues/6). -While `string` is used in all the containers that were analyzed, it was suggested that allowing -anything (such as objects) could allow containers to offer a more advanced query API. - -An example given was to use the container as an object builder. The `$id` parameter would then be an -object that would describe how to create an instance. - -The conclusion of the discussion was that this was beyond the scope of getting entries from a container without -knowing how the container provided them, and it was more fit for a factory. - -## Contributors - -Are listed here all people that contributed in the discussions or votes, by alphabetical order: - -- [Amy Stephen](https://github.com/AmyStephen) -- [David Négrier](https://github.com/moufmouf) -- [Don Gilbert](https://github.com/dongilbert) -- [Jason Judge](https://github.com/judgej) -- [Jeremy Lindblom](https://github.com/jeremeamia) -- [Marco Pivetta](https://github.com/Ocramius) -- [Matthieu Napoli](https://github.com/mnapoli) -- [Paul M. Jones](https://github.com/pmjones) -- [Stephan Hochdörfer](https://github.com/shochdoerfer) -- [Taylor Otwell](https://github.com/taylorotwell) - -## Relevant links - -- [`ContainerInterface.php`](https://github.com/container-interop/container-interop/blob/master/src/Interop/Container/ContainerInterface.php) -- [List of all issues](https://github.com/container-interop/container-interop/issues?labels=ContainerInterface&milestone=&page=1&state=closed) -- [Vote for the interface name](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote) diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface.md b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface.md deleted file mode 100644 index 9f609674c8..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/ContainerInterface.md +++ /dev/null @@ -1,153 +0,0 @@ -Container interface -=================== - -This document describes a common interface for dependency injection containers. - -The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a -container to obtain objects and parameters (called *entries* in the rest of this document). - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", -"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be -interpreted as described in [RFC 2119][]. - -The word `implementor` in this document is to be interpreted as someone -implementing the `ContainerInterface` in a depency injection-related library or framework. -Users of dependency injections containers (DIC) are refered to as `user`. - -[RFC 2119]: http://tools.ietf.org/html/rfc2119 - -1. Specification ------------------ - -### 1.1 Basics - -- The `Interop\Container\ContainerInterface` exposes two methods : `get` and `has`. - -- `get` takes one mandatory parameter: an entry identifier. It MUST be a string. - A call to `get` can return anything (a *mixed* value), or throws an exception if the identifier - is not known to the container. Two successive calls to `get` with the same - identifier SHOULD return the same value. However, depending on the `implementor` - design and/or `user` configuration, different values might be returned, so - `user` SHOULD NOT rely on getting the same value on 2 successive calls. - While `ContainerInterface` only defines one mandatory parameter in `get()`, implementations - MAY accept additional optional parameters. - -- `has` takes one unique parameter: an entry identifier. It MUST return `true` - if an entry identifier is known to the container and `false` if it is not. - -### 1.2 Exceptions - -Exceptions directly thrown by the container MUST implement the -[`Interop\Container\Exception\ContainerException`](../src/Interop/Container/Exception/ContainerException.php). - -A call to the `get` method with a non-existing id should throw a -[`Interop\Container\Exception\NotFoundException`](../src/Interop/Container/Exception/NotFoundException.php). - -### 1.3 Additional features - -This section describes additional features that MAY be added to a container. Containers are not -required to implement these features to respect the ContainerInterface. - -#### 1.3.1 Delegate lookup feature - -The goal of the *delegate lookup* feature is to allow several containers to share entries. -Containers implementing this feature can perform dependency lookups in other containers. - -Containers implementing this feature will offer a greater lever of interoperability -with other containers. Implementation of this feature is therefore RECOMMENDED. - -A container implementing this feature: - -- MUST implement the `ContainerInterface` -- MUST provide a way to register a delegate container (using a constructor parameter, or a setter, - or any possible way). The delegate container MUST implement the `ContainerInterface`. - -When a container is configured to use a delegate container for dependencies: - -- Calls to the `get` method should only return an entry if the entry is part of the container. - If the entry is not part of the container, an exception should be thrown - (as requested by the `ContainerInterface`). -- Calls to the `has` method should only return `true` if the entry is part of the container. - If the entry is not part of the container, `false` should be returned. -- If the fetched entry has dependencies, **instead** of performing - the dependency lookup in the container, the lookup is performed on the *delegate container*. - -Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself. - -It is however allowed for containers to provide exception cases for special entries, and a way to lookup -into the same container (or another container) instead of the delegate container. - -2. Package ----------- - -The interfaces and classes described as well as relevant exception are provided as part of the -[container-interop/container-interop](https://packagist.org/packages/container-interop/container-interop) package. - -3. `Interop\Container\ContainerInterface` ------------------------------------------ - -```php -setParentContainer($this); - } - } - ... - } -} - -``` - -**Cons:** - -Cons have been extensively discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777). -Basically, forcing a setter into an interface is a bad idea. Setters are similar to constructor arguments, -and it's a bad idea to standardize a constructor: how the delegate container is configured into a container is an implementation detail. This outweights the benefits of the interface. - -### 4.4 Alternative: no exception case for delegate lookups - -Originally, the proposed wording for delegate lookup calls was: - -> Important! The lookup MUST be performed on the delegate container **only**, not on the container itself. - -This was later replaced by: - -> Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself. -> -> It is however allowed for containers to provide exception cases for special entries, and a way to lookup -> into the same container (or another container) instead of the delegate container. - -Exception cases have been allowed to avoid breaking dependencies with some services that must be provided -by the container (on @njasm proposal). This was proposed here: https://github.com/container-interop/container-interop/pull/20#issuecomment-56597235 - -### 4.5 Alternative: having one of the containers act as the composite container - -In real-life scenarios, we usually have a big framework (Symfony 2, Zend Framework 2, etc...) and we want to -add another DI container to this container. Most of the time, the "big" framework will be responsible for -creating the controller's instances, using it's own DI container. Until *container-interop* is fully adopted, -the "big" framework will not be aware of the existence of a composite container that it should use instead -of its own container. - -For this real-life use cases, @mnapoli and @moufmouf proposed to extend the "big" framework's DI container -to make it act as a composite container. - -This has been discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-40367194) -and [here](http://mouf-php.com/container-interop-whats-next#solution4). - -This was implemented in Symfony 2 using: - -- [interop.symfony.di](https://github.com/thecodingmachine/interop.symfony.di/tree/v0.1.0) -- [framework interop](https://github.com/mnapoli/framework-interop/) - -This was implemented in Silex using: - -- [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di) - -Having a container act as the composite container is not part of the delegate lookup standard because it is -simply a temporary design pattern used to make existing frameworks that do not support yet ContainerInterop -play nice with other DI containers. - - -5. Implementations ------------------- - -The following projects already implement the delegate lookup feature: - -- [Mouf](http://mouf-php.com), through the [`setDelegateLookupContainer` method](https://github.com/thecodingmachine/mouf/blob/2.0/src/Mouf/MoufManager.php#L2120) -- [PHP-DI](http://php-di.org/), through the [`$wrapperContainer` parameter of the constructor](https://github.com/mnapoli/PHP-DI/blob/master/src/DI/Container.php#L72) -- [pimple-interop](https://github.com/moufmouf/pimple-interop), through the [`$container` parameter of the constructor](https://github.com/moufmouf/pimple-interop/blob/master/src/Interop/Container/Pimple/PimpleInterop.php#L62) - -6. People ---------- - -Are listed here all people that contributed in the discussions, by alphabetical order: - -- [Alexandru Pătrănescu](https://github.com/drealecs) -- [Ben Peachey](https://github.com/potherca) -- [David Négrier](https://github.com/moufmouf) -- [Jeremy Lindblom](https://github.com/jeremeamia) -- [Marco Pivetta](https://github.com/Ocramius) -- [Matthieu Napoli](https://github.com/mnapoli) -- [Nelson J Morais](https://github.com/njasm) -- [Phil Sturgeon](https://github.com/philsturgeon) -- [Stephan Hochdörfer](https://github.com/shochdoerfer) - -7. Relevant Links ------------------ - -_**Note:** Order descending chronologically._ - -- [Pull request on the delegate lookup feature](https://github.com/container-interop/container-interop/pull/20) -- [Pull request on the interface idea](https://github.com/container-interop/container-interop/pull/8) -- [Original article exposing the delegate lookup idea along many others](http://mouf-php.com/container-interop-whats-next) - diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/Delegate-lookup.md b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/Delegate-lookup.md deleted file mode 100644 index 04eb3aea02..0000000000 --- a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/Delegate-lookup.md +++ /dev/null @@ -1,60 +0,0 @@ -Delegate lookup feature -======================= - -This document describes a standard for dependency injection containers. - -The goal set by the *delegate lookup* feature is to allow several containers to share entries. -Containers implementing this feature can perform dependency lookups in other containers. - -Containers implementing this feature will offer a greater lever of interoperability -with other containers. Implementation of this feature is therefore RECOMMENDED. - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", -"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be -interpreted as described in [RFC 2119][]. - -The word `implementor` in this document is to be interpreted as someone -implementing the delegate lookup feature in a dependency injection-related library or framework. -Users of dependency injections containers (DIC) are refered to as `user`. - -[RFC 2119]: http://tools.ietf.org/html/rfc2119 - -1. Vocabulary -------------- - -In a dependency injection container, the container is used to fetch entries. -Entries can have dependencies on other entries. Usually, these other entries are fetched by the container. - -The *delegate lookup* feature is the ability for a container to fetch dependencies in -another container. In the rest of the document, the word "container" will reference the container -implemented by the implementor. The word "delegate container" will reference the container we are -fetching the dependencies from. - -2. Specification ----------------- - -A container implementing the *delegate lookup* feature: - -- MUST implement the [`ContainerInterface`](ContainerInterface.md) -- MUST provide a way to register a delegate container (using a constructor parameter, or a setter, - or any possible way). The delegate container MUST implement the [`ContainerInterface`](ContainerInterface.md). - -When a container is configured to use a delegate container for dependencies: - -- Calls to the `get` method should only return an entry if the entry is part of the container. - If the entry is not part of the container, an exception should be thrown - (as requested by the [`ContainerInterface`](ContainerInterface.md)). -- Calls to the `has` method should only return `true` if the entry is part of the container. - If the entry is not part of the container, `false` should be returned. -- If the fetched entry has dependencies, **instead** of performing - the dependency lookup in the container, the lookup is performed on the *delegate container*. - -Important: By default, the dependency lookups SHOULD be performed on the delegate container **only**, not on the container itself. - -It is however allowed for containers to provide exception cases for special entries, and a way to lookup -into the same container (or another container) instead of the delegate container. - -3. Package / Interface ----------------------- - -This feature is not tied to any code, interface or package. diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/interoperating_containers.png b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/interoperating_containers.png deleted file mode 100644 index 9c672e16c72a08708ea5bdeb51757c2951d3ee66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35971 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 diff --git a/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/priority.png b/wcfsetup/install/files/lib/system/api/container-interop/container-interop/docs/images/priority.png deleted file mode 100644 index 5760dc71b557fea7ec5bd5699adfd1c228b9cdec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22949 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'/project/{project}/issue/{issue}', function ($project, $issue) { - // ... -}); -``` - -Or this command defined with [Silly](https://github.com/mnapoli/silly#usage): - -```php -$app->command('greet [name] [--yell]', function ($name, $yell) { - // ... -}); -``` - -Same pattern in [Slim](http://www.slimframework.com): - -```php -$app->get('/hello/:name', function ($name) { - // ... -}); -``` - -You get the point. These frameworks invoke the controller/command/handler using something akin to named parameters: whatever the order of the parameters, they are matched by their name. - -**This library allows to invoke callables with named parameters in a generic and extensible way.** - -### Dependency injection - -Anyone familiar with AngularJS is familiar with how dependency injection is performed: - -```js -angular.controller('MyController', ['dep1', 'dep2', function(dep1, dep2) { - // ... -}]); -``` - -In PHP we find this pattern again in some frameworks and DI containers with partial to full support. For example in Silex you can type-hint the application to get it injected, but it only works with `Silex\Application`: - -```php -$app->get('/hello/{name}', function (Silex\Application $app, $name) { - // ... -}); -``` - -In Silly, it only works with `OutputInterface` to inject the application output: - -```php -$app->command('greet [name]', function ($name, OutputInterface $output) { - // ... -}); -``` - -[PHP-DI](http://php-di.org/doc/container.html) provides a way to invoke a callable and resolve all dependencies from the container using type-hints: - -```php -$container->call(function (Logger $logger, EntityManager $em) { - // ... -}); -``` - -**This library provides clear extension points to let frameworks implement any kind of dependency injection support they want.** - -### TL/DR - -In short, this library is meant to be a base building block for calling a function with named parameters and/or dependency injection. - -## Installation - -```sh -$ composer require PHP-DI/invoker -``` - -## Usage - -### Default behavior - -By default the `Invoker` can call using named parameters: - -```php -$invoker = new Invoker\Invoker; - -$invoker->call(function () { - echo 'Hello world!'; -}); - -// Simple parameter array -$invoker->call(function ($name) { - echo 'Hello ' . $name; -}, ['John']); - -// Named parameters -$invoker->call(function ($name) { - echo 'Hello ' . $name; -}, [ - 'name' => 'John' -]); - -// Use the default value -$invoker->call(function ($name = 'world') { - echo 'Hello ' . $name; -}); - -// Invoke any PHP callable -$invoker->call(['MyClass', 'myStaticMethod']); - -// Using Class::method syntax -$invoker->call('MyClass::myStaticMethod'); -``` - -Dependency injection in parameters is supported but needs to be configured with your container. Read on or jump to [*Built-in support for dependency injection*](#built-in-support-for-dependency-injection) if you are impatient. - -Additionally, callables can also be resolved from your container. Read on or jump to [*Resolving callables from a container*](#resolving-callables-from-a-container) if you are impatient. - -### Parameter resolvers - -Extending the behavior of the `Invoker` is easy and is done by implementing a [`ParameterResolver`](https://github.com/PHP-DI/Invoker/blob/master/src/ParameterResolver/ParameterResolver.php). - -This is explained in details the [Parameter resolvers documentation](doc/parameter-resolvers.md). - -#### Built-in support for dependency injection - -Rather than have you re-implement support for dependency injection with different containers every time, this package ships with 2 optional resolvers: - -- [`TypeHintContainerResolver`](https://github.com/PHP-DI/Invoker/blob/master/src/ParameterResolver/Container/TypeHintContainerResolver.php) - - This resolver will inject container entries by searching for the class name using the type-hint: - - ```php - $invoker->call(function (Psr\Logger\LoggerInterface $logger) { - // ... - }); - ``` - - In this example it will `->get('Psr\Logger\LoggerInterface')` from the container and inject it. - - This resolver is only useful if you store objects in your container using the class (or interface) name. Silex or Symfony for example store services under a custom name (e.g. `twig`, `db`, etc.) instead of the class name: in that case use the resolver shown below. - -- [`ParameterNameContainerResolver`](https://github.com/PHP-DI/Invoker/blob/master/src/ParameterResolver/Container/ParameterNameContainerResolver.php) - - This resolver will inject container entries by searching for the name of the parameter: - - ```php - $invoker->call(function ($twig) { - // ... - }); - ``` - - In this example it will `->get('twig')` from the container and inject it. - -These resolvers can work with any dependency injection container compliant with [container-interop](https://github.com/container-interop/container-interop). If you container is not compliant you can use the [Acclimate](https://github.com/jeremeamia/acclimate-container) package. - -Setting up those resolvers is simple: - -```php -// $container must be an instance of Interop\Container\ContainerInterface -$container = ... - -$containerResolver = new TypeHintContainerResolver($container); -// or -$containerResolver = new ParameterNameContainerResolver($container); - -$invoker = new Invoker\Invoker; -// Register it before all the other parameter resolvers -$invoker->getParameterResolver()->prependResolver($containerResolver); -``` - -You can also register both resolvers at the same time if you wish by prepending both. Implementing support for more tricky things is easy and up to you! - -### Resolving callables from a container - -The `Invoker` can be wired to your DI container to resolve the callables. - -For example with an invokable class: - -```php -class MyHandler -{ - public function __invoke() - { - // ... - } -} - -// By default this doesn't work: an instance of the class should be provided -$invoker->call('MyHandler'); - -// If we set up the container to use -$invoker = new Invoker\Invoker(null, $container); -// Now 'MyHandler' is resolved using the container! -$invoker->call('MyHandler'); -``` - -The same works for a class method: - -```php -class WelcomeController -{ - public function home() - { - // ... - } -} - -// By default this doesn't work: home() is not a static method -$invoker->call(['WelcomeController', 'home']); - -// If we set up the container to use -$invoker = new Invoker\Invoker(null, $container); -// Now 'WelcomeController' is resolved using the container! -$invoker->call(['WelcomeController', 'home']); -// Alternatively we can use the Class::method syntax -$invoker->call('WelcomeController::home'); -``` - -That feature can be used as the base building block for a framework's dispatcher. - -Again, any [container-interop](https://github.com/container-interop/container-interop) compliant container can be provided, and [Acclimate](https://github.com/jeremeamia/acclimate-container) can be used for incompatible containers. diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/composer.json b/wcfsetup/install/files/lib/system/api/php-di/invoker/composer.json deleted file mode 100644 index 3f0c04169b..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "php-di/invoker", - "description": "Generic and extensible callable invoker", - "keywords": ["invoker", "dependency-injection", "dependency", "injection", "callable", "invoke"], - "homepage": "https://github.com/PHP-DI/Invoker", - "license": "MIT", - "type": "library", - "autoload": { - "psr-4": { - "Invoker\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Invoker\\Test\\": "tests/" - } - }, - "require": { - "container-interop/container-interop": "~1.1" - }, - "require-dev": { - "phpunit/phpunit": "~4.5", - "athletic/athletic": "~0.1.8" - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/doc/parameter-resolvers.md b/wcfsetup/install/files/lib/system/api/php-di/invoker/doc/parameter-resolvers.md deleted file mode 100644 index bfccb7f10e..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/doc/parameter-resolvers.md +++ /dev/null @@ -1,109 +0,0 @@ -# Parameter resolvers - -Extending the behavior of the `Invoker` is easy and is done by implementing a [`ParameterResolver`](https://github.com/PHP-DI/Invoker/blob/master/src/ParameterResolver/ParameterResolver.php): - -```php -interface ParameterResolver -{ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ); -} -``` - -- `$providedParameters` contains the parameters provided by the user when calling `$invoker->call($callable, $parameters)` -- `$resolvedParameters` contains parameters that have already been resolved by other parameter resolvers - -An `Invoker` can chain multiple parameter resolvers to mix behaviors, e.g. you can mix "named parameters" support with "dependency injection" support. This is why a `ParameterResolver` should skip parameters that are already resolved in `$resolvedParameters`. - -Here is an implementation example for dumb dependency injection that creates a new instance of the classes type-hinted: - -```php -class MyParameterResolver implements ParameterResolver -{ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - foreach ($reflection->getParameters() as $index => $parameter) { - if (array_key_exists($index, $resolvedParameters)) { - // Skip already resolved parameters - continue; - } - - $class = $parameter->getClass(); - - if ($class) { - $resolvedParameters[$index] = $class->newInstance(); - } - } - - return $resolvedParameters; - } -} -``` - -To use it: - -```php -$invoker = new Invoker\Invoker(new MyParameterResolver); - -$invoker->call(function (ArticleManager $articleManager) { - $articleManager->publishArticle('Hello world', 'This is the article content.'); -}); -``` - -A new instance of `ArticleManager` will be created by our parameter resolver. - -## Chaining parameter resolvers - -The fun starts to happen when we want to add support for many things: - -- named parameters -- dependency injection for type-hinted parameters -- ... - -This is where we should use the [`ResolverChain`](https://github.com/PHP-DI/Invoker/blob/master/src/ParameterResolver/ResolverChain.php). This resolver implements the [Chain of responsibility](http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern) design pattern. - -For example the default chain is: - -```php -$parameterResolver = new ResolverChain([ - new NumericArrayResolver, - new AssociativeArrayResolver, - new DefaultValueResolver, -]); -``` - -It allows to support even the weirdest use cases like: - -```php -$parameters = []; - -// First parameter will receive "Welcome" -$parameters[] = 'Welcome'; - -// Parameter named "content" will receive "Hello world!" -$parameters['content'] = 'Hello world!'; - -// $published is not defined so it will use its default value -$invoker->call(function ($title, $content, $published = true) { - // ... -}, $parameters); -``` - -We can put our custom parameter resolver in the list and created a super-duper invoker that also supports basic dependency injection: - -```php -$parameterResolver = new ResolverChain([ - new MyParameterResolver, // Our resolver is at the top for highest priority - new NumericArrayResolver, - new AssociativeArrayResolver, - new DefaultValueResolver, -]); - -$invoker = new Invoker\Invoker($parameterResolver); -``` diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/CallableResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/CallableResolver.php deleted file mode 100644 index eab8c0efce..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/CallableResolver.php +++ /dev/null @@ -1,131 +0,0 @@ - - */ -class CallableResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * Resolve the given callable into a real PHP callable. - * - * @param callable|string|array $callable - * - * @return callable Real PHP callable. - * - * @throws NotCallableException - */ - public function resolve($callable) - { - if (is_string($callable) && strpos($callable, '::') !== false) { - $callable = explode('::', $callable, 2); - } - - $callable = $this->resolveFromContainer($callable); - - if (! is_callable($callable)) { - throw new NotCallableException(sprintf( - '%s is not a callable', - is_object($callable) ? 'Instance of ' . get_class($callable) : var_export($callable, true) - )); - } - - return $callable; - } - - /** - * @param callable|string|array $callable - * @return callable - * @throws NotCallableException - */ - private function resolveFromContainer($callable) - { - // Shortcut for a very common use case - if ($callable instanceof \Closure) { - return $callable; - } - - $isStaticCallToNonStaticMethod = false; - - // If it's already a callable there is nothing to do - if (is_callable($callable)) { - $isStaticCallToNonStaticMethod = $this->isStaticCallToNonStaticMethod($callable); - if (! $isStaticCallToNonStaticMethod) { - return $callable; - } - } - - // The callable is a container entry name - if (is_string($callable)) { - if ($this->container->has($callable)) { - return $this->container->get($callable); - } else { - throw new NotCallableException(sprintf( - '"%s" is neither a callable nor a valid container entry', - $callable - )); - } - } - - // The callable is an array whose first item is a container entry name - // e.g. ['some-container-entry', 'methodToCall'] - if (is_array($callable) && is_string($callable[0])) { - if ($this->container->has($callable[0])) { - // Replace the container entry name by the actual object - $callable[0] = $this->container->get($callable[0]); - return $callable; - } elseif ($isStaticCallToNonStaticMethod) { - throw new NotCallableException(sprintf( - 'Cannot call %s::%s() because %s() is not a static method and "%s" is not a container entry', - $callable[0], - $callable[1], - $callable[1], - $callable[0] - )); - } else { - throw new NotCallableException(sprintf( - 'Cannot call %s on %s because it is not a class nor a valid container entry', - $callable[1], - $callable[0] - )); - } - } - - // Unrecognized stuff, we let it fail later - return $callable; - } - - /** - * Check if the callable represents a static call to a non-static method. - * - * @param mixed $callable - * @return bool - */ - private function isStaticCallToNonStaticMethod($callable) - { - if (is_array($callable) && is_string($callable[0])) { - list($class, $method) = $callable; - $reflection = new \ReflectionMethod($class, $method); - - return ! $reflection->isStatic(); - } - - return false; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/InvocationException.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/InvocationException.php deleted file mode 100644 index a5f6ffcd12..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/InvocationException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class InvocationException extends \Exception -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotCallableException.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotCallableException.php deleted file mode 100644 index 1f3e35246a..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotCallableException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class NotCallableException extends InvocationException -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotEnoughParametersException.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotEnoughParametersException.php deleted file mode 100644 index 1be4eb98ca..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Exception/NotEnoughParametersException.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ -class NotEnoughParametersException extends InvocationException -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Invoker.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Invoker.php deleted file mode 100644 index ffdcd0bf20..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Invoker.php +++ /dev/null @@ -1,122 +0,0 @@ - - */ -class Invoker implements InvokerInterface -{ - /** - * @var CallableResolver|null - */ - private $callableResolver; - - /** - * @var ParameterResolver - */ - private $parameterResolver; - - /** - * @var ContainerInterface|null - */ - private $container; - - public function __construct(ParameterResolver $parameterResolver = null, ContainerInterface $container = null) - { - $this->parameterResolver = $parameterResolver ?: $this->createParameterResolver(); - $this->container = $container; - - if ($container) { - $this->callableResolver = new CallableResolver($container); - } - } - - /** - * {@inheritdoc} - */ - public function call($callable, array $parameters = array()) - { - if ($this->callableResolver) { - $callable = $this->callableResolver->resolve($callable); - } - - if (! is_callable($callable)) { - throw new NotCallableException(sprintf( - '%s is not a callable', - is_object($callable) ? 'Instance of ' . get_class($callable) : var_export($callable, true) - )); - } - - $callableReflection = CallableReflection::create($callable); - - $args = $this->parameterResolver->getParameters($callableReflection, $parameters, array()); - - // Sort by array key because call_user_func_array ignores numeric keys - ksort($args); - - // Check all parameters are resolved - $diff = array_diff_key($callableReflection->getParameters(), $args); - if (! empty($diff)) { - /** @var \ReflectionParameter $parameter */ - $parameter = reset($diff); - throw new NotEnoughParametersException(sprintf( - 'Unable to invoke the callable because no value was given for parameter %d ($%s)', - $parameter->getPosition() + 1, - $parameter->name - )); - } - - return call_user_func_array($callable, $args); - } - - /** - * Create the default parameter resolver. - * - * @return ParameterResolver - */ - private function createParameterResolver() - { - return new ResolverChain(array( - new NumericArrayResolver, - new AssociativeArrayResolver, - new DefaultValueResolver, - )); - } - - /** - * @return ParameterResolver By default it's a ResolverChain - */ - public function getParameterResolver() - { - return $this->parameterResolver; - } - - /** - * @return ContainerInterface|null - */ - public function getContainer() - { - return $this->container; - } - - /** - * @return CallableResolver|null Returns null if no container was given in the constructor. - */ - public function getCallableResolver() - { - return $this->callableResolver; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/InvokerInterface.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/InvokerInterface.php deleted file mode 100644 index cd6980e2d7..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/InvokerInterface.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ -interface InvokerInterface -{ - /** - * Call the given function using the given parameters. - * - * @param callable $callable Function to call. - * @param array $parameters Parameters to use. - * - * @return mixed Result of the function. - * - * @throws InvocationException Base exception class for all the sub-exceptions below. - * @throws NotCallableException - * @throws NotEnoughParametersException - */ - public function call($callable, array $parameters = array()); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/AssociativeArrayResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/AssociativeArrayResolver.php deleted file mode 100644 index d51f2c7d05..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/AssociativeArrayResolver.php +++ /dev/null @@ -1,39 +0,0 @@ -call($callable, ['foo' => 'bar'])` will inject the string `'bar'` - * in the parameter named `$foo`. - * - * Parameters that are not indexed by a string are ignored. - * - * @author Matthieu Napoli - */ -class AssociativeArrayResolver implements ParameterResolver -{ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - $parameters = $reflection->getParameters(); - - // Skip parameters already resolved - if (! empty($resolvedParameters)) { - $parameters = array_diff_key($parameters, $resolvedParameters); - } - - foreach ($parameters as $index => $parameter) { - if (array_key_exists($parameter->name, $providedParameters)) { - $resolvedParameters[$index] = $providedParameters[$parameter->name]; - } - } - - return $resolvedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/ParameterNameContainerResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/ParameterNameContainerResolver.php deleted file mode 100644 index 983dea414f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/ParameterNameContainerResolver.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -class ParameterNameContainerResolver implements ParameterResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * @param ContainerInterface $container The container to get entries from. - */ - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - $parameters = $reflection->getParameters(); - - // Skip parameters already resolved - if (! empty($resolvedParameters)) { - $parameters = array_diff_key($parameters, $resolvedParameters); - } - - foreach ($parameters as $index => $parameter) { - $name = $parameter->name; - - if ($name && $this->container->has($name)) { - $resolvedParameters[$index] = $this->container->get($name); - } - } - - return $resolvedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/TypeHintContainerResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/TypeHintContainerResolver.php deleted file mode 100644 index 65a4079497..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/Container/TypeHintContainerResolver.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -class TypeHintContainerResolver implements ParameterResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * @param ContainerInterface $container The container to get entries from. - */ - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - $parameters = $reflection->getParameters(); - - // Skip parameters already resolved - if (! empty($resolvedParameters)) { - $parameters = array_diff_key($parameters, $resolvedParameters); - } - - foreach ($parameters as $index => $parameter) { - $parameterClass = $parameter->getClass(); - - if ($parameterClass && $this->container->has($parameterClass->name)) { - $resolvedParameters[$index] = $this->container->get($parameterClass->name); - } - } - - return $resolvedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/DefaultValueResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/DefaultValueResolver.php deleted file mode 100644 index 6fa8f8c366..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/DefaultValueResolver.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ -class DefaultValueResolver implements ParameterResolver -{ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - $parameters = $reflection->getParameters(); - - // Skip parameters already resolved - if (! empty($resolvedParameters)) { - $parameters = array_diff_key($parameters, $resolvedParameters); - } - - foreach ($parameters as $index => $parameter) { - /** @var \ReflectionParameter $parameter */ - if ($parameter->isOptional()) { - try { - $resolvedParameters[$index] = $parameter->getDefaultValue(); - } catch (ReflectionException $e) { - // Can't get default values from PHP internal classes and functions - } - } - } - - return $resolvedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/NumericArrayResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/NumericArrayResolver.php deleted file mode 100644 index dc5f02c46d..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/NumericArrayResolver.php +++ /dev/null @@ -1,39 +0,0 @@ -call($callable, ['foo', 'bar'])` will simply resolve the parameters - * to `['foo', 'bar']`. - * - * Parameters that are not indexed by a number (i.e. parameter position) - * will be ignored. - * - * @author Matthieu Napoli - */ -class NumericArrayResolver implements ParameterResolver -{ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - // Skip parameters already resolved - if (! empty($resolvedParameters)) { - $providedParameters = array_diff_key($providedParameters, $resolvedParameters); - } - - foreach ($providedParameters as $key => $value) { - if (is_int($key)) { - $resolvedParameters[$key] = $value; - } - } - - return $resolvedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ParameterResolver.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ParameterResolver.php deleted file mode 100644 index 39c7abcdfd..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ParameterResolver.php +++ /dev/null @@ -1,33 +0,0 @@ - - */ -interface ParameterResolver -{ - /** - * Resolves the parameters to use to call the callable. - * - * `$resolvedParameters` contains parameters that have already been resolved. - * - * Each ParameterResolver must resolve parameters that are not already - * in `$resolvedParameters`. That allows to chain multiple ParameterResolver. - * - * @param ReflectionFunctionAbstract $reflection Reflection object for the callable. - * @param array $providedParameters Parameters provided by the caller. - * @param array $resolvedParameters Parameters resolved (indexed by parameter position). - * - * @return array - */ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ResolverChain.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ResolverChain.php deleted file mode 100644 index d5247462bf..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/ParameterResolver/ResolverChain.php +++ /dev/null @@ -1,69 +0,0 @@ - - */ -class ResolverChain implements ParameterResolver -{ - /** - * @var ParameterResolver[] - */ - private $resolvers = array(); - - public function __construct(array $resolvers = array()) - { - $this->resolvers = $resolvers; - } - - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - $reflectionParameters = $reflection->getParameters(); - - foreach ($this->resolvers as $resolver) { - $resolvedParameters = $resolver->getParameters( - $reflection, - $providedParameters, - $resolvedParameters - ); - - $diff = array_diff_key($reflectionParameters, $resolvedParameters); - if (empty($diff)) { - // Stop traversing: all parameters are resolved - return $resolvedParameters; - } - } - - return $resolvedParameters; - } - - /** - * Push a parameter resolver after the ones already registered. - * - * @param ParameterResolver $resolver - */ - public function appendResolver(ParameterResolver $resolver) - { - $this->resolvers[] = $resolver; - } - - /** - * Insert a parameter resolver before the ones already registered. - * - * @param ParameterResolver $resolver - */ - public function prependResolver(ParameterResolver $resolver) - { - array_unshift($this->resolvers, $resolver); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Reflection/CallableReflection.php b/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Reflection/CallableReflection.php deleted file mode 100644 index 7835f44855..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/invoker/src/Reflection/CallableReflection.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ -class CallableReflection -{ - /** - * @param callable $callable - * - * @return \ReflectionFunctionAbstract - * - * @throws NotCallableException - * - * TODO Use the `callable` type-hint once support for PHP 5.4 and up. - */ - public static function create($callable) - { - // Closure - if ($callable instanceof \Closure) { - return new \ReflectionFunction($callable); - } - - // Array callable - if (is_array($callable)) { - list($class, $method) = $callable; - - return new \ReflectionMethod($class, $method); - } - - // Callable object (i.e. implementing __invoke()) - if (is_object($callable) && method_exists($callable, '__invoke')) { - return new \ReflectionMethod($callable, '__invoke'); - } - - // Callable class (i.e. implementing __invoke()) - if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) { - return new \ReflectionMethod($callable, '__invoke'); - } - - // Standard function - if (is_string($callable) && function_exists($callable)) { - return new \ReflectionFunction($callable); - } - - throw new NotCallableException(sprintf( - '%s is not a callable', - is_string($callable) ? $callable : 'Instance of ' . get_class($callable) - )); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/.coveralls.yml b/wcfsetup/install/files/lib/system/api/php-di/php-di/.coveralls.yml deleted file mode 100644 index bc71b62f87..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/.coveralls.yml +++ /dev/null @@ -1,2 +0,0 @@ -coverage_clover: clover.xml -json_path: coveralls-upload.json diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/.gitattributes b/wcfsetup/install/files/lib/system/api/php-di/php-di/.gitattributes deleted file mode 100644 index 362238c15d..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/.gitattributes +++ /dev/null @@ -1,8 +0,0 @@ -# .gitattributes -tests/ export-ignore -website/ export-ignore -doc/ export-ignore -news/ export-ignore - -# Auto detect text files and perform LF normalization -* text=auto diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/.gitignore b/wcfsetup/install/files/lib/system/api/php-di/php-di/.gitignore deleted file mode 100644 index b39e0cdff5..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -/.idea/ -/vendor/ -/composer.phar -/composer.lock -/theme/ -/.couscous/ -/website/bower_components/ -/website/css/all.min.css -/logo/ diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/.travis.yml b/wcfsetup/install/files/lib/system/api/php-di/php-di/.travis.yml deleted file mode 100644 index 1fed6a382d..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: php - -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - hhvm - -matrix: - include: - - php: 5.4 - env: dependencies=lowest - -before_script: - - composer self-update - - if [[ $(phpenv version-name) == '5.6' ]]; then composer require satooshi/php-coveralls:dev-master -n ; fi - - if [[ $(phpenv version-name) != '5.6' ]]; then composer install -n ; fi - - if [ "$dependencies" = "lowest" ]; then composer update --prefer-lowest --prefer-stable -n; fi; - -script: - - if [[ $(phpenv version-name) == '5.6' ]]; then phpunit --coverage-clover clover.xml ; fi - - if [[ $(phpenv version-name) != '5.6' ]]; then phpunit ; fi - -after_script: - - if [[ $(phpenv version-name) == '5.6' ]]; then php vendor/bin/coveralls -v ; fi diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/404.md b/wcfsetup/install/files/lib/system/api/php-di/php-di/404.md deleted file mode 100644 index c4e870fdc7..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/404.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -layout: 404 ---- diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/CONTRIBUTING.md b/wcfsetup/install/files/lib/system/api/php-di/php-di/CONTRIBUTING.md deleted file mode 100644 index 6e3bd2407b..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/CONTRIBUTING.md +++ /dev/null @@ -1,52 +0,0 @@ -# Contributing - -[![Build Status](https://travis-ci.org/PHP-DI/PHP-DI.png?branch=master)](https://travis-ci.org/PHP-DI/PHP-DI) [![Coverage Status](https://coveralls.io/repos/PHP-DI/PHP-DI/badge.png?branch=master)](https://coveralls.io/r/PHP-DI/PHP-DI?branch=master) - -PHP-DI is licensed under the MIT License. - - -## Set up - -* Check out the sources using git or download them - -```bash -$ git clone https://github.com/PHP-DI/PHP-DI.git -``` - -* Install the libraries using composer: - -```bash -$ curl -s http://getcomposer.org/installer | php -$ php composer.phar install -``` - -If you are running Windows or are having trouble, read [the official documentation](http://getcomposer.org/doc/00-intro.md#installation). - - -## Run the tests - -The tests are run with [PHPUnit](http://www.phpunit.de/manual/current/en/installation.html): - -```bash -$ phpunit -``` - - -## Learning the internals - -Read the [How it works](doc/how-it-works.md) documentation. - - -## What to do? - -- Add tests: pick up uncovered situations in the [code coverage report](https://coveralls.io/r/PHP-DI/PHP-DI) -- Resolve issues: [issue list](https://github.com/PHP-DI/PHP-DI/issues) -- Improve the documentation -- … - - -## Coding style - -The code follows PSR0, PSR1 and [PSR2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md). - -Also, do not hesitate to add your name to the author list of a class in the docblock if you improve it. diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/LICENSE b/wcfsetup/install/files/lib/system/api/php-di/php-di/LICENSE deleted file mode 100644 index f24e183de7..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -PHP-DI - PHP Dependency Injection - -Copyright (C) Matthieu Napoli - -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/wcfsetup/install/files/lib/system/api/php-di/php-di/README.md b/wcfsetup/install/files/lib/system/api/php-di/php-di/README.md deleted file mode 100644 index 7e40802540..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/README.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: home ---- - -PHP-DI is a Dependency Injection Container made for humans. - -[![Build Status](https://img.shields.io/travis/PHP-DI/PHP-DI.svg?style=flat-square)](https://travis-ci.org/PHP-DI/PHP-DI) -[![HHVM Status](https://img.shields.io/hhvm/php-di/php-di.svg?style=flat-square)](http://hhvm.h4cc.de/package/php-di/php-di) -[![Coverage Status](https://img.shields.io/coveralls/PHP-DI/PHP-DI/master.svg?style=flat-square)](https://coveralls.io/r/PHP-DI/PHP-DI?branch=master) -[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/PHP-DI/PHP-DI.svg?style=flat-square)](https://scrutinizer-ci.com/g/PHP-DI/PHP-DI/?branch=master) -[![Latest Version](https://img.shields.io/github/release/PHP-DI/PHP-DI.svg?style=flat-square)](https://packagist.org/packages/php-di/php-di) -[![Total Downloads](https://img.shields.io/packagist/dt/mnapoli/PHP-DI.svg?style=flat-square)](https://packagist.org/packages/mnapoli/php-di) - -[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/PHP-DI/PHP-DI.svg)](http://isitmaintained.com/project/PHP-DI/PHP-DI "Average time to resolve an issue") -[![Percentage of issues still open](http://isitmaintained.com/badge/open/PHP-DI/PHP-DI.svg)](http://isitmaintained.com/project/PHP-DI/PHP-DI "Percentage of issues still open") - -It is meant to be practical, powerful, and framework-agnostic. - -Read more on the website: **[php-di.org](http://php-di.org)** - -Join us in the Gitter chat room: [![Gitter chat](https://badges.gitter.im/PHP-DI/PHP-DI.png)](https://gitter.im/PHP-DI/PHP-DI) diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/change-log.md b/wcfsetup/install/files/lib/system/api/php-di/php-di/change-log.md deleted file mode 100644 index 3a7ba86873..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/change-log.md +++ /dev/null @@ -1,303 +0,0 @@ -# Change log - -## 5.1 - -Read the [news entry](news/16-php-di-5-1-released.md). - -Improvements: - -- [Zend Framework 2 integration](https://github.com/PHP-DI/ZF2-Bridge) (by @Rastusik) -- [#308](https://github.com/PHP-DI/PHP-DI/pull/308): Instantiate factories using the container (`DI\factory(['FooFactory', 'create'])`) -- Many performances improvements - some benchmarks show up to 35% performance improvements, real results may vary of course -- Many documentation improvements (@jdreesen, @mindplay-dk, @mnapoli, @holtkamp, @Rastusik) -- [#296](https://github.com/PHP-DI/PHP-DI/issues/296): Provide a faster `ArrayCache` implementation, mostly useful in micro-benchmarks - -Bugfixes: - -- [#257](https://github.com/PHP-DI/PHP-DI/issues/257) & [#274](https://github.com/PHP-DI/PHP-DI/issues/274): Private properties of parent classes are not injected when using annotations -- [#300](https://github.com/PHP-DI/PHP-DI/pull/300): Exception if object definition extends an incompatible definition -- [#306](https://github.com/PHP-DI/PHP-DI/issues/306): Errors when using parameters passed by reference (fixed by @bradynpoulsen) -- [#318](https://github.com/PHP-DI/PHP-DI/issues/318): `Container::call()` ignores parameter's default value - -Internal changes: - -- [#276](https://github.com/PHP-DI/PHP-DI/pull/276): Tests now pass on Windows (@bgaillard) - -## 5.0 - -This is the complete change log. You can also read the [migration guide](doc/migration/5.0.md) for upgrading, or [the news article](news/15-php-di-5-0-released.md) for a nicer introduction to this new version. - -Improvements: - -- Moved to an organization on GitHub: [github.com/PHP-DI/PHP-DI](https://github.com/PHP-DI/PHP-DI) -- The package has been renamed to: from `mnapoli/php-di` to [`php-di/php-di`](https://packagist.org/packages/php-di/php-di) -- New [Silex integration](doc/frameworks/silex.md) -- Lighter package: from 10 to 3 Composer dependencies! -- [#235](https://github.com/PHP-DI/PHP-DI/issues/235): `DI\link()` is now deprecated in favor of `DI\get()`. There is no BC break as `DI\link()` still works. -- [#207](https://github.com/PHP-DI/PHP-DI/issues/207): Support for `DI\link()` in arrays -- [#203](https://github.com/PHP-DI/PHP-DI/issues/203): New `DI\string()` helper ([documentation](doc/php-definitions.md)) -- [#208](https://github.com/PHP-DI/PHP-DI/issues/208): Support for nested definitions -- [#226](https://github.com/PHP-DI/PHP-DI/pull/226): `DI\factory()` can now be omitted with closures: - - ```php - // before - 'My\Class' => DI\factory(function () { ... }) - // now (optional shortcut) - 'My\Class' => function () { ... } - ``` -- [#193](https://github.com/PHP-DI/PHP-DI/issues/193): `DI\object()->method()` now supports calling the same method twice (or more). -- [#248](https://github.com/PHP-DI/PHP-DI/issues/248): New `DI\decorate()` helper to decorate a previously defined entry ([documentation](doc/definition-overriding.md)) -- [#215](https://github.com/PHP-DI/PHP-DI/pull/215): New `DI\add()` helper to add entries to an existing array ([documentation](doc/definition-overriding.md)) -- [#218](https://github.com/PHP-DI/PHP-DI/issues/218): `ContainerBuilder::addDefinitions()` can now take an array of definitions -- [#211](https://github.com/PHP-DI/PHP-DI/pull/211): `ContainerBuilder::addDefinitions()` is now fluent (return `$this`) -- [#250](https://github.com/PHP-DI/PHP-DI/issues/250): `Container::call()` now also accepts parameters not indexed by name as well as embedded definitions ([documentation](doc/container.md)) -- Various performance improvements, e.g. lower the number of files loaded, simpler architecture, … - -BC breaks: - -- PHP-DI now requires a version of PHP >= 5.4.0 -- The package is lighter by default: - - [#251](https://github.com/PHP-DI/PHP-DI/issues/251): Annotations are disabled by default, if you use annotations enable them with `$containerBuilder->useAnnotations(true)`. Additionally the `doctrine/annotations` package isn't required by default anymore, so you also need to run `composer require doctrine/annotations`. - - `doctrine/cache` is not installed by default anymore, you need to require it in `composer.json` (`~1.0`) if you want to configure a cache for PHP-DI - - [#198](https://github.com/PHP-DI/PHP-DI/issues/198): `ocramius/proxy-manager` is not installed by default anymore, you need to require it in `composer.json` (`~1.0`) if you want to use **lazy injection** -- Closures are now converted into factory definitions automatically. If you ever defined a closure as a value (e.g. to have the closure injected in a class), you need to wrap the closure with the new `DI\value()` helper. -- [#223](https://github.com/PHP-DI/PHP-DI/issues/223): `DI\ContainerInterface` was deprecated since v4.1 and has been removed - -Internal changes in case you were replacing/extending some parts: - -- the definition sources architecture has been refactored, if you defined custom definition sources you will need to update your code (it should be much easier now) -- [#252](https://github.com/PHP-DI/PHP-DI/pull/252): `DI\Scope` internal implementation has changed. You are encouraged to use the constants (`DI\Scope::SINGLETON` and `DI\Scope::PROTOTYPE`) instead of the static methods, but backward compatibility is kept (static methods still work). -- [#241](https://github.com/PHP-DI/PHP-DI/issues/241): `Container::call()` now uses the *Invoker* external library - -## 4.4 - -Read the [news entry](news/13-php-di-4-4-released.md). - -- [#185](https://github.com/PHP-DI/PHP-DI/issues/185) Support for invokable objects in `Container::call()` -- [#192](https://github.com/PHP-DI/PHP-DI/pull/192) Support for invokable classes in `Container::call()` (will instantiate the class) -- [#184](https://github.com/PHP-DI/PHP-DI/pull/184) Option to ignore phpdoc errors - -## 4.3 - -Read the [news entry](news/11-php-di-4-3-released.md). - -- [#176](https://github.com/PHP-DI/PHP-DI/pull/176) New definition type for reading environment variables: `DI\env()` -- [#181](https://github.com/PHP-DI/PHP-DI/pull/181) `DI\FactoryInterface` and `DI\InvokerInterface` are now auto-registered inside the container so that you can inject them without any configuration needed -- [#173](https://github.com/PHP-DI/PHP-DI/pull/173) `$container->call(['MyClass', 'method]);` will get `MyClass` from the container if `method()` is not a static method - -## 4.2.2 - -- Fixed [#180](https://github.com/PHP-DI/PHP-DI/pull/180): `Container::call()` with object methods (`[$object, 'method']`) is now supported - -## 4.2.1 - -- Support for PHP 5.3.3, which was previously incomplete because of a bug in the reflection (there is now a workaround for this bug) - -But if you can, seriously avoid this (really old) PHP version and upgrade. - -## 4.2 - -Read the [news entry](news/10-php-di-4-2-released.md). - -**Minor BC-break**: Optional parameters (that were not configured) were injected, they are now ignored, which is what naturally makes sense since they are optional. -Example: - -```php - public function __construct(Bar $bar = null) - { - $this->bar = $bar ?: $this->createDefaultBar(); - } -``` - -Before 4.2, PHP-DI would try to inject a `Bar` instance. From 4.2 and onwards, it will inject `null`. - -Of course, you can still explicitly define an injection for the optional parameters and that will work. - -All changes: - -* [#162](https://github.com/PHP-DI/PHP-DI/pull/162) Added `Container::call()` to call functions with dependency injection -* [#156](https://github.com/PHP-DI/PHP-DI/issues/156) Wildcards (`*`) in definitions -* [#164](https://github.com/PHP-DI/PHP-DI/issues/164) Prototype scope is now available for `factory()` definitions too -* FIXED [#168](https://github.com/PHP-DI/PHP-DI/pull/168) `Container::has()` now returns false for interfaces and abstract classes that are not mapped in the definitions -* FIXED [#171](https://github.com/PHP-DI/PHP-DI/issues/171) Optional parameters are now ignored (not injected) if not set in the definitions (see the BC-break warning above) - -## 4.1 - -Read the [news entry](news/09-php-di-4-1-released.md). - -BC-breaks: None. - -* [#138](https://github.com/PHP-DI/PHP-DI/issues/138) [Container-interop](https://github.com/container-interop/container-interop) compliance -* [#143](https://github.com/PHP-DI/PHP-DI/issues/143) Much more explicit exception messages -* [#157](https://github.com/PHP-DI/PHP-DI/issues/157) HHVM support -* [#158](https://github.com/PHP-DI/PHP-DI/issues/158) Improved the documentation for [Symfony 2 integration](http://php-di.org/doc/frameworks/symfony2.html) - -## 4.0 - -Major changes: - -* The configuration format has changed ([read more here to understand why](news/06-php-di-4-0-new-definitions.md)) - -Read the migration guide if you are using 3.x: [Migration guide from 3.x to 4.0](doc/migration/4.0.md). - -BC-breaks: - -* YAML, XML and JSON definitions have been removed, and the PHP definition format has changed (see above) -* `ContainerSingleton` has been removed -* You cannot configure an injection as lazy anymore, you can only configure a container entry as lazy -* The Container constructor now takes mandatory parameters. Use the ContainerBuilder to create a Container. -* Removed `ContainerBuilder::setDefinitionsValidation()` (no definition validation anymore) -* `ContainerBuilder::useReflection()` is now named: `ContainerBuilder::useAutowiring()` -* `ContainerBuilder::addDefinitionsFromFile()` is now named: `ContainerBuilder::addDefinitions()` -* The `$proxy` parameter in `Container::get($name, $proxy = true)` hase been removed. To get a proxy, you now need to define an entry as "lazy". - -Other changes: - -* Added `ContainerInterface` and `FactoryInterface`, both implemented by the container. -* [#115](https://github.com/PHP-DI/PHP-DI/issues/115) Added `Container::has()` -* [#142](https://github.com/PHP-DI/PHP-DI/issues/142) Added `Container::make()` to resolve an entry -* [#127](https://github.com/PHP-DI/PHP-DI/issues/127) Added support for cases where PHP-DI is wrapped by another container (like Acclimate): PHP-DI can now use the wrapping container to perform injections -* [#128](https://github.com/PHP-DI/PHP-DI/issues/128) Configure entry aliases -* [#110](https://github.com/PHP-DI/PHP-DI/issues/110) XML definitions are not supported anymore -* [#122](https://github.com/PHP-DI/PHP-DI/issues/122) JSON definitions are not supported anymore -* `ContainerSingleton` has finally been removed -* Added `ContainerBuilder::buildDevContainer()` to get started with a default container very easily. -* [#99](https://github.com/PHP-DI/PHP-DI/issues/99) Fixed "`@param` with PHP internal type throws exception" - -## 3.5.1 - -* FIXED [#126](https://github.com/PHP-DI/PHP-DI/issues/126): `Container::set` without effect if a value has already been set and retrieved - -## 3.5 - -Read the [news entry](news/05-php-di-3-5.md). - -* Importing `@Inject` and `@Injectable` annotations is now optional! It means that you don't have to write `use DI\Annotation\Inject` anymore -* FIXED [#124](https://github.com/PHP-DI/PHP-DI/issues/124): `@Injects` annotation conflicts with other annotations - -## 3.4 - -Read the [news entry](news/04-php-di-3-4.md). - -* [#106](https://github.com/PHP-DI/PHP-DI/pull/106) You can now define arrays of values (in YAML, PHP, …) thanks to [@unkind](https://github.com/unkind) -* [#98](https://github.com/PHP-DI/PHP-DI/issues/98) `ContainerBuilder` is now fluent thanks to [@drdamour](https://github.com/drdamour) -* [#101](https://github.com/PHP-DI/PHP-DI/pull/101) Optional parameters are now supported: if you don't define a value to inject, their default value will be used -* XML definitions have been deprecated, there weren't even documented and were not maintained. They will be removed in 4.0. -* FIXED [#100](https://github.com/PHP-DI/PHP-DI/issues/100): bug for lazy injection in constructors - -## 3.3 - -Read the [news entry](news/03-php-di-3-3.md). - -* Inject dependencies on an existing instance with `Container::injectOn` (work from [Jeff Flitton](https://github.com/jflitton): [#89](https://github.com/PHP-DI/PHP-DI/pull/89)). -* [#86](https://github.com/PHP-DI/PHP-DI/issues/86): Optimized definition lookup (faster) -* FIXED [#87](https://github.com/PHP-DI/PHP-DI/issues/87): Rare bug in the `PhpDocParser`, fixed by [drdamour](https://github.com/drdamour) - -## 3.2 - -Read the [news entry](news/02-php-di-3-2.md). - -Small BC-break: PHP-DI 3.0 and 3.1 injected properties before calling the constructor. This was confusing and [not supported for internal classes](https://github.com/PHP-DI/PHP-DI/issues/74). -From 3.2 and on, properties are injected after calling the constructor. - -* **[Lazy injection](doc/lazy-injection.md)**: it is now possible to use lazy injection on properties and methods (setters and constructors). -* Lazy dependencies are now proxies that extend the class they proxy, so type-hinting works. -* Addition of the **`ContainerBuilder`** object, that helps to [create and configure a `Container`](doc/container-configuration.md). -* Some methods for configuring the Container have gone **deprecated** in favor of the `ContainerBuilder`. Fear not, these deprecated methods will remain until next major version (4.0). - * `Container::useReflection`, use ContainerBuilder::useReflection instead - * `Container::useAnnotations`, use ContainerBuilder::useAnnotations instead - * `Container::setDefinitionCache`, use ContainerBuilder::setDefinitionCache instead - * `Container::setDefinitionsValidation`, use ContainerBuilder::setDefinitionsValidation instead -* The container is now auto-registered (as 'DI\Container'). You can now inject the container without registering it. - -## 3.1.1 - -* Value definitions (`$container->set('foo', 80)`) are not cached anymore -* FIXED [#82](https://github.com/PHP-DI/PHP-DI/issues/82): Serialization error when using a cache - -## 3.1 - -Read the [news entry](news/01-php-di-3-1.md). - -* Zend Framework 1 integration through the [PHP-DI-ZF1 project](https://github.com/PHP-DI/PHP-DI-ZF1) -* Fixed the order of priorities when you mix different definition sources (reflection, annotations, files, …). See [Definition overriding](doc/definition-overriding.md) -* Now possible to define null values with `$container->set('foo', null)` (see [#79](https://github.com/PHP-DI/PHP-DI/issues/79)). -* Deprecated usage of `ContainerSingleton`, will be removed in next major version (4.0) - -## 3.0.6 - -* FIXED [#76](https://github.com/PHP-DI/PHP-DI/issues/76): Definition conflict when setting a closure for a class name - -## 3.0.5 - -* FIXED [#70](https://github.com/PHP-DI/PHP-DI/issues/70): Definition conflict when setting a value for a class name - -## 3.0.4 - -* FIXED [#69](https://github.com/PHP-DI/PHP-DI/issues/69): YamlDefinitionFileLoader crashes if YAML file is empty - -## 3.0.3 - -* Fixed over-restrictive dependencies in composer.json - -## 3.0.2 - -* [#64](https://github.com/PHP-DI/PHP-DI/issues/64): Non PHP-DI exceptions are not captured-rethrown anymore when injecting dependencies (cleaner stack trace) - -## 3.0.1 - -* [#62](https://github.com/PHP-DI/PHP-DI/issues/62): When using aliases, definitions are now merged - -## 3.0 - -Major compatibility breaks with 2.x. - -* The container is no longer a Singleton (but `ContainerSingleton::getInstance()` is available for fools who like it) -* Setter injection -* Constructor injection -* Scopes: singleton (share the same instance of the class) or prototype (create a new instance each time it is fetched). Defined at class level. -* Configuration is reworked from scratch. Now every configuration backend can do 100% of the job. -* Provided configuration backends: - * Reflection - * Annotations: @Inject, @Injectable - * PHP code (`Container::set()`) - * PHP array - * YAML file -* As a consequence, annotations are not mandatory anymore, all functionalities can be used with or without annotations. -* Renamed `DI\Annotations\` to `DI\Annotation\` -* `Container` no longer implements ArrayAccess, use only `$container->get($key)` now -* ZF1 integration broken and removed (work in progress for next releases) -* Code now follows PSR1 and PSR2 coding styles -* FIXED: [#58](https://github.com/PHP-DI/PHP-DI/issues/58) Getting a proxy of an alias didn't work - -## 2.1 - -* `use` statements to import classes from other namespaces are now taken into account with the `@var` annotation -* Updated and lightened the dependencies : `doctrine/common` has been replaced with more specific `doctrine/annotations` and `doctrine/cache` - -## 2.0 - -Major compatibility breaks with 1.x. - -* `Container::resolveDependencies()` has been renamed to `Container::injectAll()` -* Dependencies are now injected **before** the constructor is called, and thus are available in the constructor -* Merged `@Value` annotation with `@Inject`: no difference between value and bean injection anymore -* Container implements ArrayAccess for get() and set() (`$container['db.host'] = 'localhost';`) -* Ini configuration files removed: configuration is done in PHP -* Allow to define beans within closures for lazy-loading -* Switched to MIT License - -Warning: - -* If you use PHP 5.3 and __wakeup() methods, they will be called when PHP-DI creates new instances of those classes. - -## 1.1 - -* Caching of annotations based on Doctrine caches - -## 1.0 - -* DependencyManager renamed to Container -* Refactored basic Container usage with `get` and `set` -* Allow named injection `@Inject(name="")` -* Zend Framework integration diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/composer.json b/wcfsetup/install/files/lib/system/api/php-di/php-di/composer.json deleted file mode 100644 index 3111f93603..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/composer.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "php-di/php-di", - "type": "library", - "description": "The dependency injection container for humans", - "keywords": ["di", "dependency injection", "container"], - "homepage": "http://php-di.org/", - "license": "MIT", - "autoload": { - "psr-4": { - "DI\\": "src/DI/" - }, - "files": [ - "src/DI/functions.php" - ] - }, - "autoload-dev": { - "psr-4": { - "DI\\Test\\IntegrationTest\\": "tests/IntegrationTest/", - "DI\\Test\\UnitTest\\": "tests/UnitTest/" - } - }, - "require": { - "php": ">=5.4.0", - "container-interop/container-interop": "~1.0", - "php-di/invoker": "^1.0.1", - "php-di/phpdoc-reader": "~2.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.5", - "mnapoli/phpunit-easymock": "~0.1.4", - "doctrine/cache": "~1.4", - "doctrine/annotations": "~1.2", - "ocramius/proxy-manager": "~1.0" - }, - "replace": { - "mnapoli/php-di": "*" - }, - "suggest": { - "doctrine/cache": "Install it if you want to use the cache (version ~1.4)", - "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", - "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~1.0)" - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/couscous.yml b/wcfsetup/install/files/lib/system/api/php-di/php-di/couscous.yml deleted file mode 100644 index c18e3cf688..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/couscous.yml +++ /dev/null @@ -1,110 +0,0 @@ -baseUrl: http://php-di.org - -scripts: - before: - - lessc --clean-css website/less/main.less website/css/all.min.css - -menu: - items: - introduction: - section: Introduction - items: - getting-started: - text: Getting started - url: doc/getting-started.html - understanding-di: - text: Understanding dependency injection - url: doc/understanding-di.html - best-practices: - text: "\"Best practices\" guide" - url: doc/best-practices.html - usage: - section: Usage - items: - container-configuration: - text: Configuring the container - url: doc/container-configuration.html - container: - text: Using the container - url: doc/container.html - definition: - section: Definitions - items: - introduction: - text: Introduction - url: doc/definition.html - autowiring: - text: Autowiring - url: doc/autowiring.html - php: - text: PHP definitions - url: doc/php-definitions.html - annotations: - text: Annotations - url: doc/annotations.html - definition-overriding: - text: Definition extensions and overriding - url: doc/definition-overriding.html - frameworks: - section: Frameworks - items: - symfony2: - text: Symfony 2 - url: doc/frameworks/symfony2.html - silex: - text: Silex - url: doc/frameworks/silex.html - zf2: - text: Zend Framework 2 - url: doc/frameworks/zf2.html - zf1: - text: Zend Framework 1 - url: doc/frameworks/zf1.html - silly: - text: Silly - url: doc/frameworks/silly.html - advanced: - section: Advanced topics - items: - performances: - text: Performances - url: doc/performances.html - scopes: - text: Scopes - url: doc/scopes.html - lazy-injection: - text: Lazy injection - url: doc/lazy-injection.html - inject-on-instance: - text: Inject on an existing instance - url: doc/inject-on-instance.html - environments: - text: Injections depending on the environment - url: doc/environments.html - migration: - section: Migration guides - items: - 4: - text: From PHP-DI 3.x to 4.0 - url: doc/migration/4.0.html - 5: - text: From PHP-DI 4.x to 5.0 - url: doc/migration/5.0.html - internals: - section: Internals - items: - contributing: - text: Contributing - url: contributing.html - how-it-works: - text: How PHP-DI works - url: doc/how-it-works.html - versions: - section: Old documentation - items: - v3: - text: PHP-DI 3.x - absoluteUrl: https://github.com/PHP-DI/PHP-DI/tree/3.x/doc - v4: - text: PHP-DI 4.x - absoluteUrl: https://github.com/PHP-DI/PHP-DI/tree/4.x/doc diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/phpunit.xml.dist b/wcfsetup/install/files/lib/system/api/php-di/php-di/phpunit.xml.dist deleted file mode 100644 index 81c7f73867..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/phpunit.xml.dist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - ./tests/UnitTest/ - - - ./tests/IntegrationTest/ - - - - - - src - - - - diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Inject.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Inject.php deleted file mode 100644 index d0776a62d5..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Inject.php +++ /dev/null @@ -1,95 +0,0 @@ - - */ -final class Inject -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * Parameters, indexed by the parameter number (index) or name - * - * Used if the annotation is set on a method - * @var array - */ - private $parameters = []; - - /** - * @param array $values - */ - public function __construct(array $values) - { - // Process the parameters as a list AND as a parameter array (we don't know on what the annotation is) - - // @Inject(name="foo") - if (isset($values['name']) && is_string($values['name'])) { - $this->name = $values['name']; - return; - } - - // @Inject - if (! isset($values['value'])) { - return; - } - - $values = $values['value']; - - // @Inject("foo") - if (is_string($values)) { - $this->name = $values; - } - - // @Inject({...}) on a method - if (is_array($values)) { - foreach ($values as $key => $value) { - if (! is_string($value)) { - throw new AnnotationException(sprintf( - '@Inject({"param" = "value"}) expects "value" to be a string, %s given.', - json_encode($value) - )); - } - - $this->parameters[$key] = $value; - } - } - } - - /** - * @return string Name of the entry to inject - */ - public function getName() - { - return $this->name; - } - - /** - * @return array Parameters, indexed by the parameter number (index) or name - */ - public function getParameters() - { - return $this->parameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Injectable.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Injectable.php deleted file mode 100644 index 2176b6782e..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Annotation/Injectable.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @author Matthieu Napoli - */ -final class Injectable -{ - /** - * The scope of an class: prototype, singleton - * @var string|null - */ - private $scope; - - /** - * Should the object be lazy-loaded - * @var boolean|null - */ - private $lazy; - - /** - * @param array $values - */ - public function __construct(array $values) - { - if (isset($values['scope'])) { - if ($values['scope'] === 'prototype') { - $this->scope = Scope::PROTOTYPE; - } elseif ($values['scope'] === 'singleton') { - $this->scope = Scope::SINGLETON; - } else { - throw new UnexpectedValueException(sprintf("Value '%s' is not a valid scope", $values['scope'])); - } - } - if (isset($values['lazy'])) { - $this->lazy = (boolean) $values['lazy']; - } - } - - /** - * @return string|null - */ - public function getScope() - { - return $this->scope; - } - - /** - * @return boolean|null - */ - public function isLazy() - { - return $this->lazy; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Cache/ArrayCache.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Cache/ArrayCache.php deleted file mode 100644 index dcd6c0ffcd..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Cache/ArrayCache.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author David Abdemoulaie - */ -class ArrayCache implements Cache, FlushableCache, ClearableCache -{ - /** - * @var array $data - */ - private $data = []; - - public function fetch($id) - { - return $this->contains($id) ? $this->data[$id] : false; - } - - public function contains($id) - { - // isset() is required for performance optimizations, to avoid unnecessary function calls to array_key_exists. - return isset($this->data[$id]) || array_key_exists($id, $this->data); - } - - public function save($id, $data, $lifeTime = 0) - { - $this->data[$id] = $data; - - return true; - } - - public function delete($id) - { - unset($this->data[$id]); - - return true; - } - - public function getStats() - { - return null; - } - - public function flushAll() - { - $this->data = array(); - - return true; - } - - public function deleteAll() - { - return $this->flushAll(); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Container.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Container.php deleted file mode 100644 index 642e56b84f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Container.php +++ /dev/null @@ -1,341 +0,0 @@ - - */ -class Container implements ContainerInterface, FactoryInterface, \DI\InvokerInterface -{ - /** - * Map of entries with Singleton scope that are already resolved. - * @var array - */ - private $singletonEntries = []; - - /** - * @var DefinitionSource - */ - private $definitionSource; - - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - /** - * Array of entries being resolved. Used to avoid circular dependencies and infinite loops. - * @var array - */ - private $entriesBeingResolved = []; - - /** - * @var \Invoker\InvokerInterface|null - */ - private $invoker; - - /** - * Container that wraps this container. If none, points to $this. - * - * @var ContainerInterface - */ - private $wrapperContainer; - - /** - * Use the ContainerBuilder to ease constructing the Container. - * - * @see ContainerBuilder - * - * @param DefinitionSource $definitionSource - * @param ProxyFactory $proxyFactory - * @param ContainerInterface $wrapperContainer If the container is wrapped by another container. - */ - public function __construct( - DefinitionSource $definitionSource, - ProxyFactory $proxyFactory, - ContainerInterface $wrapperContainer = null - ) { - $this->wrapperContainer = $wrapperContainer ?: $this; - - $this->definitionSource = $definitionSource; - $this->definitionResolver = new ResolverDispatcher($this->wrapperContainer, $proxyFactory); - - // Auto-register the container - $this->singletonEntries['DI\Container'] = $this; - $this->singletonEntries['DI\FactoryInterface'] = $this; - $this->singletonEntries['DI\InvokerInterface'] = $this; - } - - /** - * Returns an entry of the container by its name. - * - * @param string $name Entry name or a class name. - * - * @throws InvalidArgumentException The name parameter must be of type string. - * @throws DependencyException Error while resolving the entry. - * @throws NotFoundException No entry found for the given name. - * @return mixed - */ - public function get($name) - { - if (! is_string($name)) { - throw new InvalidArgumentException(sprintf( - 'The name parameter must be of type string, %s given', - is_object($name) ? get_class($name) : gettype($name) - )); - } - - // Try to find the entry in the singleton map - if (array_key_exists($name, $this->singletonEntries)) { - return $this->singletonEntries[$name]; - } - - $definition = $this->definitionSource->getDefinition($name); - if (! $definition) { - throw new NotFoundException("No entry or class found for '$name'"); - } - - $value = $this->resolveDefinition($definition); - - // If the entry is singleton, we store it to always return it without recomputing it - if ($definition->getScope() === Scope::SINGLETON) { - $this->singletonEntries[$name] = $value; - } - - return $value; - } - - /** - * Build an entry of the container by its name. - * - * This method behave like get() except it forces the scope to "prototype", - * which means the definition of the entry will be re-evaluated each time. - * For example, if the entry is a class, then a new instance will be created each time. - * - * This method makes the container behave like a factory. - * - * @param string $name Entry name or a class name. - * @param array $parameters Optional parameters to use to build the entry. Use this to force specific parameters - * to specific values. Parameters not defined in this array will be resolved using - * the container. - * - * @throws InvalidArgumentException The name parameter must be of type string. - * @throws DependencyException Error while resolving the entry. - * @throws NotFoundException No entry found for the given name. - * @return mixed - */ - public function make($name, array $parameters = []) - { - if (! is_string($name)) { - throw new InvalidArgumentException(sprintf( - 'The name parameter must be of type string, %s given', - is_object($name) ? get_class($name) : gettype($name) - )); - } - - $definition = $this->definitionSource->getDefinition($name); - if (! $definition) { - // Try to find the entry in the singleton map - if (array_key_exists($name, $this->singletonEntries)) { - return $this->singletonEntries[$name]; - } - - throw new NotFoundException("No entry or class found for '$name'"); - } - - return $this->resolveDefinition($definition, $parameters); - } - - /** - * Test if the container can provide something for the given name. - * - * @param string $name Entry name or a class name. - * - * @throws InvalidArgumentException The name parameter must be of type string. - * @return bool - */ - public function has($name) - { - if (! is_string($name)) { - throw new InvalidArgumentException(sprintf( - 'The name parameter must be of type string, %s given', - is_object($name) ? get_class($name) : gettype($name) - )); - } - - if (array_key_exists($name, $this->singletonEntries)) { - return true; - } - - $definition = $this->definitionSource->getDefinition($name); - if ($definition === null) { - return false; - } - - return $this->definitionResolver->isResolvable($definition); - } - - /** - * Inject all dependencies on an existing instance - * - * @param object $instance Object to perform injection upon - * @throws InvalidArgumentException - * @throws DependencyException Error while injecting dependencies - * @return object $instance Returns the same instance - */ - public function injectOn($instance) - { - $objectDefinition = $this->definitionSource->getDefinition(get_class($instance)); - if (! $objectDefinition instanceof ObjectDefinition) { - return $instance; - } - - $definition = new InstanceDefinition($instance, $objectDefinition); - - $this->definitionResolver->resolve($definition); - - return $instance; - } - - /** - * Call the given function using the given parameters. - * - * Missing parameters will be resolved from the container. - * - * @param callable $callable Function to call. - * @param array $parameters Parameters to use. Can be indexed by the parameter names - * or not indexed (same order as the parameters). - * The array can also contain DI definitions, e.g. DI\get(). - * - * @return mixed Result of the function. - */ - public function call($callable, array $parameters = []) - { - return $this->getInvoker()->call($callable, $parameters); - } - - /** - * Define an object or a value in the container. - * - * @param string $name Entry name - * @param mixed|DefinitionHelper $value Value, use definition helpers to define objects - */ - public function set($name, $value) - { - if ($value instanceof DefinitionHelper) { - $value = $value->getDefinition($name); - } elseif ($value instanceof \Closure) { - $value = new FactoryDefinition($name, $value); - } - - if ($value instanceof Definition) { - $this->setDefinition($name, $value); - } else { - $this->singletonEntries[$name] = $value; - } - } - - /** - * Resolves a definition. - * - * Checks for circular dependencies while resolving the definition. - * - * @param Definition $definition - * @param array $parameters - * - * @throws DependencyException Error while resolving the entry. - * @return mixed - */ - private function resolveDefinition(Definition $definition, array $parameters = []) - { - $entryName = $definition->getName(); - - // Check if we are already getting this entry -> circular dependency - if (isset($this->entriesBeingResolved[$entryName])) { - throw new DependencyException("Circular dependency detected while trying to resolve entry '$entryName'"); - } - $this->entriesBeingResolved[$entryName] = true; - - // Resolve the definition - try { - $value = $this->definitionResolver->resolve($definition, $parameters); - } catch (Exception $exception) { - unset($this->entriesBeingResolved[$entryName]); - throw $exception; - } - - unset($this->entriesBeingResolved[$entryName]); - - return $value; - } - - private function setDefinition($name, Definition $definition) - { - if ($this->definitionSource instanceof CachedDefinitionSource) { - throw new \LogicException('You cannot set a definition at runtime on a container that has a cache configured. Doing so would risk caching the definition for the next execution, where it might be different. You can either put your definitions in a file, remove the cache or ->set() a raw value directly (PHP object, string, int, ...) instead of a PHP-DI definition.'); - } - - if (! $this->definitionSource instanceof MutableDefinitionSource) { - // This can happen if you instantiate the container yourself - throw new \LogicException('The container has not been initialized correctly'); - } - - // Clear existing entry if it exists - if (array_key_exists($name, $this->singletonEntries)) { - unset($this->singletonEntries[$name]); - } - - $this->definitionSource->addDefinition($definition); - } - - /** - * @return \Invoker\InvokerInterface - */ - private function getInvoker() - { - if (! $this->invoker) { - $parameterResolver = new ResolverChain([ - new DefinitionParameterResolver($this->definitionResolver), - new NumericArrayResolver, - new AssociativeArrayResolver, - new DefaultValueResolver, - new TypeHintContainerResolver($this->wrapperContainer), - ]); - - $this->invoker = new Invoker($parameterResolver, $this); - } - - return $this->invoker; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/ContainerBuilder.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/ContainerBuilder.php deleted file mode 100644 index 53871e2bd0..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/ContainerBuilder.php +++ /dev/null @@ -1,258 +0,0 @@ -build(); - * - * @since 3.2 - * @author Matthieu Napoli - */ -class ContainerBuilder -{ - /** - * Name of the container class, used to create the container. - * @var string - */ - private $containerClass; - - /** - * @var boolean - */ - private $useAutowiring = true; - - /** - * @var boolean - */ - private $useAnnotations = false; - - /** - * @var boolean - */ - private $ignorePhpDocErrors = false; - - /** - * @var Cache - */ - private $cache; - - /** - * If true, write the proxies to disk to improve performances. - * @var boolean - */ - private $writeProxiesToFile = false; - - /** - * Directory where to write the proxies (if $writeProxiesToFile is enabled). - * @var string - */ - private $proxyDirectory; - - /** - * If PHP-DI is wrapped in another container, this references the wrapper. - * @var ContainerInterface - */ - private $wrapperContainer; - - /** - * @var DefinitionSource[] - */ - private $definitionSources = []; - - /** - * Build a container configured for the dev environment. - * - * @return Container - */ - public static function buildDevContainer() - { - $builder = new self(); - return $builder->build(); - } - - /** - * @param string $containerClass Name of the container class, used to create the container. - */ - public function __construct($containerClass = 'DI\Container') - { - $this->containerClass = $containerClass; - } - - /** - * Build and return a container. - * - * @return Container - */ - public function build() - { - $sources = array_reverse($this->definitionSources); - if ($this->useAnnotations) { - $sources[] = new AnnotationReader($this->ignorePhpDocErrors); - } elseif ($this->useAutowiring) { - $sources[] = new Autowiring(); - } - - $chain = new SourceChain($sources); - - if ($this->cache) { - $source = new CachedDefinitionSource($chain, $this->cache); - $chain->setRootDefinitionSource($source); - } else { - $source = $chain; - // Mutable definition source - $source->setMutableDefinitionSource(new DefinitionArray()); - } - - $proxyFactory = new ProxyFactory($this->writeProxiesToFile, $this->proxyDirectory); - - $containerClass = $this->containerClass; - - return new $containerClass($source, $proxyFactory, $this->wrapperContainer); - } - - /** - * Enable or disable the use of autowiring to guess injections. - * - * Enabled by default. - * - * @param boolean $bool - * @return ContainerBuilder - */ - public function useAutowiring($bool) - { - $this->useAutowiring = $bool; - return $this; - } - - /** - * Enable or disable the use of annotations to guess injections. - * - * Disabled by default. - * - * @param boolean $bool - * @return ContainerBuilder - */ - public function useAnnotations($bool) - { - $this->useAnnotations = $bool; - return $this; - } - - /** - * Enable or disable ignoring phpdoc errors (non-existent classes in `@param` or `@var`) - * - * @param boolean $bool - * @return ContainerBuilder - */ - public function ignorePhpDocErrors($bool) - { - $this->ignorePhpDocErrors = $bool; - return $this; - } - - /** - * Enables the use of a cache for the definitions. - * - * @param Cache $cache Cache backend to use - * @return ContainerBuilder - */ - public function setDefinitionCache(Cache $cache) - { - $this->cache = $cache; - return $this; - } - - /** - * Configure the proxy generation - * - * For dev environment, use writeProxiesToFile(false) (default configuration) - * For production environment, use writeProxiesToFile(true, 'tmp/proxies') - * - * @param boolean $writeToFile If true, write the proxies to disk to improve performances - * @param string|null $proxyDirectory Directory where to write the proxies - * @return ContainerBuilder - * - * @throws InvalidArgumentException when writeToFile is set to true and the proxy directory is null - */ - public function writeProxiesToFile($writeToFile, $proxyDirectory = null) - { - $this->writeProxiesToFile = $writeToFile; - - if ($writeToFile && $proxyDirectory === null) { - throw new InvalidArgumentException( - "The proxy directory must be specified if you want to write proxies on disk" - ); - } - $this->proxyDirectory = $proxyDirectory; - - return $this; - } - - /** - * If PHP-DI's container is wrapped by another container, we can - * set this so that PHP-DI will use the wrapper rather than itself for building objects. - * - * @param ContainerInterface $otherContainer - * @return $this - */ - public function wrapContainer(ContainerInterface $otherContainer) - { - $this->wrapperContainer = $otherContainer; - - return $this; - } - - /** - * Add definitions to the container. - * - * @param string|array|DefinitionSource $definitions Can be an array of definitions, the - * name of a file containing definitions - * or a DefinitionSource object. - * @return $this - */ - public function addDefinitions($definitions) - { - if (is_string($definitions)) { - // File - $definitions = new DefinitionFile($definitions); - } elseif (is_array($definitions)) { - $definitions = new DefinitionArray($definitions); - } elseif (! $definitions instanceof DefinitionSource) { - throw new InvalidArgumentException(sprintf( - '%s parameter must be a string, an array or a DefinitionSource object, %s given', - 'ContainerBuilder::addDefinitions()', - is_object($definitions) ? get_class($definitions) : gettype($definitions) - )); - } - - $this->definitionSources[] = $definitions; - - return $this; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Debug.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Debug.php deleted file mode 100644 index a8b3ae2101..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Debug.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -class Debug -{ - /** - * Dump the definition to a string. - * - * @param Definition $definition - * - * @return string - */ - public static function dumpDefinition(Definition $definition) - { - static $dumper; - - if (! $dumper) { - $dumper = new DefinitionDumperDispatcher(); - } - - return $dumper->dump($definition); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/AliasDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/AliasDefinition.php deleted file mode 100644 index ea26506b12..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/AliasDefinition.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ -class AliasDefinition implements CacheableDefinition -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * Name of the target entry - * @var string - */ - private $targetEntryName; - - /** - * @param string $name Entry name - * @param string $targetEntryName Name of the target entry - */ - public function __construct($name, $targetEntryName) - { - $this->name = $name; - $this->targetEntryName = $targetEntryName; - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return Scope::PROTOTYPE; - } - - /** - * @return string - */ - public function getTargetEntryName() - { - return $this->targetEntryName; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinition.php deleted file mode 100644 index f225f89a5d..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinition.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ -class ArrayDefinition implements Definition -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * @var array - */ - private $values; - - /** - * @param string $name Entry name - * @param array $values - */ - public function __construct($name, array $values) - { - $this->name = $name; - $this->values = $values; - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return Scope::SINGLETON; - } - - /** - * @return array - */ - public function getValues() - { - return $this->values; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinitionExtension.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinitionExtension.php deleted file mode 100644 index e2f2b76f75..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ArrayDefinitionExtension.php +++ /dev/null @@ -1,61 +0,0 @@ - - */ -class ArrayDefinitionExtension extends ArrayDefinition implements HasSubDefinition -{ - /** - * @var ArrayDefinition - */ - private $subDefinition; - - /** - * {@inheritdoc} - */ - public function getValues() - { - if (! $this->subDefinition) { - return parent::getValues(); - } - - return array_merge($this->subDefinition->getValues(), parent::getValues()); - } - - /** - * @return string - */ - public function getSubDefinitionName() - { - return $this->getName(); - } - - /** - * {@inheritdoc} - */ - public function setSubDefinition(Definition $definition) - { - if (! $definition instanceof ArrayDefinition) { - throw new DefinitionException(sprintf( - 'Definition %s tries to add array entries but the previous definition is not an array', - $this->getName() - )); - } - - $this->subDefinition = $definition; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/CacheableDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/CacheableDefinition.php deleted file mode 100644 index eca8e3a86b..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/CacheableDefinition.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -interface CacheableDefinition extends Definition -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/DecoratorDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/DecoratorDefinition.php deleted file mode 100644 index 68b4b60d65..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/DecoratorDefinition.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ -class DecoratorDefinition extends FactoryDefinition implements Definition, HasSubDefinition -{ - /** - * @var Definition - */ - private $decorated; - - /** - * @return string - */ - public function getSubDefinitionName() - { - return $this->getName(); - } - - /** - * @param Definition $definition - */ - public function setSubDefinition(Definition $definition) - { - $this->decorated = $definition; - } - - /** - * @return Definition - */ - public function getDecoratedDefinition() - { - return $this->decorated; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Definition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Definition.php deleted file mode 100644 index 849c382c78..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Definition.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ -interface Definition -{ - /** - * Returns the name of the entry in the container - * - * @return string - */ - public function getName(); - - /** - * Returns the scope of the entry - * - * @return string - */ - public function getScope(); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/AliasDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/AliasDefinitionDumper.php deleted file mode 100644 index c50c6a7f0d..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/AliasDefinitionDumper.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ -class AliasDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof AliasDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with AliasDefinition objects, %s given', - get_class($definition) - )); - } - - if ($definition->getName()) { - return sprintf( - "get(%s => %s)", - $definition->getName(), - $definition->getTargetEntryName() - ); - } - - return sprintf( - "get(%s)", - $definition->getTargetEntryName() - ); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ArrayDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ArrayDefinitionDumper.php deleted file mode 100644 index c31b7b1f38..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ArrayDefinitionDumper.php +++ /dev/null @@ -1,65 +0,0 @@ - - */ -class ArrayDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof ArrayDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with ArrayDefinition objects, %s given', - get_class($definition) - )); - } - - $str = '[' . PHP_EOL; - - foreach ($definition->getValues() as $key => $value) { - if (is_string($key)) { - $key = "'" . $key . "'"; - } - - $str .= ' ' . $key . ' => '; - - if ($value instanceof DefinitionHelper) { - $nestedDefinition = Debug::dumpDefinition($value->getDefinition('')); - $str .= $this->indent($nestedDefinition); - } else { - $str .= var_export($value, true); - } - - $str .= ',' . PHP_EOL; - } - - $str .= ']'; - - return $str; - } - - private function indent($str) - { - return str_replace(PHP_EOL, PHP_EOL . " ", $str); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DecoratorDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DecoratorDefinitionDumper.php deleted file mode 100644 index 9aaa55fcea..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DecoratorDefinitionDumper.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ -class DecoratorDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof DecoratorDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with DecoratorDefinition objects, %s given', - get_class($definition) - )); - } - - return 'Decorate(' . $definition->getSubDefinitionName() . ')'; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumper.php deleted file mode 100644 index 7083c97a5c..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumper.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -interface DefinitionDumper -{ - /** - * Returns the given definition as string representation. - * - * @param Definition $definition - * - * @return string - */ - public function dump(Definition $definition); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumperDispatcher.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumperDispatcher.php deleted file mode 100644 index 89add31d07..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/DefinitionDumperDispatcher.php +++ /dev/null @@ -1,68 +0,0 @@ - - */ -class DefinitionDumperDispatcher implements DefinitionDumper -{ - /** - * Definition dumpers, indexed by the class of the definition they can dump. - * - * @var DefinitionDumper[]|null - */ - private $dumpers = []; - - public function __construct($dumpers = null) - { - $this->dumpers = $dumpers; - } - - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - $this->initialize(); - - $class = get_class($definition); - - if (! array_key_exists($class, $this->dumpers)) { - throw new \RuntimeException(sprintf( - 'There is no DefinitionDumper capable of dumping this definition of type %s', - $class - )); - } - - $dumper = $this->dumpers[$class]; - - return $dumper->dump($definition); - } - - private function initialize() - { - if ($this->dumpers === null) { - $this->dumpers = [ - 'DI\Definition\ValueDefinition' => new ValueDefinitionDumper(), - 'DI\Definition\FactoryDefinition' => new FactoryDefinitionDumper(), - 'DI\Definition\DecoratorDefinition' => new DecoratorDefinitionDumper(), - 'DI\Definition\AliasDefinition' => new AliasDefinitionDumper(), - 'DI\Definition\ObjectDefinition' => new ObjectDefinitionDumper(), - 'DI\Definition\EnvironmentVariableDefinition' => new EnvironmentVariableDefinitionDumper(), - ]; - } - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/EnvironmentVariableDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/EnvironmentVariableDefinitionDumper.php deleted file mode 100644 index 9886731761..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/EnvironmentVariableDefinitionDumper.php +++ /dev/null @@ -1,63 +0,0 @@ - - */ -class EnvironmentVariableDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof EnvironmentVariableDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with EnvironmentVariableDefinition objects, %s given', - get_class($definition) - )); - } - - $str = " variable = " . $definition->getVariableName(); - $str .= PHP_EOL . " optional = " . ($definition->isOptional() ? 'yes' : 'no'); - - if ($definition->isOptional()) { - $defaultValue = $definition->getDefaultValue(); - - if ($defaultValue instanceof DefinitionHelper) { - $nestedDefinition = Debug::dumpDefinition($defaultValue->getDefinition('')); - $defaultValueStr = $this->indent($nestedDefinition); - } else { - $defaultValueStr = var_export($defaultValue, true); - } - - $str .= PHP_EOL . " default = " . $defaultValueStr; - } - - return sprintf( - "Environment variable (" . PHP_EOL . "%s" . PHP_EOL . ")", - $str - ); - } - - private function indent($str) - { - return str_replace(PHP_EOL, PHP_EOL . " ", $str); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/FactoryDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/FactoryDefinitionDumper.php deleted file mode 100644 index 8477f5dab8..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/FactoryDefinitionDumper.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ -class FactoryDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof FactoryDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with FactoryDefinition objects, %s given', - get_class($definition) - )); - } - - return 'Factory'; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ObjectDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ObjectDefinitionDumper.php deleted file mode 100644 index 66d87d778a..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ObjectDefinitionDumper.php +++ /dev/null @@ -1,158 +0,0 @@ - - */ -class ObjectDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof ObjectDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with ObjectDefinition objects, %s given', - get_class($definition) - )); - } - - $className = $definition->getClassName(); - $classExist = class_exists($className) || interface_exists($className); - - // Class - if (! $classExist) { - $warning = '#UNKNOWN# '; - } else { - $class = new \ReflectionClass($className); - $warning = $class->isInstantiable() ? '' : '#NOT INSTANTIABLE# '; - } - $str = sprintf(' class = %s%s', $warning, $className); - - // Scope - $str .= PHP_EOL . " scope = " . $definition->getScope(); - - // Lazy - $str .= PHP_EOL . " lazy = " . var_export($definition->isLazy(), true); - - if ($classExist) { - // Constructor - $str .= $this->dumpConstructor($className, $definition); - - // Properties - $str .= $this->dumpProperties($definition); - - // Methods - $str .= $this->dumpMethods($className, $definition); - } - - return sprintf("Object (" . PHP_EOL . "%s" . PHP_EOL . ")", $str); - } - - private function dumpConstructor($className, ObjectDefinition $definition) - { - $str = ''; - - $constructorInjection = $definition->getConstructorInjection(); - - if ($constructorInjection !== null) { - $parameters = $this->dumpMethodParameters($className, $constructorInjection); - - $str .= sprintf(PHP_EOL . " __construct(" . PHP_EOL . " %s" . PHP_EOL . " )", $parameters); - } - - return $str; - } - - private function dumpProperties(ObjectDefinition $definition) - { - $str = ''; - - foreach ($definition->getPropertyInjections() as $propertyInjection) { - $value = $propertyInjection->getValue(); - if ($value instanceof EntryReference) { - $valueStr = sprintf('get(%s)', $value->getName()); - } else { - $valueStr = var_export($value, true); - } - - $str .= sprintf(PHP_EOL . " $%s = %s", $propertyInjection->getPropertyName(), $valueStr); - } - - return $str; - } - - private function dumpMethods($className, ObjectDefinition $definition) - { - $str = ''; - - foreach ($definition->getMethodInjections() as $methodInjection) { - $parameters = $this->dumpMethodParameters($className, $methodInjection); - - $str .= sprintf(PHP_EOL . " %s(" . PHP_EOL . " %s" . PHP_EOL . " )", $methodInjection->getMethodName(), $parameters); - } - - return $str; - } - - private function dumpMethodParameters($className, MethodInjection $methodInjection) - { - $methodReflection = new \ReflectionMethod($className, $methodInjection->getMethodName()); - - $args = []; - - $definitionParameters = $methodInjection->getParameters(); - - foreach ($methodReflection->getParameters() as $index => $parameter) { - if (array_key_exists($index, $definitionParameters)) { - $value = $definitionParameters[$index]; - - if ($value instanceof EntryReference) { - $args[] = sprintf('$%s = get(%s)', $parameter->getName(), $value->getName()); - } else { - $args[] = sprintf('$%s = %s', $parameter->getName(), var_export($value, true)); - } - continue; - } - - // If the parameter is optional and wasn't specified, we take its default value - if ($parameter->isOptional()) { - try { - $value = $parameter->getDefaultValue(); - - $args[] = sprintf( - '$%s = (default value) %s', - $parameter->getName(), - var_export($value, true) - ); - continue; - } catch (ReflectionException $e) { - // The default value can't be read through Reflection because it is a PHP internal class - } - } - - $args[] = sprintf('$%s = #UNDEFINED#', $parameter->getName()); - } - - return implode(PHP_EOL . ' ', $args); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/StringDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/StringDefinitionDumper.php deleted file mode 100644 index b7267d7cf4..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/StringDefinitionDumper.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ -class StringDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof StringDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with StringDefinition objects, %s given', - get_class($definition) - )); - } - - return $definition->getExpression(); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ValueDefinitionDumper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ValueDefinitionDumper.php deleted file mode 100644 index c6decdc277..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Dumper/ValueDefinitionDumper.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ -class ValueDefinitionDumper implements DefinitionDumper -{ - /** - * {@inheritdoc} - */ - public function dump(Definition $definition) - { - if (! $definition instanceof ValueDefinition) { - throw new \InvalidArgumentException(sprintf( - 'This definition dumper is only compatible with ValueDefinition objects, %s given', - get_class($definition) - )); - } - - ob_start(); - - var_dump($definition->getValue()); - - return sprintf( - "Value (" . PHP_EOL . " %s" . PHP_EOL . ")", - trim(ob_get_clean()) - ); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EntryReference.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EntryReference.php deleted file mode 100644 index 3a136045d3..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EntryReference.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ -class EntryReference implements DefinitionHelper -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * @param string $entryName Entry name - */ - public function __construct($entryName) - { - $this->name = $entryName; - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getDefinition($entryName) - { - return new AliasDefinition($entryName, $this->name); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EnvironmentVariableDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EnvironmentVariableDefinition.php deleted file mode 100644 index 1cc0997765..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/EnvironmentVariableDefinition.php +++ /dev/null @@ -1,116 +0,0 @@ - - */ -class EnvironmentVariableDefinition implements CacheableDefinition -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * The name of the environment variable - * @var string - */ - private $variableName; - - /** - * Whether or not the environment variable definition is optional - * - * If true and the environment variable given by $variableName has not been - * defined, $defaultValue is used. - * - * @var boolean - */ - private $isOptional; - - /** - * The default value to use if the environment variable is optional and not provided - * @var mixed - */ - private $defaultValue; - - /** - * @var string|null - */ - private $scope; - - /** - * @param string $name Entry name - * @param string $variableName The name of the environment variable - * @param boolean $isOptional Whether or not the environment variable definition is optional - * @param mixed $defaultValue The default value to use if the environment variable is optional and not provided - */ - public function __construct($name, $variableName, $isOptional = false, $defaultValue = null) - { - $this->name = $name; - $this->variableName = $variableName; - $this->isOptional = $isOptional; - $this->defaultValue = $defaultValue; - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * @return string The name of the environment variable - */ - public function getVariableName() - { - return $this->variableName; - } - - /** - * @return boolean Whether or not the environment variable definition is optional - */ - public function isOptional() - { - return $this->isOptional; - } - - /** - * @return mixed The default value to use if the environment variable is optional and not provided - */ - public function getDefaultValue() - { - return $this->defaultValue; - } - - /** - * @param string $scope - */ - public function setScope($scope) - { - $this->scope = $scope; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return $this->scope ?: Scope::SINGLETON; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/AnnotationException.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/AnnotationException.php deleted file mode 100644 index 3657c20c9f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/AnnotationException.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -class AnnotationException extends DefinitionException -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/DefinitionException.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/DefinitionException.php deleted file mode 100644 index cfa806aa20..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Exception/DefinitionException.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -class DefinitionException extends \Exception -{ - public static function create(Definition $definition, $message) - { - return new self(sprintf( - "%s" . PHP_EOL . "Full definition:" . PHP_EOL . "%s", - $message, - Debug::dumpDefinition($definition) - )); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/FactoryDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/FactoryDefinition.php deleted file mode 100644 index 6c007a08d5..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/FactoryDefinition.php +++ /dev/null @@ -1,75 +0,0 @@ - - */ -class FactoryDefinition implements Definition -{ - /** - * Entry name. - * @var string - */ - private $name; - - /** - * @var string - */ - private $scope; - - /** - * Callable that returns the value. - * @var callable - */ - private $factory; - - /** - * @param string $name Entry name - * @param callable $factory Callable that returns the value associated to the entry name. - * @param string|null $scope - */ - public function __construct($name, $factory, $scope = null) - { - $this->name = $name; - $this->factory = $factory; - $this->scope = $scope; - } - - /** - * @return string Entry name. - */ - public function getName() - { - return $this->name; - } - - /** - * Default scope is singleton: the callable is called once and the result is shared. - * - * {@inheritdoc} - */ - public function getScope() - { - return $this->scope ?: Scope::SINGLETON; - } - - /** - * @return callable Callable that returns the value associated to the entry name. - */ - public function getCallable() - { - return $this->factory; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/HasSubDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/HasSubDefinition.php deleted file mode 100644 index 76391200a8..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/HasSubDefinition.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ -interface HasSubDefinition extends Definition -{ - /** - * @return string - */ - public function getSubDefinitionName(); - - /** - * @param Definition $definition - */ - public function setSubDefinition(Definition $definition); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ArrayDefinitionExtensionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ArrayDefinitionExtensionHelper.php deleted file mode 100644 index 6961b4c1df..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ArrayDefinitionExtensionHelper.php +++ /dev/null @@ -1,46 +0,0 @@ - - */ -class ArrayDefinitionExtensionHelper implements DefinitionHelper -{ - /** - * @var array - */ - private $values = []; - - /** - * @param array $values Values to add to the array. - */ - public function __construct(array $values) - { - $this->values = $values; - } - - /** - * @param string $entryName Container entry name - * - * @return ArrayDefinitionExtension - */ - public function getDefinition($entryName) - { - return new ArrayDefinitionExtension($entryName, $this->values); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/DefinitionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/DefinitionHelper.php deleted file mode 100644 index 2493b2fc73..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/DefinitionHelper.php +++ /dev/null @@ -1,24 +0,0 @@ - - */ -interface DefinitionHelper -{ - /** - * @param string $entryName Container entry name - * @return \DI\Definition\Definition - */ - public function getDefinition($entryName); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/EnvironmentVariableDefinitionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/EnvironmentVariableDefinitionHelper.php deleted file mode 100644 index 8e525bd0ab..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/EnvironmentVariableDefinitionHelper.php +++ /dev/null @@ -1,64 +0,0 @@ - - */ -class EnvironmentVariableDefinitionHelper implements DefinitionHelper -{ - /** - * The name of the environment variable - * @var string - */ - private $variableName; - - /** - * Whether or not the environment variable definition is optional - * - * If true and the environment variable given by $variableName has not been - * defined, $defaultValue is used. - * - * @var boolean - */ - private $isOptional; - - /** - * The default value to use if the environment variable is optional and not provided - * @var mixed - */ - private $defaultValue; - - /** - * @param string $variableName The name of the environment variable - * @param boolean $isOptional Whether or not the environment variable definition is optional - * @param mixed $defaultValue The default value to use if the environment variable is optional and not provided - */ - public function __construct($variableName, $isOptional, $defaultValue = null) - { - $this->variableName = $variableName; - $this->isOptional = $isOptional; - $this->defaultValue = $defaultValue; - } - - /** - * @param string $entryName Container entry name - * - * @return EnvironmentVariableDefinition - */ - public function getDefinition($entryName) - { - return new EnvironmentVariableDefinition($entryName, $this->variableName, $this->isOptional, $this->defaultValue); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/FactoryDefinitionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/FactoryDefinitionHelper.php deleted file mode 100644 index 0278023cf1..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/FactoryDefinitionHelper.php +++ /dev/null @@ -1,72 +0,0 @@ - - */ -class FactoryDefinitionHelper implements DefinitionHelper -{ - /** - * @var callable - */ - private $factory; - - /** - * @var string|null - */ - private $scope; - - /** - * @var bool - */ - private $decorate; - - /** - * @param callable $factory - * @param bool $decorate Is the factory decorating a previous definition? - */ - public function __construct($factory, $decorate = false) - { - $this->factory = $factory; - $this->decorate = $decorate; - } - - /** - * Defines the scope of the entry. - * - * @param string $scope - * - * @return FactoryDefinitionHelper - */ - public function scope($scope) - { - $this->scope = $scope; - return $this; - } - - /** - * @param string $entryName Container entry name - * @return FactoryDefinition - */ - public function getDefinition($entryName) - { - if ($this->decorate) { - return new DecoratorDefinition($entryName, $this->factory, $this->scope); - } - - return new FactoryDefinition($entryName, $this->factory, $this->scope); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ObjectDefinitionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ObjectDefinitionHelper.php deleted file mode 100644 index a05725b440..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ObjectDefinitionHelper.php +++ /dev/null @@ -1,279 +0,0 @@ - - */ -class ObjectDefinitionHelper implements DefinitionHelper -{ - /** - * @var string|null - */ - private $className; - - /** - * @var boolean|null - */ - private $lazy; - - /** - * @var string|null - */ - private $scope; - - /** - * Array of constructor parameters. - * @var array - */ - private $constructor = []; - - /** - * Array of properties and their value. - * @var array - */ - private $properties = []; - - /** - * Array of methods and their parameters. - * @var array - */ - private $methods = []; - - /** - * Helper for defining an object. - * - * @param string|null $className Class name of the object. - * If null, the name of the entry (in the container) will be used as class name. - */ - public function __construct($className = null) - { - $this->className = $className; - } - - /** - * Define the entry as lazy. - * - * A lazy entry is created only when it is used, a proxy is injected instead. - * - * @return ObjectDefinitionHelper - */ - public function lazy() - { - $this->lazy = true; - return $this; - } - - /** - * Defines the scope of the entry. - * - * @param string $scope - * - * @return ObjectDefinitionHelper - */ - public function scope($scope) - { - $this->scope = $scope; - return $this; - } - - /** - * Defines the arguments to use to call the constructor. - * - * This method takes a variable number of arguments, example: - * ->constructor($param1, $param2, $param3) - * - * @param mixed ... Parameters to use for calling the constructor of the class. - * - * @return ObjectDefinitionHelper - */ - public function constructor() - { - $this->constructor = func_get_args(); - return $this; - } - - /** - * Defines a value for a specific argument of the constructor. - * - * This method is usually used together with annotations or autowiring, when a parameter - * is not (or cannot be) type-hinted. Using this method instead of constructor() allows to - * avoid defining all the parameters (letting them being resolved using annotations or autowiring) - * and only define one. - * - * @param string $parameter Parameter for which the value will be given. - * @param mixed $value Value to give to this parameter. - * - * @return ObjectDefinitionHelper - */ - public function constructorParameter($parameter, $value) - { - $this->constructor[$parameter] = $value; - return $this; - } - - /** - * Defines a value to inject in a property of the object. - * - * @param string $property Entry in which to inject the value. - * @param mixed $value Value to inject in the property. - * - * @return ObjectDefinitionHelper - */ - public function property($property, $value) - { - $this->properties[$property] = $value; - return $this; - } - - /** - * Defines a method to call and the arguments to use. - * - * This method takes a variable number of arguments after the method name, example: - * - * ->method('myMethod', $param1, $param2) - * - * Can be used multiple times to declare multiple calls. - * - * @param string $method Name of the method to call. - * @param mixed ... Parameters to use for calling the method. - * - * @return ObjectDefinitionHelper - */ - public function method($method) - { - $args = func_get_args(); - array_shift($args); - - if (! isset($this->methods[$method])) { - $this->methods[$method] = []; - } - - $this->methods[$method][] = $args; - - return $this; - } - - /** - * Defines a method to call and a value for a specific argument. - * - * This method is usually used together with annotations or autowiring, when a parameter - * is not (or cannot be) type-hinted. Using this method instead of method() allows to - * avoid defining all the parameters (letting them being resolved using annotations or - * autowiring) and only define one. - * - * If multiple calls to the method have been configured already (e.g. in a previous definition) - * then this method only overrides the parameter for the *first* call. - * - * @param string $method Name of the method to call. - * @param string $parameter Name or index of the parameter for which the value will be given. - * @param mixed $value Value to give to this parameter. - * - * @return ObjectDefinitionHelper - */ - public function methodParameter($method, $parameter, $value) - { - // Special case for the constructor - if ($method === '__construct') { - $this->constructor[$parameter] = $value; - return $this; - } - - if (! isset($this->methods[$method])) { - $this->methods[$method] = [0 => []]; - } - - $this->methods[$method][0][$parameter] = $value; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getDefinition($entryName) - { - $definition = new ObjectDefinition($entryName, $this->className); - - if ($this->lazy !== null) { - $definition->setLazy($this->lazy); - } - if ($this->scope !== null) { - $definition->setScope($this->scope); - } - - if (! empty($this->constructor)) { - $parameters = $this->fixParameters($definition, '__construct', $this->constructor); - $constructorInjection = MethodInjection::constructor($parameters); - $definition->setConstructorInjection($constructorInjection); - } - - if (! empty($this->properties)) { - foreach ($this->properties as $property => $value) { - $definition->addPropertyInjection( - new PropertyInjection($property, $value) - ); - } - } - - if (! empty($this->methods)) { - foreach ($this->methods as $method => $calls) { - foreach ($calls as $parameters) { - $parameters = $this->fixParameters($definition, $method, $parameters); - $methodInjection = new MethodInjection($method, $parameters); - $definition->addMethodInjection($methodInjection); - } - } - } - - return $definition; - } - - /** - * Fixes parameters indexed by the parameter name -> reindex by position. - * - * This is necessary so that merging definitions between sources is possible. - * - * @param ObjectDefinition $definition - * @param string $method - * @param array $parameters - * @throws DefinitionException - * @return array - */ - private function fixParameters(ObjectDefinition $definition, $method, $parameters) - { - $fixedParameters = []; - - foreach ($parameters as $index => $parameter) { - // Parameter indexed by the parameter name, we reindex it with its position - if (is_string($index)) { - $callable = [$definition->getClassName(), $method]; - try { - $reflectionParameter = new \ReflectionParameter($callable, $index); - } catch (\ReflectionException $e) { - throw DefinitionException::create($definition, "Parameter with name '$index' could not be found"); - } - - $index = $reflectionParameter->getPosition(); - } - - $fixedParameters[$index] = $parameter; - } - - return $fixedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/StringDefinitionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/StringDefinitionHelper.php deleted file mode 100644 index b6949527c8..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/StringDefinitionHelper.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -class StringDefinitionHelper implements DefinitionHelper -{ - /** - * @var string - */ - private $expression; - - public function __construct($expression) - { - $this->expression = $expression; - } - - /** - * @param string $entryName Container entry name - * - * @return StringDefinition - */ - public function getDefinition($entryName) - { - return new StringDefinition($entryName, $this->expression); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ValueDefinitionHelper.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ValueDefinitionHelper.php deleted file mode 100644 index 436ebe31d9..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Helper/ValueDefinitionHelper.php +++ /dev/null @@ -1,42 +0,0 @@ - - */ -class ValueDefinitionHelper implements DefinitionHelper -{ - /** - * @var mixed - */ - private $value; - - /** - * @param mixed $value - */ - public function __construct($value) - { - $this->value = $value; - } - - /** - * @param string $entryName Container entry name - * @return ValueDefinition - */ - public function getDefinition($entryName) - { - return new ValueDefinition($entryName, $this->value); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/InstanceDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/InstanceDefinition.php deleted file mode 100644 index 7be8e6571f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/InstanceDefinition.php +++ /dev/null @@ -1,76 +0,0 @@ - - */ -class InstanceDefinition implements Definition -{ - /** - * Instance on which to inject dependencies. - * - * @var object - */ - private $instance; - - /** - * @var ObjectDefinition - */ - private $objectDefinition; - - /** - * @param object $instance - * @param ObjectDefinition $objectDefinition - */ - public function __construct($instance, ObjectDefinition $objectDefinition) - { - $this->instance = $instance; - $this->objectDefinition = $objectDefinition; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - // Name are superfluous for instance definitions - return ''; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return Scope::PROTOTYPE; - } - - /** - * @return object - */ - public function getInstance() - { - return $this->instance; - } - - /** - * @return ObjectDefinition - */ - public function getObjectDefinition() - { - return $this->objectDefinition; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition.php deleted file mode 100644 index 03cbf99be9..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition.php +++ /dev/null @@ -1,337 +0,0 @@ - - */ -class ObjectDefinition implements Definition, CacheableDefinition, HasSubDefinition -{ - /** - * Entry name (most of the time, same as $classname) - * @var string - */ - private $name; - - /** - * Class name (if null, then the class name is $name) - * @var string|null - */ - private $className; - - /** - * Constructor parameter injection - * @var MethodInjection|null - */ - private $constructorInjection; - - /** - * Property injections - * @var PropertyInjection[] - */ - private $propertyInjections = []; - - /** - * Method calls - * @var MethodInjection[][] - */ - private $methodInjections = []; - - /** - * @var string|null - */ - private $scope; - - /** - * @var boolean|null - */ - private $lazy; - - /** - * Store if the class exists. Storing it (in cache) avoids recomputing this. - * - * @var bool - */ - private $classExists; - - /** - * Store if the class is instantiable. Storing it (in cache) avoids recomputing this. - * - * @var bool - */ - private $isInstantiable; - - /** - * @param string $name Class name - * @param string $className - */ - public function __construct($name, $className = null) - { - $this->name = (string) $name; - $this->setClassName($className); - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * @param string|null $className - */ - public function setClassName($className) - { - $this->className = $className; - - $this->updateCache(); - } - - /** - * @return string Class name - */ - public function getClassName() - { - if ($this->className !== null) { - return $this->className; - } - return $this->name; - } - - /** - * @return MethodInjection|null - */ - public function getConstructorInjection() - { - return $this->constructorInjection; - } - - /** - * @param MethodInjection $constructorInjection - */ - public function setConstructorInjection(MethodInjection $constructorInjection) - { - $this->constructorInjection = $constructorInjection; - } - - /** - * @return PropertyInjection[] Property injections - */ - public function getPropertyInjections() - { - return $this->propertyInjections; - } - - /** - * @param string $propertyName - * @return PropertyInjection - */ - public function getPropertyInjection($propertyName) - { - return isset($this->propertyInjections[$propertyName]) ? $this->propertyInjections[$propertyName] : null; - } - - /** - * @param PropertyInjection $propertyInjection - */ - public function addPropertyInjection(PropertyInjection $propertyInjection) - { - $this->propertyInjections[$propertyInjection->getPropertyName()] = $propertyInjection; - } - - /** - * @return MethodInjection[] Method injections - */ - public function getMethodInjections() - { - // Return array leafs - $injections = []; - array_walk_recursive($this->methodInjections, function ($injection) use (&$injections) { - $injections[] = $injection; - }); - return $injections; - } - - /** - * @param MethodInjection $methodInjection - */ - public function addMethodInjection(MethodInjection $methodInjection) - { - $method = $methodInjection->getMethodName(); - if (! isset($this->methodInjections[$method])) { - $this->methodInjections[$method] = []; - } - $this->methodInjections[$method][] = $methodInjection; - } - - /** - * @param string $scope - */ - public function setScope($scope) - { - $this->scope = $scope; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return $this->scope ?: Scope::SINGLETON; - } - - /** - * @param boolean|null $lazy - */ - public function setLazy($lazy) - { - $this->lazy = $lazy; - } - - /** - * @return bool - */ - public function isLazy() - { - if ($this->lazy !== null) { - return $this->lazy; - } else { - // Default value - return false; - } - } - - /** - * @return bool - */ - public function classExists() - { - return $this->classExists; - } - - /** - * @return bool - */ - public function isInstantiable() - { - return $this->isInstantiable; - } - - /** - * {@inheritdoc} - */ - public function getSubDefinitionName() - { - return $this->getClassName(); - } - - /** - * {@inheritdoc} - */ - public function setSubDefinition(Definition $definition) - { - if (! $definition instanceof ObjectDefinition) { - return; - } - - // The current prevails - if ($this->className === null) { - $this->setClassName($definition->className); - } - if ($this->scope === null) { - $this->scope = $definition->scope; - } - if ($this->lazy === null) { - $this->lazy = $definition->lazy; - } - - // Merge constructor injection - $this->mergeConstructorInjection($definition); - - // Merge property injections - $this->mergePropertyInjections($definition); - - // Merge method injections - $this->mergeMethodInjections($definition); - } - - private function mergeConstructorInjection(ObjectDefinition $definition) - { - if ($definition->getConstructorInjection() !== null) { - if ($this->constructorInjection !== null) { - // Merge - $this->constructorInjection->merge($definition->getConstructorInjection()); - } else { - // Set - $this->constructorInjection = $definition->getConstructorInjection(); - } - } - } - - private function mergePropertyInjections(ObjectDefinition $definition) - { - foreach ($definition->getPropertyInjections() as $propertyName => $propertyInjection) { - if (! array_key_exists($propertyName, $this->propertyInjections)) { - // Add - $this->propertyInjections[$propertyName] = $propertyInjection; - } - } - } - - private function mergeMethodInjections(ObjectDefinition $definition) - { - foreach ($definition->methodInjections as $methodName => $calls) { - if (array_key_exists($methodName, $this->methodInjections)) { - $this->mergeMethodCalls($calls, $methodName); - } else { - // Add - $this->methodInjections[$methodName] = $calls; - } - } - } - - private function mergeMethodCalls(array $calls, $methodName) - { - foreach ($calls as $index => $methodInjection) { - // Merge - if (array_key_exists($index, $this->methodInjections[$methodName])) { - // Merge - $this->methodInjections[$methodName][$index]->merge($methodInjection); - } else { - // Add - $this->methodInjections[$methodName][$index] = $methodInjection; - } - } - } - - private function updateCache() - { - $className = $this->getClassName(); - - $this->classExists = class_exists($className) || interface_exists($className); - - if (! $this->classExists) { - $this->isInstantiable = false; - return; - } - - $class = new ReflectionClass($className); - $this->isInstantiable = $class->isInstantiable(); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/MethodInjection.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/MethodInjection.php deleted file mode 100644 index 5861641fdb..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/MethodInjection.php +++ /dev/null @@ -1,94 +0,0 @@ - - */ -class MethodInjection implements Definition -{ - /** - * @var string - */ - private $methodName; - - /** - * @var array - */ - private $parameters = []; - - /** - * @param string $methodName - * @param array $parameters - */ - public function __construct($methodName, array $parameters = []) - { - $this->methodName = (string) $methodName; - $this->parameters = $parameters; - } - - public static function constructor(array $parameters = []) - { - return new self('__construct', $parameters); - } - - /** - * @return string Method name - */ - public function getMethodName() - { - return $this->methodName; - } - - /** - * @return array - */ - public function getParameters() - { - return $this->parameters; - } - - /** - * Replace the parameters of the definition by a new array of parameters. - * - * @param array $parameters - */ - public function replaceParameters(array $parameters) - { - $this->parameters = $parameters; - } - - public function merge(MethodInjection $definition) - { - // In case of conflicts, the current definition prevails. - $this->parameters = $this->parameters + $definition->parameters; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return Scope::PROTOTYPE; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/PropertyInjection.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/PropertyInjection.php deleted file mode 100644 index 07ecf9e322..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ObjectDefinition/PropertyInjection.php +++ /dev/null @@ -1,74 +0,0 @@ - - */ -class PropertyInjection -{ - /** - * Property name - * @var string - */ - private $propertyName; - - /** - * Value that should be injected in the property - * @var mixed - */ - private $value; - - /** - * Use for injecting in properties of parent classes: the class name - * must be the name of the parent class because private properties - * can be attached to the parent classes, not the one we are resolving. - * @var string|null - */ - private $className; - - /** - * @param string $propertyName Property name - * @param mixed $value Value that should be injected in the property - * @param string|null $className - */ - public function __construct($propertyName, $value, $className = null) - { - $this->propertyName = (string) $propertyName; - $this->value = $value; - $this->className = $className; - } - - /** - * @return string Property name - */ - public function getPropertyName() - { - return $this->propertyName; - } - - /** - * @return string Value that should be injected in the property - */ - public function getValue() - { - return $this->value; - } - - /** - * @return string|null - */ - public function getClassName() - { - return $this->className; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/AliasResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/AliasResolver.php deleted file mode 100644 index b92772d381..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/AliasResolver.php +++ /dev/null @@ -1,63 +0,0 @@ - - */ -class AliasResolver implements DefinitionResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * The resolver needs a container. - * This container will be used to get the entry to which the alias points to. - * - * @param ContainerInterface $container - */ - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * Resolve an alias definition to a value. - * - * This will return the entry the alias points to. - * - * @param AliasDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - return $this->container->get($definition->getTargetEntryName()); - } - - /** - * @param AliasDefinition $definition - * - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return $this->container->has($definition->getTargetEntryName()); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ArrayResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ArrayResolver.php deleted file mode 100644 index dcc76822bc..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ArrayResolver.php +++ /dev/null @@ -1,91 +0,0 @@ - - */ -class ArrayResolver implements DefinitionResolver -{ - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - /** - * @param DefinitionResolver $definitionResolver Used to resolve nested definitions. - */ - public function __construct(DefinitionResolver $definitionResolver) - { - $this->definitionResolver = $definitionResolver; - } - - /** - * Resolve an array definition to a value. - * - * An array definition can contain simple values or references to other entries. - * - * @param ArrayDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - $values = $definition->getValues(); - - $values = $this->resolveNestedDefinitions($definition, $values); - - return $values; - } - - /** - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } - - private function resolveNestedDefinitions(ArrayDefinition $definition, array $values) - { - foreach ($values as $key => $value) { - if ($value instanceof DefinitionHelper) { - $values[$key] = $this->resolveDefinition($value, $definition, $key); - } - } - - return $values; - } - - private function resolveDefinition(DefinitionHelper $value, ArrayDefinition $definition, $key) - { - try { - return $this->definitionResolver->resolve($value->getDefinition('')); - } catch (DependencyException $e) { - throw $e; - } catch (Exception $e) { - throw new DependencyException(sprintf( - "Error while resolving %s[%s]. %s", - $definition->getName(), - $key, - $e->getMessage() - ), 0, $e); - } - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DecoratorResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DecoratorResolver.php deleted file mode 100644 index db19a60cb6..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DecoratorResolver.php +++ /dev/null @@ -1,93 +0,0 @@ - - */ -class DecoratorResolver implements DefinitionResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - /** - * The resolver needs a container. This container will be passed to the factory as a parameter - * so that the factory can access other entries of the container. - * - * @param ContainerInterface $container - * @param DefinitionResolver $definitionResolver Used to resolve nested definitions. - */ - public function __construct(ContainerInterface $container, DefinitionResolver $definitionResolver) - { - $this->container = $container; - $this->definitionResolver = $definitionResolver; - } - - /** - * Resolve a decorator definition to a value. - * - * This will call the callable of the definition and pass it the decorated entry. - * - * @param DecoratorDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - $callable = $definition->getCallable(); - - if (! is_callable($callable)) { - throw new DefinitionException(sprintf( - 'The decorator "%s" is not callable', - $definition->getName() - )); - } - - $decoratedDefinition = $definition->getDecoratedDefinition(); - - if (! $decoratedDefinition instanceof Definition) { - if (! $definition->getSubDefinitionName()) { - throw new DefinitionException('Decorators cannot be nested in another definition'); - } - - throw new DefinitionException(sprintf( - 'Entry "%s" decorates nothing: no previous definition with the same name was found', - $definition->getName() - )); - } - - $decorated = $this->definitionResolver->resolve($decoratedDefinition); - - return call_user_func($callable, $decorated, $this->container); - } - - /** - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DefinitionResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DefinitionResolver.php deleted file mode 100644 index a4358b15ba..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/DefinitionResolver.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ -interface DefinitionResolver -{ - /** - * Resolve a definition to a value. - * - * @param Definition $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * - * @throws DefinitionException If the definition cannot be resolved. - * - * @return mixed Value obtained from the definition. - */ - public function resolve(Definition $definition, array $parameters = []); - - /** - * Check if a definition can be resolved. - * - * @param Definition $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * - * @return bool - */ - public function isResolvable(Definition $definition, array $parameters = []); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/EnvironmentVariableResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/EnvironmentVariableResolver.php deleted file mode 100644 index 0a9849ca3f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/EnvironmentVariableResolver.php +++ /dev/null @@ -1,81 +0,0 @@ - - */ -class EnvironmentVariableResolver implements DefinitionResolver -{ - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - /** - * @var callable - */ - private $variableReader; - - public function __construct(DefinitionResolver $definitionResolver, $variableReader = 'getenv') - { - $this->definitionResolver = $definitionResolver; - $this->variableReader = $variableReader; - } - - /** - * Resolve an environment variable definition to a value. - * - * @param EnvironmentVariableDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - $value = call_user_func($this->variableReader, $definition->getVariableName()); - - if (false !== $value) { - return $value; - } - - if (!$definition->isOptional()) { - throw new DefinitionException(sprintf( - "The environment variable '%s' has not been defined", - $definition->getVariableName() - )); - } - - $value = $definition->getDefaultValue(); - - // Nested definition - if ($value instanceof DefinitionHelper) { - return $this->definitionResolver->resolve($value->getDefinition('')); - } - - return $value; - } - - /** - * @param EnvironmentVariableDefinition $definition - * - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/FactoryResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/FactoryResolver.php deleted file mode 100644 index 28c797b70f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/FactoryResolver.php +++ /dev/null @@ -1,82 +0,0 @@ - - */ -class FactoryResolver implements DefinitionResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * @var Invoker|null - */ - private $invoker; - - /** - * The resolver needs a container. This container will be passed to the factory as a parameter - * so that the factory can access other entries of the container. - * - * @param ContainerInterface $container - */ - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * Resolve a factory definition to a value. - * - * This will call the callable of the definition. - * - * @param FactoryDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - $callable = $definition->getCallable(); - - if (! is_callable($callable)) { - throw new DefinitionException(sprintf( - 'The factory definition "%s" is not callable', - $definition->getName() - )); - } - - if (! $this->invoker) { - $this->invoker = new Invoker(new NumericArrayResolver, $this->container); - } - - return $this->invoker->call($callable, [$this->container]); - } - - /** - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/InstanceInjector.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/InstanceInjector.php deleted file mode 100644 index eb825bae8b..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/InstanceInjector.php +++ /dev/null @@ -1,53 +0,0 @@ - - */ -class InstanceInjector extends ObjectCreator -{ - /** - * Injects dependencies on an existing instance. - * - * @param InstanceDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - try { - $this->injectMethodsAndProperties($definition->getInstance(), $definition->getObjectDefinition()); - } catch (NotFoundException $e) { - $message = sprintf( - "Error while injecting dependencies into %s: %s", - get_class($definition->getInstance()), - $e->getMessage() - ); - throw new DependencyException($message, 0, $e); - } - } - - /** - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ObjectCreator.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ObjectCreator.php deleted file mode 100644 index cc2169a818..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ObjectCreator.php +++ /dev/null @@ -1,258 +0,0 @@ - - */ -class ObjectCreator implements DefinitionResolver -{ - /** - * @var ProxyFactory - */ - private $proxyFactory; - - /** - * @var ParameterResolver - */ - private $parameterResolver; - - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - /** - * @param DefinitionResolver $definitionResolver Used to resolve nested definitions. - * @param ProxyFactory $proxyFactory Used to create proxies for lazy injections. - */ - public function __construct( - DefinitionResolver $definitionResolver, - ProxyFactory $proxyFactory - ) { - $this->definitionResolver = $definitionResolver; - $this->proxyFactory = $proxyFactory; - $this->parameterResolver = new ParameterResolver($definitionResolver); - } - - /** - * Resolve a class definition to a value. - * - * This will create a new instance of the class using the injections points defined. - * - * @param ObjectDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - // Lazy? - if ($definition->isLazy()) { - return $this->createProxy($definition, $parameters); - } - - return $this->createInstance($definition, $parameters); - } - - /** - * The definition is not resolvable if the class is not instantiable (interface or abstract) - * or if the class doesn't exist. - * - * @param ObjectDefinition $definition - * - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return $definition->isInstantiable(); - } - - /** - * Returns a proxy instance - * - * @param ObjectDefinition $definition - * @param array $parameters - * - * @return LazyLoadingInterface Proxy instance - */ - private function createProxy(ObjectDefinition $definition, array $parameters) - { - /** @noinspection PhpUnusedParameterInspection */ - $proxy = $this->proxyFactory->createProxy( - $definition->getClassName(), - function (& $wrappedObject, $proxy, $method, $params, & $initializer) use ($definition, $parameters) { - $wrappedObject = $this->createInstance($definition, $parameters); - $initializer = null; // turning off further lazy initialization - return true; - } - ); - - return $proxy; - } - - /** - * Creates an instance of the class and injects dependencies.. - * - * @param ObjectDefinition $definition - * @param array $parameters Optional parameters to use to create the instance. - * - * @throws DefinitionException - * @throws DependencyException - * @return object - */ - private function createInstance(ObjectDefinition $definition, array $parameters) - { - $this->assertClassExists($definition); - - $classname = $definition->getClassName(); - $classReflection = new ReflectionClass($classname); - - $this->assertClassIsInstantiable($definition); - - $constructorInjection = $definition->getConstructorInjection(); - - try { - $args = $this->parameterResolver->resolveParameters( - $constructorInjection, - $classReflection->getConstructor(), - $parameters - ); - - if (count($args) > 0) { - $object = $classReflection->newInstanceArgs($args); - } else { - $object = new $classname; - } - - $this->injectMethodsAndProperties($object, $definition); - } catch (NotFoundException $e) { - throw new DependencyException(sprintf( - "Error while injecting dependencies into %s: %s", - $classReflection->getName(), - $e->getMessage() - ), 0, $e); - } catch (DefinitionException $e) { - throw DefinitionException::create($definition, sprintf( - "Entry %s cannot be resolved: %s", - $definition->getName(), - $e->getMessage() - )); - } - - if (! $object) { - throw new DependencyException(sprintf( - "Entry %s cannot be resolved: %s could not be constructed", - $definition->getName(), - $classReflection->getName() - )); - } - - return $object; - } - - protected function injectMethodsAndProperties($object, ObjectDefinition $objectDefinition) - { - // Property injections - foreach ($objectDefinition->getPropertyInjections() as $propertyInjection) { - $this->injectProperty($object, $propertyInjection); - } - - // Method injections - foreach ($objectDefinition->getMethodInjections() as $methodInjection) { - $methodReflection = new \ReflectionMethod($object, $methodInjection->getMethodName()); - $args = $this->parameterResolver->resolveParameters($methodInjection, $methodReflection); - - $methodReflection->invokeArgs($object, $args); - } - } - - /** - * Inject dependencies into properties. - * - * @param object $object Object to inject dependencies into - * @param PropertyInjection $propertyInjection Property injection definition - * - * @throws DependencyException - * @throws DefinitionException - */ - private function injectProperty($object, PropertyInjection $propertyInjection) - { - $propertyName = $propertyInjection->getPropertyName(); - - $className = $propertyInjection->getClassName(); - $className = $className ?: get_class($object); - $property = new ReflectionProperty($className, $propertyName); - - $value = $propertyInjection->getValue(); - - if ($value instanceof DefinitionHelper) { - /** @var Definition $nestedDefinition */ - $nestedDefinition = $value->getDefinition(''); - - try { - $value = $this->definitionResolver->resolve($nestedDefinition); - } catch (DependencyException $e) { - throw $e; - } catch (Exception $e) { - throw new DependencyException(sprintf( - "Error while injecting in %s::%s. %s", - get_class($object), - $propertyName, - $e->getMessage() - ), 0, $e); - } - } - - if (! $property->isPublic()) { - $property->setAccessible(true); - } - $property->setValue($object, $value); - } - - private function assertClassExists(ObjectDefinition $definition) - { - if (! $definition->classExists()) { - throw DefinitionException::create($definition, - sprintf( - "Entry %s cannot be resolved: class %s doesn't exist", - $definition->getName(), - $definition->getClassName() - )); - } - } - - private function assertClassIsInstantiable(ObjectDefinition $definition) - { - if (! $definition->isInstantiable()) { - throw DefinitionException::create($definition, - sprintf( - "Entry %s cannot be resolved: class %s is not instantiable", - $definition->getName(), - $definition->getClassName() - )); - } - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ParameterResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ParameterResolver.php deleted file mode 100644 index 63b0ba975a..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ParameterResolver.php +++ /dev/null @@ -1,140 +0,0 @@ - - */ -class ParameterResolver -{ - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - /** - * @param DefinitionResolver $definitionResolver Will be used to resolve nested definitions. - */ - public function __construct(DefinitionResolver $definitionResolver) - { - $this->definitionResolver = $definitionResolver; - } - - /** - * @param MethodInjection $definition - * @param \ReflectionFunctionAbstract $functionReflection - * @param array $parameters - * - * @throws DefinitionException A parameter has no value defined or guessable. - * @return array Parameters to use to call the function. - */ - public function resolveParameters( - MethodInjection $definition = null, - \ReflectionFunctionAbstract $functionReflection = null, - array $parameters = [] - ) { - $args = []; - - if (! $functionReflection) { - return $args; - } - - $definitionParameters = $definition ? $definition->getParameters() : array(); - - foreach ($functionReflection->getParameters() as $index => $parameter) { - if (array_key_exists($parameter->getName(), $parameters)) { - // Look in the $parameters array - $value = &$parameters[$parameter->getName()]; - } elseif (array_key_exists($index, $definitionParameters)) { - // Look in the definition - $value = &$definitionParameters[$index]; - } else { - // If the parameter is optional and wasn't specified, we take its default value - if ($parameter->isOptional()) { - $args[] = $this->getParameterDefaultValue($parameter, $functionReflection); - continue; - } - - throw new DefinitionException(sprintf( - "The parameter '%s' of %s has no value defined or guessable", - $parameter->getName(), - $this->getFunctionName($functionReflection) - )); - } - - if ($value instanceof DefinitionHelper) { - $nestedDefinition = $value->getDefinition(''); - - // If the container cannot produce the entry, we can use the default parameter value - if ($parameter->isOptional() && !$this->definitionResolver->isResolvable($nestedDefinition)) { - $value = $this->getParameterDefaultValue($parameter, $functionReflection); - } else { - $value = $this->definitionResolver->resolve($nestedDefinition); - } - } - - $args[] = &$value; - } - - return $args; - } - - /** - * Returns the default value of a function parameter. - * - * @param \ReflectionParameter $parameter - * @param \ReflectionFunctionAbstract $function - * - * @throws DefinitionException Can't get default values from PHP internal classes and functions - * @return mixed - */ - private function getParameterDefaultValue( - \ReflectionParameter $parameter, - \ReflectionFunctionAbstract $function - ) { - try { - return $parameter->getDefaultValue(); - } catch (\ReflectionException $e) { - throw new DefinitionException(sprintf( - "The parameter '%s' of %s has no type defined or guessable. It has a default value, " - . "but the default value can't be read through Reflection because it is a PHP internal class.", - $parameter->getName(), - $this->getFunctionName($function) - )); - } - } - - private function getFunctionName(\ReflectionFunctionAbstract $reflectionFunction) - { - if ($reflectionFunction instanceof \ReflectionMethod) { - return sprintf( - '%s::%s', - $reflectionFunction->getDeclaringClass()->getName(), - $reflectionFunction->getName() - ); - } elseif ($reflectionFunction->isClosure()) { - return sprintf( - 'closure defined in %s at line %d', - $reflectionFunction->getFileName(), - $reflectionFunction->getStartLine() - ); - } - - return $reflectionFunction->getName(); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ResolverDispatcher.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ResolverDispatcher.php deleted file mode 100644 index d93d57c74a..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ResolverDispatcher.php +++ /dev/null @@ -1,138 +0,0 @@ - - */ -class ResolverDispatcher implements DefinitionResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * @var ProxyFactory - */ - private $proxyFactory; - - private $valueResolver; - private $arrayResolver; - private $factoryResolver; - private $decoratorResolver; - private $aliasResolver; - private $objectResolver; - private $instanceResolver; - private $envVariableResolver; - private $stringResolver; - - public function __construct(ContainerInterface $container, ProxyFactory $proxyFactory) - { - $this->container = $container; - $this->proxyFactory = $proxyFactory; - } - - /** - * Resolve a definition to a value. - * - * @param Definition $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * - * @throws DefinitionException If the definition cannot be resolved. - * - * @return mixed Value obtained from the definition. - */ - public function resolve(Definition $definition, array $parameters = []) - { - $definitionResolver = $this->getDefinitionResolver($definition); - - return $definitionResolver->resolve($definition, $parameters); - } - - /** - * Check if a definition can be resolved. - * - * @param Definition $definition Object that defines how the value should be obtained. - * @param array $parameters Optional parameters to use to build the entry. - * - * @return bool - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - $definitionResolver = $this->getDefinitionResolver($definition); - - return $definitionResolver->isResolvable($definition, $parameters); - } - - /** - * Returns a resolver capable of handling the given definition. - * - * @param Definition $definition - * - * @throws \RuntimeException No definition resolver was found for this type of definition. - * @return DefinitionResolver - */ - private function getDefinitionResolver(Definition $definition) - { - switch (true) { - case ($definition instanceof \DI\Definition\ObjectDefinition): - if (! $this->objectResolver) { - $this->objectResolver = new ObjectCreator($this, $this->proxyFactory); - } - return $this->objectResolver; - case ($definition instanceof \DI\Definition\ValueDefinition): - if (! $this->valueResolver) { - $this->valueResolver = new ValueResolver(); - } - return $this->valueResolver; - case ($definition instanceof \DI\Definition\AliasDefinition): - if (! $this->aliasResolver) { - $this->aliasResolver = new AliasResolver($this->container); - } - return $this->aliasResolver; - case ($definition instanceof \DI\Definition\DecoratorDefinition): - if (! $this->decoratorResolver) { - $this->decoratorResolver = new DecoratorResolver($this->container, $this); - } - return $this->decoratorResolver; - case ($definition instanceof \DI\Definition\FactoryDefinition): - if (! $this->factoryResolver) { - $this->factoryResolver = new FactoryResolver($this->container); - } - return $this->factoryResolver; - case ($definition instanceof \DI\Definition\ArrayDefinition): - if (! $this->arrayResolver) { - $this->arrayResolver = new ArrayResolver($this); - } - return $this->arrayResolver; - case ($definition instanceof \DI\Definition\EnvironmentVariableDefinition): - if (! $this->envVariableResolver) { - $this->envVariableResolver = new EnvironmentVariableResolver($this); - } - return $this->envVariableResolver; - case ($definition instanceof \DI\Definition\StringDefinition): - if (! $this->stringResolver) { - $this->stringResolver = new StringResolver($this->container); - } - return $this->stringResolver; - case ($definition instanceof \DI\Definition\InstanceDefinition): - if (! $this->instanceResolver) { - $this->instanceResolver = new InstanceInjector($this, $this->proxyFactory); - } - return $this->instanceResolver; - default: - throw new \RuntimeException('No definition resolver was configured for definition of type ' . get_class($definition)); - } - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/StringResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/StringResolver.php deleted file mode 100644 index 96854d40cf..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/StringResolver.php +++ /dev/null @@ -1,81 +0,0 @@ - - */ -class StringResolver implements DefinitionResolver -{ - /** - * @var ContainerInterface - */ - private $container; - - /** - * The resolver needs a container. - * This container will be used to get the entry to which the alias points to. - * - * @param ContainerInterface $container - */ - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * Resolve a value definition to a value. - * - * A value definition is simple, so this will just return the value of the ValueDefinition. - * - * @param StringDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - $expression = $definition->getExpression(); - - $result = preg_replace_callback('#\{([^\{\}]+)\}#', function (array $matches) use ($definition) { - try { - return $this->container->get($matches[1]); - } catch (NotFoundException $e) { - throw new DependencyException(sprintf( - "Error while parsing string expression for entry '%s': %s", - $definition->getName(), - $e->getMessage() - ), 0, $e); - } - }, $expression); - - if ($result === null) { - throw new \RuntimeException(sprintf('An unknown error occurred while parsing the string definition: \'%s\'', $expression)); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ValueResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ValueResolver.php deleted file mode 100644 index 04d98fcf49..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Resolver/ValueResolver.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ -class ValueResolver implements DefinitionResolver -{ - /** - * Resolve a value definition to a value. - * - * A value definition is simple, so this will just return the value of the ValueDefinition. - * - * @param ValueDefinition $definition - * - * {@inheritdoc} - */ - public function resolve(Definition $definition, array $parameters = []) - { - return $definition->getValue(); - } - - /** - * {@inheritdoc} - */ - public function isResolvable(Definition $definition, array $parameters = []) - { - return true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/AnnotationReader.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/AnnotationReader.php deleted file mode 100644 index e12ab86e05..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/AnnotationReader.php +++ /dev/null @@ -1,280 +0,0 @@ - - */ -class AnnotationReader implements DefinitionSource -{ - /** - * @var Reader - */ - private $annotationReader; - - /** - * @var PhpDocReader - */ - private $phpDocReader; - - /** - * @var bool - */ - private $ignorePhpDocErrors; - - public function __construct($ignorePhpDocErrors = false) - { - $this->ignorePhpDocErrors = (bool) $ignorePhpDocErrors; - } - - /** - * {@inheritdoc} - * @throws AnnotationException - * @throws InvalidArgumentException The class doesn't exist - */ - public function getDefinition($name) - { - if (!class_exists($name) && !interface_exists($name)) { - return null; - } - - $class = new ReflectionClass($name); - $definition = new ObjectDefinition($name); - - $this->readInjectableAnnotation($class, $definition); - - // Browse the class properties looking for annotated properties - $this->readProperties($class, $definition); - - // Browse the object's methods looking for annotated methods - $this->readMethods($class, $definition); - - return $definition; - } - - /** - * Browse the class properties looking for annotated properties. - */ - private function readProperties(ReflectionClass $class, ObjectDefinition $definition) - { - foreach ($class->getProperties() as $property) { - if ($property->isStatic()) { - continue; - } - $this->readProperty($property, $definition); - } - - // Read also the *private* properties of the parent classes - /** @noinspection PhpAssignmentInConditionInspection */ - while ($class = $class->getParentClass()) { - foreach ($class->getProperties(ReflectionProperty::IS_PRIVATE) as $property) { - if ($property->isStatic()) { - continue; - } - $this->readProperty($property, $definition, $class->getName()); - } - } - } - - private function readProperty(ReflectionProperty $property, ObjectDefinition $definition, $classname = null) - { - // Look for @Inject annotation - /** @var $annotation Inject */ - $annotation = $this->getAnnotationReader()->getPropertyAnnotation($property, 'DI\Annotation\Inject'); - if ($annotation === null) { - return null; - } - - // @Inject("name") or look for @var content - $entryName = $annotation->getName() ?: $this->getPhpDocReader()->getPropertyClass($property); - - if ($entryName === null) { - throw new AnnotationException(sprintf( - '@Inject found on property %s::%s but unable to guess what to inject, use a @var annotation', - $property->getDeclaringClass()->getName(), - $property->getName() - )); - } - - $definition->addPropertyInjection( - new PropertyInjection($property->getName(), new EntryReference($entryName), $classname) - ); - } - - /** - * Browse the object's methods looking for annotated methods. - */ - private function readMethods(ReflectionClass $class, ObjectDefinition $objectDefinition) - { - // This will look in all the methods, including those of the parent classes - foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - if ($method->isStatic()) { - continue; - } - - $methodInjection = $this->getMethodInjection($method); - - if (! $methodInjection) { - continue; - } - - if ($method->isConstructor()) { - $objectDefinition->setConstructorInjection($methodInjection); - } else { - $objectDefinition->addMethodInjection($methodInjection); - } - } - } - - private function getMethodInjection(ReflectionMethod $method) - { - // Look for @Inject annotation - /** @var $annotation Inject|null */ - try { - $annotation = $this->getAnnotationReader()->getMethodAnnotation($method, 'DI\Annotation\Inject'); - } catch (AnnotationException $e) { - throw new AnnotationException(sprintf( - '@Inject annotation on %s::%s is malformed. %s', - $method->getDeclaringClass()->getName(), - $method->getName(), - $e->getMessage() - ), 0, $e); - } - $annotationParameters = $annotation ? $annotation->getParameters() : []; - - // @Inject on constructor is implicit - if (! ($annotation || $method->isConstructor())) { - return null; - } - - $parameters = []; - foreach ($method->getParameters() as $index => $parameter) { - $entryName = $this->getMethodParameter($index, $parameter, $annotationParameters); - - if ($entryName !== null) { - $parameters[$index] = new EntryReference($entryName); - } - } - - if ($method->isConstructor()) { - return MethodInjection::constructor($parameters); - } else { - return new MethodInjection($method->getName(), $parameters); - } - } - - /** - * @param int $parameterIndex - * @param ReflectionParameter $parameter - * @param array $annotationParameters - * - * @return string|null Entry name or null if not found. - */ - private function getMethodParameter($parameterIndex, ReflectionParameter $parameter, array $annotationParameters) - { - // @Inject has definition for this parameter (by index, or by name) - if (isset($annotationParameters[$parameterIndex])) { - return $annotationParameters[$parameterIndex]; - } - if (isset($annotationParameters[$parameter->getName()])) { - return $annotationParameters[$parameter->getName()]; - } - - // Skip optional parameters if not explicitly defined - if ($parameter->isOptional()) { - return null; - } - - // Try to use the type-hinting - $parameterClass = $parameter->getClass(); - if ($parameterClass) { - return $parameterClass->getName(); - } - - // Last resort, look for @param tag - return $this->getPhpDocReader()->getParameterClass($parameter); - } - - /** - * @return Reader The annotation reader - */ - public function getAnnotationReader() - { - if ($this->annotationReader === null) { - AnnotationRegistry::registerAutoloadNamespace('DI\Annotation', __DIR__ . '/../../../'); - $this->annotationReader = new SimpleAnnotationReader(); - $this->annotationReader->addNamespace('DI\Annotation'); - } - - return $this->annotationReader; - } - - /** - * @return PhpDocReader - */ - private function getPhpDocReader() - { - if ($this->phpDocReader === null) { - $this->phpDocReader = new PhpDocReader($this->ignorePhpDocErrors); - } - - return $this->phpDocReader; - } - - private function readInjectableAnnotation(ReflectionClass $class, ObjectDefinition $definition) - { - try { - /** @var $annotation Injectable|null */ - $annotation = $this->getAnnotationReader() - ->getClassAnnotation($class, 'DI\Annotation\Injectable'); - } catch (UnexpectedValueException $e) { - throw new DefinitionException(sprintf( - 'Error while reading @Injectable on %s: %s', - $class->getName(), - $e->getMessage() - ), 0, $e); - } - - if (! $annotation) { - return; - } - - if ($annotation->getScope()) { - $definition->setScope($annotation->getScope()); - } - if ($annotation->isLazy() !== null) { - $definition->setLazy($annotation->isLazy()); - } - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/Autowiring.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/Autowiring.php deleted file mode 100644 index 730799bc8b..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/Autowiring.php +++ /dev/null @@ -1,68 +0,0 @@ - - */ -class Autowiring implements DefinitionSource -{ - /** - * {@inheritdoc} - */ - public function getDefinition($name) - { - if (!class_exists($name) && !interface_exists($name)) { - return null; - } - - $definition = new ObjectDefinition($name); - - // Constructor - $class = new \ReflectionClass($name); - $constructor = $class->getConstructor(); - if ($constructor && $constructor->isPublic()) { - $definition->setConstructorInjection( - MethodInjection::constructor($this->getParametersDefinition($constructor)) - ); - } - - return $definition; - } - - /** - * Read the type-hinting from the parameters of the function. - */ - private function getParametersDefinition(\ReflectionFunctionAbstract $constructor) - { - $parameters = []; - - foreach ($constructor->getParameters() as $index => $parameter) { - // Skip optional parameters - if ($parameter->isOptional()) { - continue; - } - - $parameterClass = $parameter->getClass(); - - if ($parameterClass) { - $parameters[$index] = new EntryReference($parameterClass->getName()); - } - } - - return $parameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/CachedDefinitionSource.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/CachedDefinitionSource.php deleted file mode 100644 index 19bc7c0e62..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/CachedDefinitionSource.php +++ /dev/null @@ -1,104 +0,0 @@ - - */ -class CachedDefinitionSource implements DefinitionSource -{ - /** - * Prefix for cache key, to avoid conflicts with other systems using the same cache - * @var string - */ - const CACHE_PREFIX = 'DI\\Definition\\'; - - /** - * @var DefinitionSource - */ - private $source; - - /** - * @var Cache - */ - private $cache; - - public function __construct(DefinitionSource $source, Cache $cache) - { - $this->source = $source; - $this->cache = $cache; - } - - /** - * {@inheritdoc} - */ - public function getDefinition($name) - { - // Look in cache - $definition = $this->fetchFromCache($name); - - if ($definition === false) { - $definition = $this->source->getDefinition($name); - - // Save to cache - if ($definition === null || ($definition instanceof CacheableDefinition)) { - $this->saveToCache($name, $definition); - } - } - - return $definition; - } - - /** - * @return Cache - */ - public function getCache() - { - return $this->cache; - } - - /** - * Fetches a definition from the cache - * - * @param string $name Entry name - * @return Definition|null|boolean The cached definition, null or false if the value is not already cached - */ - private function fetchFromCache($name) - { - $cacheKey = self::CACHE_PREFIX . $name; - - $data = $this->cache->fetch($cacheKey); - - if ($data !== false) { - return $data; - } - - return false; - } - - /** - * Saves a definition to the cache - * - * @param string $name Entry name - * @param Definition|null $definition - */ - private function saveToCache($name, Definition $definition = null) - { - $cacheKey = self::CACHE_PREFIX . $name; - - $this->cache->save($cacheKey, $definition); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionArray.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionArray.php deleted file mode 100644 index 21b6eeb9ce..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionArray.php +++ /dev/null @@ -1,142 +0,0 @@ - - */ -class DefinitionArray implements DefinitionSource, MutableDefinitionSource -{ - const WILDCARD = '*'; - /** - * Matches anything except "\" - */ - const WILDCARD_PATTERN = '([^\\\\]+)'; - - /** - * DI definitions in a PHP array - * @var array - */ - private $definitions = []; - - /** - * @param array $definitions - */ - public function __construct(array $definitions = []) - { - $this->definitions = $definitions; - } - - /** - * @param array $definitions DI definitions in a PHP array indexed by the definition name. - */ - public function addDefinitions(array $definitions) - { - // The newly added data prevails - // "for keys that exist in both arrays, the elements from the left-hand array will be used" - $this->definitions = $definitions + $this->definitions; - } - - /** - * {@inheritdoc} - */ - public function addDefinition(Definition $definition) - { - $this->definitions[$definition->getName()] = $definition; - } - - /** - * {@inheritdoc} - */ - public function getDefinition($name) - { - // Look for the definition by name - if (array_key_exists($name, $this->definitions)) { - return $this->castDefinition($this->definitions[$name], $name); - } - - // Look if there are wildcards definitions - foreach ($this->definitions as $key => $definition) { - if (strpos($key, self::WILDCARD) === false) { - continue; - } - - // Turn the pattern into a regex - $key = addslashes($key); - $key = '#' . str_replace(self::WILDCARD, self::WILDCARD_PATTERN, $key) . '#'; - if (preg_match($key, $name, $matches) === 1) { - $definition = $this->castDefinition($definition, $name); - - // For a class definition, we replace * in the class name with the matches - // *Interface -> *Impl => FooInterface -> FooImpl - if ($definition instanceof ObjectDefinition) { - array_shift($matches); - $definition->setClassName( - $this->replaceWildcards($definition->getClassName(), $matches) - ); - } - - return $definition; - } - } - - return null; - } - - /** - * @param mixed $definition - * @param string $name - * @return Definition - */ - private function castDefinition($definition, $name) - { - if ($definition instanceof DefinitionHelper) { - $definition = $definition->getDefinition($name); - } - if (! $definition instanceof Definition && is_array($definition)) { - $definition = new ArrayDefinition($name, $definition); - } - if ($definition instanceof \Closure) { - $definition = new FactoryDefinition($name, $definition); - } - if (! $definition instanceof Definition) { - $definition = new ValueDefinition($name, $definition); - } - - return $definition; - } - - /** - * Replaces all the wildcards in the string with the given replacements. - * @param string $string - * @param string[] $replacements - * @return string - */ - private function replaceWildcards($string, array $replacements) - { - foreach ($replacements as $replacement) { - $pos = strpos($string, self::WILDCARD); - if ($pos !== false) { - $string = substr_replace($string, $replacement, $pos, 1); - } - } - - return $string; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionFile.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionFile.php deleted file mode 100644 index a79ccf8a24..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionFile.php +++ /dev/null @@ -1,74 +0,0 @@ - - */ -class DefinitionFile extends DefinitionArray -{ - /** - * @var bool - */ - private $initialized = false; - - /** - * File containing definitions, or null if the definitions are given as a PHP array. - * @var string|null - */ - private $file; - - /** - * @param string $file File in which the definitions are returned as an array. - */ - public function __construct($file) - { - // Lazy-loading to improve performances - $this->file = $file; - - parent::__construct([]); - } - - /** - * {@inheritdoc} - */ - public function getDefinition($name) - { - $this->initialize(); - - return parent::getDefinition($name); - } - - /** - * Lazy-loading of the definitions. - * @throws DefinitionException - */ - private function initialize() - { - if ($this->initialized === true) { - return; - } - - $definitions = require $this->file; - - if (! is_array($definitions)) { - throw new DefinitionException("File {$this->file} should return an array of definitions"); - } - - $this->addDefinitions($definitions); - - $this->initialized = true; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionSource.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionSource.php deleted file mode 100644 index 7aa5836c41..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/DefinitionSource.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ -interface DefinitionSource -{ - /** - * Returns the DI definition for the entry name. - * - * @param string $name - * - * @throws DefinitionException An invalid definition was found. - * @return Definition|null - */ - public function getDefinition($name); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/MutableDefinitionSource.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/MutableDefinitionSource.php deleted file mode 100644 index 287cc32304..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/MutableDefinitionSource.php +++ /dev/null @@ -1,15 +0,0 @@ - - */ -interface MutableDefinitionSource extends DefinitionSource -{ - public function addDefinition(Definition $definition); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/SourceChain.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/SourceChain.php deleted file mode 100644 index 962d6f4e65..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/Source/SourceChain.php +++ /dev/null @@ -1,108 +0,0 @@ - - */ -class SourceChain implements DefinitionSource, MutableDefinitionSource -{ - /** - * @var DefinitionSource[] - */ - private $sources; - - /** - * @var DefinitionSource - */ - private $rootSource; - - /** - * @var MutableDefinitionSource|null - */ - private $mutableSource; - - /** - * @param DefinitionSource[] $sources - */ - public function __construct(array $sources) - { - // We want a numerically indexed array to ease the traversal later - $this->sources = array_values($sources); - $this->rootSource = $this; - } - - /** - * {@inheritdoc} - * @param int $startIndex Use this parameter to start looking from a specific - * point in the source chain. - */ - public function getDefinition($name, $startIndex = 0) - { - $count = count($this->sources); - for ($i = $startIndex; $i < $count; $i++) { - $source = $this->sources[$i]; - - $definition = $source->getDefinition($name); - - if ($definition) { - if ($definition instanceof HasSubDefinition) { - $this->resolveSubDefinition($definition, $i); - } - return $definition; - } - } - - return null; - } - - public function addDefinition(Definition $definition) - { - if (! $this->mutableSource) { - throw new \LogicException("The container's definition source has not been initialized correctly"); - } - - $this->mutableSource->addDefinition($definition); - } - - public function setRootDefinitionSource(DefinitionSource $rootSource) - { - $this->rootSource = $rootSource; - } - - private function resolveSubDefinition(HasSubDefinition $definition, $currentIndex) - { - $subDefinitionName = $definition->getSubDefinitionName(); - - if ($subDefinitionName === $definition->getName()) { - // Extending itself: look in the next sources only (else infinite recursion) - $subDefinition = $this->getDefinition($subDefinitionName, $currentIndex + 1); - } else { - // Extending another definition: look from the root - $subDefinition = $this->rootSource->getDefinition($subDefinitionName); - } - - if ($subDefinition) { - $definition->setSubDefinition($subDefinition); - } - } - - public function setMutableDefinitionSource(MutableDefinitionSource $mutableSource) - { - $this->mutableSource = $mutableSource; - - array_unshift($this->sources, $mutableSource); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/StringDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/StringDefinition.php deleted file mode 100644 index 27d2811fbd..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/StringDefinition.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ -class StringDefinition implements Definition -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * @var string - */ - private $expression; - - /** - * @param string $name Entry name - * @param string $expression - */ - public function __construct($name, $expression) - { - $this->name = $name; - $this->expression = $expression; - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getScope() - { - return Scope::SINGLETON; - } - - /** - * @return string - */ - public function getExpression() - { - return $this->expression; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ValueDefinition.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ValueDefinition.php deleted file mode 100644 index b0123f916e..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Definition/ValueDefinition.php +++ /dev/null @@ -1,67 +0,0 @@ - - */ -class ValueDefinition implements Definition -{ - /** - * Entry name - * @var string - */ - private $name; - - /** - * @var mixed - */ - private $value; - - /** - * @param string $name Entry name - * @param mixed $value - */ - public function __construct($name, $value) - { - $this->name = $name; - $this->value = $value; - } - - /** - * @return string Entry name - */ - public function getName() - { - return $this->name; - } - - /** - * A value definition is like a constant, there is nothing to compute, the value is the same for everyone. - * - * {@inheritdoc} - */ - public function getScope() - { - return Scope::SINGLETON; - } - - /** - * @return mixed - */ - public function getValue() - { - return $this->value; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/DependencyException.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/DependencyException.php deleted file mode 100644 index f410f38a09..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/DependencyException.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -interface FactoryInterface -{ - /** - * Resolves an entry by its name. If given a class name, it will return a new instance of that class. - * - * @param string $name Entry name or a class name. - * @param array $parameters Optional parameters to use to build the entry. Use this to force specific - * parameters to specific values. Parameters not defined in this array will - * be automatically resolved. - * - * @throws \InvalidArgumentException The name parameter must be of type string. - * @throws DependencyException Error while resolving the entry. - * @throws NotFoundException No entry or class found for the given name. - * @return mixed - */ - public function make($name, array $parameters = []); -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Invoker/DefinitionParameterResolver.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Invoker/DefinitionParameterResolver.php deleted file mode 100644 index f9718f2164..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Invoker/DefinitionParameterResolver.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ -class DefinitionParameterResolver implements ParameterResolver -{ - /** - * @var DefinitionResolver - */ - private $definitionResolver; - - public function __construct(DefinitionResolver $definitionResolver) - { - $this->definitionResolver = $definitionResolver; - } - - /** - * {@inheritdoc} - */ - public function getParameters( - ReflectionFunctionAbstract $reflection, - array $providedParameters, - array $resolvedParameters - ) { - // Skip parameters already resolved - if (! empty($resolvedParameters)) { - $providedParameters = array_diff_key($providedParameters, $resolvedParameters); - } - - foreach ($providedParameters as $key => $value) { - if (! $value instanceof DefinitionHelper) { - continue; - } - - $definition = $value->getDefinition(''); - $value = $this->definitionResolver->resolve($definition); - - if (is_int($key)) { - // Indexed by position - $resolvedParameters[$key] = $value; - } else { - // Indexed by parameter name - // TODO optimize? - $reflectionParameters = $reflection->getParameters(); - foreach ($reflectionParameters as $reflectionParameter) { - if ($key === $reflectionParameter->name) { - $resolvedParameters[$reflectionParameter->getPosition()] = $value; - } - } - } - } - - return $resolvedParameters; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/InvokerInterface.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/InvokerInterface.php deleted file mode 100644 index 65d0746b82..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/InvokerInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -interface InvokerInterface extends \Invoker\InvokerInterface -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/NotFoundException.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/NotFoundException.php deleted file mode 100644 index 0119578cd6..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/NotFoundException.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -class ProxyFactory -{ - /** - * If true, write the proxies to disk to improve performances. - * @var boolean - */ - private $writeProxiesToFile; - - /** - * Directory where to write the proxies (if $writeProxiesToFile is enabled). - * @var string - */ - private $proxyDirectory; - - /** - * @var LazyLoadingValueHolderFactory|null - */ - private $proxyManager; - - public function __construct($writeProxiesToFile, $proxyDirectory = null) - { - $this->writeProxiesToFile = $writeProxiesToFile; - $this->proxyDirectory = $proxyDirectory; - } - - /** - * Creates a new lazy proxy instance of the given class with - * the given initializer - * - * @param string $className name of the class to be proxied - * @param \Closure $initializer initializer to be passed to the proxy - * - * @return \ProxyManager\Proxy\LazyLoadingInterface - */ - public function createProxy($className, \Closure $initializer) - { - $this->createProxyManager(); - - return $this->proxyManager->createProxy($className, $initializer); - } - - private function createProxyManager() - { - if ($this->proxyManager !== null) { - return; - } - - if (! class_exists('ProxyManager\Configuration')) { - throw new \RuntimeException('The ocramius/proxy-manager library is not installed. Lazy injection requires that library to be installed with Composer in order to work. Run "composer require ocramius/proxy-manager:~0.3".'); - } - - $config = new Configuration(); - - if ($this->writeProxiesToFile) { - $config->setProxiesTargetDir($this->proxyDirectory); - spl_autoload_register($config->getProxyAutoloader()); - } else { - $config->setGeneratorStrategy(new EvaluatingGeneratorStrategy()); - } - - $this->proxyManager = new LazyLoadingValueHolderFactory($config); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Reflection/CallableReflectionFactory.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Reflection/CallableReflectionFactory.php deleted file mode 100644 index f6062d3121..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Reflection/CallableReflectionFactory.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -class CallableReflectionFactory -{ - /** - * @param callable $callable - * - * @return \ReflectionFunctionAbstract - */ - public static function fromCallable($callable) - { - // Array callable - if (is_array($callable)) { - list($class, $method) = $callable; - - return new \ReflectionMethod($class, $method); - } - - // Closure - if ($callable instanceof \Closure) { - return new \ReflectionFunction($callable); - } - - // Callable object (i.e. implementing __invoke()) - if (is_object($callable) && method_exists($callable, '__invoke')) { - return new \ReflectionMethod($callable, '__invoke'); - } - - // Callable class (i.e. implementing __invoke()) - if (is_string($callable) && class_exists($callable) && method_exists($callable, '__invoke')) { - return new \ReflectionMethod($callable, '__invoke'); - } - - // Standard function - return new \ReflectionFunction($callable); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Scope.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Scope.php deleted file mode 100644 index cddd7d5c54..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/Scope.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -class Scope -{ - /** - * A singleton entry will be computed once and shared. - * - * For a class, only a single instance of the class will be created. - */ - const SINGLETON = 'singleton'; - - /** - * A prototype entry will be recomputed each time it is asked. - * - * For a class, this will create a new instance each time. - */ - const PROTOTYPE = 'prototype'; - - /** - * Method kept for backward compatibility, use the constant instead. - * - * @return string - */ - public static function SINGLETON() - { - return self::SINGLETON; - } - - /** - * Method kept for backward compatibility, use the constant instead. - * - * @return string - */ - public static function PROTOTYPE() - { - return self::PROTOTYPE; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/functions.php b/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/functions.php deleted file mode 100644 index 313c71f441..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/php-di/src/DI/functions.php +++ /dev/null @@ -1,181 +0,0 @@ - decorate(function ($foo, $container) { - * return new CachedFoo($foo, $container->get('cache')); - * }) - * - * @param callable $callable The callable takes the decorated object as first parameter and - * the container as second. - * - * @return FactoryDefinitionHelper - */ - function decorate($callable) - { - return new FactoryDefinitionHelper($callable, true); - } -} - -if (! function_exists('DI\get')) { - /** - * Helper for referencing another container entry in an object definition. - * - * @param string $entryName - * - * @return EntryReference - */ - function get($entryName) - { - return new EntryReference($entryName); - } -} - -if (! function_exists('DI\link')) { - /** - * Helper for referencing another container entry in an object definition. - * - * @deprecated \DI\link() has been replaced by \DI\get() - * - * @param string $entryName - * - * @return EntryReference - */ - function link($entryName) - { - return new EntryReference($entryName); - } -} - -if (! function_exists('DI\env')) { - /** - * Helper for referencing environment variables. - * - * @param string $variableName The name of the environment variable. - * @param mixed $defaultValue The default value to be used if the environment variable is not defined. - * - * @return EnvironmentVariableDefinitionHelper - */ - function env($variableName, $defaultValue = null) - { - // Only mark as optional if the default value was *explicitly* provided. - $isOptional = 2 === func_num_args(); - - return new EnvironmentVariableDefinitionHelper($variableName, $isOptional, $defaultValue); - } -} - -if (! function_exists('DI\add')) { - /** - * Helper for extending another definition. - * - * Example: - * - * 'log.backends' => DI\add(DI\get('My\Custom\LogBackend')) - * - * or: - * - * 'log.backends' => DI\add([ - * DI\get('My\Custom\LogBackend') - * ]) - * - * @param mixed|array $values A value or an array of values to add to the array. - * - * @return ArrayDefinitionExtensionHelper - * - * @since 5.0 - */ - function add($values) - { - if (! is_array($values)) { - $values = [$values]; - } - - return new ArrayDefinitionExtensionHelper($values); - } -} - -if (! function_exists('DI\string')) { - /** - * Helper for concatenating strings. - * - * Example: - * - * 'log.filename' => DI\string('{app.path}/app.log') - * - * @param string $expression A string expression. Use the `{}` placeholders to reference other container entries. - * - * @return StringDefinitionHelper - * - * @since 5.0 - */ - function string($expression) - { - return new StringDefinitionHelper((string) $expression); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitattributes b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitattributes deleted file mode 100644 index 912292cf40..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitattributes +++ /dev/null @@ -1,7 +0,0 @@ -# .gitattributes -tests/ export-ignore -phpunit.xml.dist export-ignore -.travis.yml export-ignore - -# Auto detect text files and perform LF normalization -* text=auto diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitignore b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitignore deleted file mode 100644 index f7be360d40..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -.idea/* -vendor/* -composer.phar -composer.lock diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/LICENSE b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/LICENSE deleted file mode 100644 index f859a317a2..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (C) 2015 Matthieu Napoli - -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/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/README.md b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/README.md deleted file mode 100644 index 9a59545479..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# PhpDocReader - -[![Build Status](https://img.shields.io/travis/PHP-DI/PhpDocReader.svg)](https://travis-ci.org/mnapoli/PhpDocReader) -[![Coverage Status](https://img.shields.io/coveralls/PHP-DI/PhpDocReader.svg)](https://coveralls.io/r/mnapoli/PhpDocReader) -![](https://img.shields.io/packagist/dt/PHP-DI/phpdoc-reader.svg) - -This project is used by: - -- [PHP-DI](http://php-di.org/) -- [phockito-unit-php-di](https://github.com/balihoo/phockito-unit-php-di) - -Fork the README to add your project here. - -## Features - -PhpDocReader parses `@var` and `@param` values in PHP docblocks: - -```php - -use My\Cache\Backend; - -class Cache -{ - /** - * @var Backend - */ - protected $backend; - - /** - * @param Backend $backend - */ - public function __construct($backend) - { - } -} -``` - -It supports namespaced class names with the same resolution rules as PHP: - -- fully qualified name (starting with `\`) -- imported class name (eg. `use My\Cache\Backend;`) -- relative class name (from the current namespace, like `SubNamespace\MyClass`) -- aliased class name (eg. `use My\Cache\Backend as FooBar;`) - -Primitive types (`@var string`) are ignored (returns null), only valid class names are returned. - -## Usage - -```php -$reader = new PhpDocReader(); - -// Read a property type (@var phpdoc) -$property = new ReflectionProperty($className, $propertyName); -$propertyClass = $reader->getPropertyClass($property); - -// Read a parameter type (@param phpdoc) -$parameter = new ReflectionParameter(array($className, $methodName), $parameterName); -$parameterClass = $reader->getParameterClass($parameter); -``` diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/composer.json b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/composer.json deleted file mode 100644 index 11da6a52e9..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/composer.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "php-di/phpdoc-reader", - "type": "library", - "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", - "keywords": ["phpdoc", "reflection"], - "license": "MIT", - "autoload": { - "psr-4": { - "PhpDocReader\\": "src/PhpDocReader" - } - }, - "autoload-dev": { - "psr-4": { - "UnitTest\\PhpDocReader\\": "tests/" - } - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.6" - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/AnnotationException.php b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/AnnotationException.php deleted file mode 100644 index 577d73f28c..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/AnnotationException.php +++ /dev/null @@ -1,10 +0,0 @@ - - */ -class AnnotationException extends \Exception -{ -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpDocReader.php b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpDocReader.php deleted file mode 100644 index 6251371b6f..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpDocReader.php +++ /dev/null @@ -1,270 +0,0 @@ - - */ -class PhpDocReader -{ - /** - * @var UseStatementParser - */ - private $parser; - - private $ignoredTypes = array( - 'bool', - 'boolean', - 'string', - 'int', - 'integer', - 'float', - 'double', - 'array', - 'object', - 'callable', - 'resource', - ); - - /** - * Enable or disable throwing errors when PhpDoc Errors occur (when parsing annotations) - * - * @var bool - */ - private $ignorePhpDocErrors; - - /** - * - * @param bool $ignorePhpDocErrors - */ - public function __construct($ignorePhpDocErrors = false) - { - $this->parser = new UseStatementParser(); - $this->ignorePhpDocErrors = $ignorePhpDocErrors; - } - - /** - * Parse the docblock of the property to get the class of the var annotation. - * - * @param ReflectionProperty $property - * - * @throws AnnotationException - * @return string|null Type of the property (content of var annotation) - * - * @deprecated Use getPropertyClass instead. - */ - public function getPropertyType(ReflectionProperty $property) - { - return $this->getPropertyClass($property); - } - - /** - * Parse the docblock of the property to get the class of the var annotation. - * - * @param ReflectionProperty $property - * - * @throws AnnotationException - * @return string|null Type of the property (content of var annotation) - */ - public function getPropertyClass(ReflectionProperty $property) - { - // Get the content of the @var annotation - if (preg_match('/@var\s+([^\s]+)/', $property->getDocComment(), $matches)) { - list(, $type) = $matches; - } else { - return null; - } - - // Ignore primitive types - if (in_array($type, $this->ignoredTypes)) { - return null; - } - - // Ignore types containing special characters ([], <> ...) - if (! preg_match('/^[a-zA-Z0-9\\\\_]+$/', $type)) { - return null; - } - - $class = $property->getDeclaringClass(); - - // If the class name is not fully qualified (i.e. doesn't start with a \) - if ($type[0] !== '\\') { - $alias = (false === $pos = strpos($type, '\\')) ? $type : substr($type, 0, $pos); - $loweredAlias = strtolower($alias); - - // Retrieve "use" statements - $uses = $this->parser->parseUseStatements($property->getDeclaringClass()); - - $found = false; - - if (isset($uses[$loweredAlias])) { - // Imported classes - if (false !== $pos) { - $type = $uses[$loweredAlias] . substr($type, $pos); - } else { - $type = $uses[$loweredAlias]; - } - $found = true; - } elseif ($this->classExists($class->getNamespaceName() . '\\' . $type)) { - $type = $class->getNamespaceName() . '\\' . $type; - $found = true; - } elseif (isset($uses['__NAMESPACE__']) && $this->classExists($uses['__NAMESPACE__'] . '\\' . $type)) { - // Class namespace - $type = $uses['__NAMESPACE__'] . '\\' . $type; - $found = true; - } elseif ($this->classExists($type)) { - // No namespace - $found = true; - } - - if (!$found && !$this->ignorePhpDocErrors) { - throw new AnnotationException(sprintf( - 'The @var annotation on %s::%s contains a non existent class "%s". ' - . 'Did you maybe forget to add a "use" statement for this annotation?', - $class->name, - $property->getName(), - $type - )); - } - } - - if (!$this->classExists($type) && !$this->ignorePhpDocErrors) { - throw new AnnotationException(sprintf( - 'The @var annotation on %s::%s contains a non existent class "%s"', - $class->name, - $property->getName(), - $type - )); - } - - // Remove the leading \ (FQN shouldn't contain it) - $type = ltrim($type, '\\'); - - return $type; - } - - /** - * Parse the docblock of the property to get the class of the param annotation. - * - * @param ReflectionParameter $parameter - * - * @throws AnnotationException - * @return string|null Type of the property (content of var annotation) - * - * @deprecated Use getParameterClass instead. - */ - public function getParameterType(ReflectionParameter $parameter) - { - return $this->getParameterClass($parameter); - } - - /** - * Parse the docblock of the property to get the class of the param annotation. - * - * @param ReflectionParameter $parameter - * - * @throws AnnotationException - * @return string|null Type of the property (content of var annotation) - */ - public function getParameterClass(ReflectionParameter $parameter) - { - // Use reflection - $parameterClass = $parameter->getClass(); - if ($parameterClass !== null) { - return $parameterClass->name; - } - - $parameterName = $parameter->name; - // Get the content of the @param annotation - $method = $parameter->getDeclaringFunction(); - if (preg_match('/@param\s+([^\s]+)\s+\$' . $parameterName . '/', $method->getDocComment(), $matches)) { - list(, $type) = $matches; - } else { - return null; - } - - // Ignore primitive types - if (in_array($type, $this->ignoredTypes)) { - return null; - } - - // Ignore types containing special characters ([], <> ...) - if (! preg_match('/^[a-zA-Z0-9\\\\_]+$/', $type)) { - return null; - } - - $class = $parameter->getDeclaringClass(); - - // If the class name is not fully qualified (i.e. doesn't start with a \) - if ($type[0] !== '\\') { - $alias = (false === $pos = strpos($type, '\\')) ? $type : substr($type, 0, $pos); - $loweredAlias = strtolower($alias); - - // Retrieve "use" statements - $uses = $this->parser->parseUseStatements($class); - - $found = false; - - if (isset($uses[$loweredAlias])) { - // Imported classes - if (false !== $pos) { - $type = $uses[$loweredAlias] . substr($type, $pos); - } else { - $type = $uses[$loweredAlias]; - } - $found = true; - } elseif ($this->classExists($class->getNamespaceName() . '\\' . $type)) { - $type = $class->getNamespaceName() . '\\' . $type; - $found = true; - } elseif (isset($uses['__NAMESPACE__']) && $this->classExists($uses['__NAMESPACE__'] . '\\' . $type)) { - // Class namespace - $type = $uses['__NAMESPACE__'] . '\\' . $type; - $found = true; - } elseif ($this->classExists($type)) { - // No namespace - $found = true; - } - - if (!$found && !$this->ignorePhpDocErrors) { - throw new AnnotationException(sprintf( - 'The @param annotation for parameter "%s" of %s::%s contains a non existent class "%s". ' - . 'Did you maybe forget to add a "use" statement for this annotation?', - $parameterName, - $class->name, - $method->name, - $type - )); - } - } - - if (!$this->classExists($type) && !$this->ignorePhpDocErrors) { - throw new AnnotationException(sprintf( - 'The @param annotation for parameter "%s" of %s::%s contains a non existent class "%s"', - $parameterName, - $class->name, - $method->name, - $type - )); - } - - // Remove the leading \ (FQN shouldn't contain it) - $type = ltrim($type, '\\'); - - return $type; - } - - /** - * @param string $class - * @return bool - */ - private function classExists($class) - { - return class_exists($class) || interface_exists($class); - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/TokenParser.php b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/TokenParser.php deleted file mode 100644 index d3965d753a..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/TokenParser.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @author Christian Kaps - */ -class TokenParser -{ - /** - * The token list. - * - * @var array - */ - private $tokens; - - /** - * The number of tokens. - * - * @var int - */ - private $numTokens; - - /** - * The current array pointer. - * - * @var int - */ - private $pointer = 0; - - /** - * @param string $contents - */ - public function __construct($contents) - { - $this->tokens = token_get_all($contents); - - // The PHP parser sets internal compiler globals for certain things. Annoyingly, the last docblock comment it - // saw gets stored in doc_comment. When it comes to compile the next thing to be include()d this stored - // doc_comment becomes owned by the first thing the compiler sees in the file that it considers might have a - // docblock. If the first thing in the file is a class without a doc block this would cause calls to - // getDocBlock() on said class to return our long lost doc_comment. Argh. - // To workaround, cause the parser to parse an empty docblock. Sure getDocBlock() will return this, but at least - // it's harmless to us. - token_get_all("numTokens = count($this->tokens); - } - - /** - * Gets all use statements. - * - * @param string $namespaceName The namespace name of the reflected class. - * - * @return array A list with all found use statements. - */ - public function parseUseStatements($namespaceName) - { - $statements = array(); - while (($token = $this->next())) { - if ($token[0] === T_USE) { - $statements = array_merge($statements, $this->parseUseStatement()); - continue; - } - 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; - } - - /** - * Gets the next non whitespace and non comment token. - * - * @param boolean $docCommentIsComment If TRUE then a doc comment is considered a comment and skipped. - * If FALSE then only whitespace and normal comments are skipped. - * - * @return array|null The token if exists, null otherwise. - */ - private function next($docCommentIsComment = true) - { - for ($i = $this->pointer; $i < $this->numTokens; $i++) { - $this->pointer++; - if ($this->tokens[$i][0] === T_WHITESPACE || - $this->tokens[$i][0] === T_COMMENT || - ($docCommentIsComment && $this->tokens[$i][0] === T_DOC_COMMENT)) { - - continue; - } - - return $this->tokens[$i]; - } - - return null; - } - - /** - * Parses 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]; - } elseif ($explicitAlias && $isNameToken) { - $alias .= $token[1]; - } elseif ($token[0] === T_AS) { - $explicitAlias = true; - $alias = ''; - } elseif ($token === ',') { - $statements[strtolower($alias)] = $class; - $class = ''; - $alias = ''; - $explicitAlias = false; - } elseif ($token === ';') { - $statements[strtolower($alias)] = $class; - break; - } else { - break; - } - } - - return $statements; - } - - /** - * Gets the namespace. - * - * @return string The found namespace. - */ - private function parseNamespace() - { - $name = ''; - while (($token = $this->next()) && ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR)) { - $name .= $token[1]; - } - - return $name; - } -} diff --git a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/UseStatementParser.php b/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/UseStatementParser.php deleted file mode 100644 index 1b0d63d20c..0000000000 --- a/wcfsetup/install/files/lib/system/api/php-di/phpdoc-reader/src/PhpDocReader/PhpParser/UseStatementParser.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @author Christian Kaps - */ -class UseStatementParser -{ - /** - * @return array A list with use statements in the form (Alias => FQN). - */ - public function parseUseStatements(\ReflectionClass $class) - { - if (false === $filename = $class->getFilename()) { - return array(); - } - - $content = $this->getFileContent($filename, $class->getStartLine()); - - if (null === $content) { - return array(); - } - - $namespace = preg_quote($class->getNamespaceName()); - $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content); - $tokenizer = new TokenParser('parseUseStatements($class->getNamespaceName()); - - return $statements; - } - - /** - * Gets the content of the file right up to the given line number. - * - * @param string $filename The name of the file to load. - * @param integer $lineNumber The number of lines to read from file. - * - * @return string The content of the file. - */ - private function getFileContent($filename, $lineNumber) - { - if ( ! is_file($filename)) { - return null; - } - - $content = ''; - $lineCnt = 0; - $file = new SplFileObject($filename); - while (!$file->eof()) { - if ($lineCnt++ == $lineNumber) { - break; - } - - $content .= $file->fgets(); - } - - return $content; - } -} diff --git a/wcfsetup/install/files/lib/system/application/ApplicationHandler.class.php b/wcfsetup/install/files/lib/system/application/ApplicationHandler.class.php index a949d56d03..c9d1c85abb 100644 --- a/wcfsetup/install/files/lib/system/application/ApplicationHandler.class.php +++ b/wcfsetup/install/files/lib/system/application/ApplicationHandler.class.php @@ -18,10 +18,6 @@ use wcf\system\SingletonFactory; * @category Community Framework */ class ApplicationHandler extends SingletonFactory { - /** - * @var ApplicationCacheBuilder - */ - protected $applicationCacheBuilder; /** * application cache * @var array @@ -34,22 +30,11 @@ class ApplicationHandler extends SingletonFactory { */ protected $pageURLs = array(); - /** - * ApplicationHandler constructor. - * - * @param ApplicationCacheBuilder $applicationCacheBuilder - */ - public function __construct(ApplicationCacheBuilder $applicationCacheBuilder) { - $this->applicationCacheBuilder = $applicationCacheBuilder; - - parent::__construct(); - } - /** * Initializes cache. */ protected function init() { - $this->cache = $this->applicationCacheBuilder->getData(); + $this->cache = ApplicationCacheBuilder::getInstance()->getData(); } /** diff --git a/wcfsetup/install/files/lib/system/event/EventHandler.class.php b/wcfsetup/install/files/lib/system/event/EventHandler.class.php index 9a218134ab..56e5e15ba4 100644 --- a/wcfsetup/install/files/lib/system/event/EventHandler.class.php +++ b/wcfsetup/install/files/lib/system/event/EventHandler.class.php @@ -1,5 +1,6 @@ eventListenerCacheBuilder = $eventListenerCacheBuilder; - - parent::__construct(); - } - /** * Loads all registered actions of the active package. */ protected function loadActions() { $environment = ((class_exists('wcf\system\WCFACP', false) || class_exists('wcf\system\CLIWCF', false)) ? 'admin' : 'user'); - $cache = $this->eventListenerCacheBuilder->getData(); + $cache = EventListenerCacheBuilder::getInstance()->getData(); if (isset($cache['actions'][$environment])) { $this->actions = $cache['actions'][$environment]; @@ -113,6 +98,7 @@ class EventHandler extends SingletonFactory { if (isset($this->inheritedActions[$member])) { $actions = $this->inheritedActions[$member]; if (isset($actions[$eventName]) && !empty($actions[$eventName])) { + /** @var EventListener $eventListener */ foreach ($actions[$eventName] as $eventListener) { if ($eventListener->validateOptions() && $eventListener->validatePermissions()) { if (isset($this->inheritedActionsObjects[$name][$eventListener->listenerClassName])) continue; @@ -200,6 +186,7 @@ class EventHandler extends SingletonFactory { } $this->actionsObjects[$name] = []; + /** @var EventListener $eventListener */ foreach ($this->actions[$name] as $eventListener) { if ($eventListener->validateOptions() && $eventListener->validatePermissions()) { if (isset($this->actionsObjects[$name][$eventListener->listenerClassName])) continue; diff --git a/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php index c7a96389e4..45d86b9680 100644 --- a/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/input/HtmlInputProcessor.class.php @@ -4,7 +4,6 @@ namespace wcf\system\html\input; use wcf\system\html\input\filter\IHtmlInputFilter; use wcf\system\html\input\filter\MessageHtmlInputFilter; use wcf\system\html\input\node\HtmlInputNodeProcessor; -use wcf\system\WCF; class HtmlInputProcessor { /** @@ -34,11 +33,10 @@ class HtmlInputProcessor { /** * @return IHtmlInputFilter|MessageHtmlInputFilter - * @throws \DI\NotFoundException */ public function getHtmlInputFilter() { if ($this->htmlInputFilter === null) { - $this->htmlInputFilter = WCF::getDIContainer()->make(MessageHtmlInputFilter::class); + $this->htmlInputFilter = new MessageHtmlInputFilter(); } return $this->htmlInputFilter; @@ -50,11 +48,10 @@ class HtmlInputProcessor { /** * @return HtmlInputNodeProcessor - * @throws \DI\NotFoundException */ public function getHtmlInputNodeProcessor() { if ($this->htmlInputNodeProcessor === null) { - $this->htmlInputNodeProcessor = WCF::getDIContainer()->make(HtmlInputNodeProcessor::class); + $this->htmlInputNodeProcessor = new HtmlInputNodeProcessor(); } return $this->htmlInputNodeProcessor; diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php index b2540e3a8a..fa413746c1 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeProcessor.class.php @@ -2,7 +2,6 @@ namespace wcf\system\html\input\node; use wcf\system\html\node\HtmlNodeProcessor; -use wcf\system\WCF; class HtmlInputNodeProcessor extends HtmlNodeProcessor { public function load($html) { @@ -12,7 +11,7 @@ class HtmlInputNodeProcessor extends HtmlNodeProcessor { } public function process() { - $woltlabMention = WCF::getDIContainer()->get(HtmlInputNodeWoltlabMention::class); + $woltlabMention = new HtmlInputNodeWoltlabMention(); $woltlabMention->process($this); } } diff --git a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php index 067491c227..3e5b741142 100644 --- a/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php +++ b/wcfsetup/install/files/lib/system/html/input/node/HtmlInputNodeWoltlabMention.class.php @@ -1,18 +1,7 @@ messageEmbeddedObjectManager = $messageEmbeddedObjectManager; - } - public function process(HtmlInputNodeProcessor $htmlInputNodeProcessor) { $userIds = []; diff --git a/wcfsetup/install/files/lib/system/html/output/HtmlOutputNodeProcessor.class.php b/wcfsetup/install/files/lib/system/html/output/HtmlOutputNodeProcessor.class.php index 97468d3563..09b1eacedd 100644 --- a/wcfsetup/install/files/lib/system/html/output/HtmlOutputNodeProcessor.class.php +++ b/wcfsetup/install/files/lib/system/html/output/HtmlOutputNodeProcessor.class.php @@ -5,7 +5,6 @@ use wcf\system\html\node\HtmlNodeProcessor; use wcf\system\html\output\node\HtmlOutputNodeBlockquote; use wcf\system\html\output\node\HtmlOutputNodeWoltlabMention; use wcf\system\html\output\node\IHtmlOutputNode; -use wcf\system\WCF; class HtmlOutputNodeProcessor extends HtmlNodeProcessor { protected $nodeData = []; @@ -18,10 +17,10 @@ class HtmlOutputNodeProcessor extends HtmlNodeProcessor { public function process() { // TODO: this should be dynamic to some extent - $quoteNode = WCF::getDIContainer()->get(HtmlOutputNodeBlockquote::class); + $quoteNode = new HtmlOutputNodeBlockquote(); $quoteNode->process($this); - $woltlabMentionNode = WCF::getDIContainer()->get(HtmlOutputNodeWoltlabMention::class); + $woltlabMentionNode = new HtmlOutputNodeWoltlabMention(); $woltlabMentionNode->process($this); } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php index eb28108449..ae8639f579 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeBlockquote.class.php @@ -8,15 +8,6 @@ use wcf\system\WCF; use wcf\util\StringUtil; class HtmlOutputNodeBlockquote implements IHtmlOutputNode { - /** - * @var ApplicationHandler - */ - protected $applicationHandler; - - public function __construct(ApplicationHandler $applicationHandler) { - $this->applicationHandler = $applicationHandler; - } - public function process(HtmlOutputNodeProcessor $htmlOutputNodeProcessor) { $elements = $htmlOutputNodeProcessor->getDocument()->getElementsByTagName('blockquote'); while ($elements->length) { @@ -39,7 +30,7 @@ class HtmlOutputNodeBlockquote implements IHtmlOutputNode { } public function replaceTag(array $data) { - $externalQuoteLink = (!empty($data['url'])) ? !$this->applicationHandler->isInternalURL($data['url']) : false; + $externalQuoteLink = (!empty($data['url'])) ? !ApplicationHandler::getInstance()->isInternalURL($data['url']) : false; if (!$externalQuoteLink) { $data['url'] = preg_replace('~^https://~', RouteHandler::getProtocol(), $data['url']); } diff --git a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php index 7f06d42a14..9c5413df57 100644 --- a/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php +++ b/wcfsetup/install/files/lib/system/html/output/node/HtmlOutputNodeWoltlabMention.class.php @@ -5,31 +5,15 @@ use wcf\data\user\UserProfile; use wcf\data\user\UserProfileCache; use wcf\system\application\ApplicationHandler; use wcf\system\html\output\HtmlOutputNodeProcessor; -use wcf\system\request\RouteHandler; use wcf\system\WCF; use wcf\util\StringUtil; class HtmlOutputNodeWoltlabMention implements IHtmlOutputNode { - /** - * @var ApplicationHandler - */ - protected $applicationHandler; - /** * @var UserProfile[] */ protected $userProfiles; - /** - * @var UserProfileCache - */ - protected $userProfileCache; - - public function __construct(ApplicationHandler $applicationHandler, UserProfileCache $userProfileCache) { - $this->applicationHandler = $applicationHandler; - $this->userProfileCache = $userProfileCache; - } - public function process(HtmlOutputNodeProcessor $htmlOutputNodeProcessor) { $this->userProfiles = []; @@ -58,7 +42,7 @@ class HtmlOutputNodeWoltlabMention implements IHtmlOutputNode { } if (!empty($userIds)) { - $this->userProfiles = $this->userProfileCache->getUserProfiles($userIds); + $this->userProfiles = UserProfileCache::getInstance()->getUserProfiles($userIds); } } diff --git a/wcfsetup/install/files/lib/system/request/ControllerMap.class.php b/wcfsetup/install/files/lib/system/request/ControllerMap.class.php index d247e83c99..4184a5b13d 100644 --- a/wcfsetup/install/files/lib/system/request/ControllerMap.class.php +++ b/wcfsetup/install/files/lib/system/request/ControllerMap.class.php @@ -1,6 +1,7 @@ to mappings * @var array */ protected $lookupCache = []; - public function __construct() { + protected function init() { // TODO: initialize custom controller mappings } diff --git a/wcfsetup/install/files/lib/system/request/LinkHandler.class.php b/wcfsetup/install/files/lib/system/request/LinkHandler.class.php index 808bae8938..dc1e07e16e 100644 --- a/wcfsetup/install/files/lib/system/request/LinkHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/LinkHandler.class.php @@ -19,21 +19,6 @@ use wcf\util\StringUtil; * @category Community Framework */ class LinkHandler extends SingletonFactory { - /** - * @var ApplicationHandler - */ - protected $applicationHandler; - - /** - * @var RequestHandler - */ - protected $requestHandler; - - /** - * @var RouteHandler - */ - protected $routeHandler; - /** * regex object to filter title * @var \wcf\system\RegEx @@ -52,20 +37,6 @@ class LinkHandler extends SingletonFactory { */ protected $titleReplace = array(); - /** - * LinkHandler constructor. - * - * @param ApplicationHandler $applicationHandler - * @param RequestHandler $requestHandler - * @param RouteHandler $routeHandler - */ - public function __construct(ApplicationHandler $applicationHandler, RequestHandler $requestHandler, RouteHandler $routeHandler) { - $this->applicationHandler = $applicationHandler; - $this->requestHandler = $requestHandler; - $this->routeHandler = $routeHandler; - - parent::__construct(); - } /** * @see \wcf\system\SingletonFactory::init() @@ -95,7 +66,7 @@ class LinkHandler extends SingletonFactory { public function getLink($controller = null, array $parameters = array(), $url = '') { $abbreviation = 'wcf'; $anchor = ''; - $isACP = $originIsACP = $this->requestHandler->isACPRequest(); + $isACP = $originIsACP = RequestHandler::getInstance()->isACPRequest(); $forceWCF = $isRaw = false; $appendSession = $encodeTitle = true; @@ -157,8 +128,7 @@ class LinkHandler extends SingletonFactory { $controller = 'Index'; } else { - // loading the PageMenu object as a dependency in ACP requests breaks everything - return WCF::getDIContainer()->get(PageMenu::class)->getLandingPage()->getProcessor()->getLink(); + return PageMenu::getInstance()->getLandingPage()->getProcessor()->getLink(); } } @@ -193,7 +163,7 @@ class LinkHandler extends SingletonFactory { } $parameters['controller'] = $controller; - $routeURL = $this->routeHandler->buildRoute($parameters, $isACP); + $routeURL = RouteHandler::getInstance()->buildRoute($parameters, $isACP); if (!$isRaw && !empty($url)) { $routeURL .= (strpos($routeURL, '?') === false) ? '?' : '&'; } @@ -215,22 +185,22 @@ class LinkHandler extends SingletonFactory { $url = RouteHandler::getHost() . RouteHandler::getPath(array('acp')) . ($isACP ? 'acp/' : '') . $url; } else { - if ($this->requestHandler->inRescueMode()) { + if (RequestHandler::getInstance()->inRescueMode()) { $pageURL = RouteHandler::getHost() . str_replace('//', '/', RouteHandler::getPath(array('acp'))); } else { // try to resolve abbreviation $application = null; if ($abbreviation != 'wcf') { - $application = $this->applicationHandler->getApplication($abbreviation); + $application = ApplicationHandler::getInstance()->getApplication($abbreviation); } // fallback to primary application if abbreviation is 'wcf' or unknown if ($forceWCF) { - $application = $this->applicationHandler->getWCF(); + $application = ApplicationHandler::getInstance()->getWCF(); } else if ($application === null) { - $application = $this->applicationHandler->getPrimaryApplication(); + $application = ApplicationHandler::getInstance()->getPrimaryApplication(); } $pageURL = $application->getPageURL(); diff --git a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php index 103b1c9b81..03d7176a93 100644 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@ -27,16 +27,6 @@ class RequestHandler extends SingletonFactory { */ protected $activeRequest = null; - /** - * @var ApplicationHandler - */ - protected $applicationHandler; - - /** - * @var ControllerMap - */ - protected $controllerMap; - /** * true, if current domain mismatch any known domain * @var boolean @@ -49,32 +39,12 @@ class RequestHandler extends SingletonFactory { */ protected $isACPRequest = false; - /** - * @var RouteHandler - */ - protected $routeHandler; - - /** - * RequestHandler constructor. - * - * @param ApplicationHandler $applicationHandler - * @param ControllerMap $controllerMap - * @param RouteHandler $routeHandler - */ - public function __construct(ApplicationHandler $applicationHandler, ControllerMap $controllerMap, RouteHandler $routeHandler) { - $this->applicationHandler = $applicationHandler; - $this->controllerMap = $controllerMap; - $this->routeHandler = $routeHandler; - - parent::__construct(); - } - /** * @see \wcf\system\SingletonFactory::init() */ protected function init() { if (isset($_SERVER['HTTP_HOST'])) { - foreach ($this->applicationHandler->getApplications() as $application) { + foreach (ApplicationHandler::getInstance()->getApplications() as $application) { if ($application->domainName == $_SERVER['HTTP_HOST']) { $this->inRescueMode = false; break; @@ -83,7 +53,7 @@ class RequestHandler extends SingletonFactory { // check if WCF is running as standalone if ($this->inRescueMode() && PACKAGE_ID == 1) { - if ($this->applicationHandler->getWCF()->domainName == $_SERVER['HTTP_HOST']) { + if (ApplicationHandler::getInstance()->getWCF()->domainName == $_SERVER['HTTP_HOST']) { $this->inRescueMode = false; } } @@ -110,11 +80,7 @@ class RequestHandler extends SingletonFactory { public function handle($application = 'wcf', $isACPRequest = false) { $this->isACPRequest = $isACPRequest; - // initialize route handler - $this->routeHandler->setRequestHandler($this); - $this->routeHandler->setDefaultRoutes(); - - if (!$this->routeHandler->matches($application)) { + if (!RouteHandler::getInstance()->matches($application)) { if (ENABLE_DEBUG_MODE) { throw new SystemException("Cannot handle request, no valid route provided."); } @@ -157,7 +123,7 @@ class RequestHandler extends SingletonFactory { */ protected function buildRequest($application) { try { - $routeData = $this->routeHandler->getRouteData(); + $routeData = RouteHandler::getInstance()->getRouteData(); // handle landing page for frontend requests if (!$this->isACPRequest()) { @@ -165,7 +131,7 @@ class RequestHandler extends SingletonFactory { // check if accessing from the wrong domain (e.g. "www." omitted but domain was configured with) if (!defined('WCF_RUN_MODE') || WCF_RUN_MODE != 'embedded') { - $applicationObject = $this->applicationHandler->getApplication($application); + $applicationObject = ApplicationHandler::getInstance()->getApplication($application); if ($applicationObject->domainName != $_SERVER['HTTP_HOST']) { // build URL, e.g. http://example.net/forum/ $url = FileUtil::addTrailingSlash(RouteHandler::getProtocol() . $applicationObject->domainName . RouteHandler::getPath()); @@ -211,7 +177,7 @@ class RequestHandler extends SingletonFactory { $controller = $routeData['controller']; - $classData = $this->controllerMap->resolve($application, $controller, $this->isACPRequest()); + $classData = ControllerMap::getInstance()->resolve($application, $controller, $this->isACPRequest()); // check if controller was provided exactly as it should /* @@ -263,12 +229,11 @@ class RequestHandler extends SingletonFactory { * @param array $routeData */ protected function handleDefaultController($application, array &$routeData) { - if (!$this->routeHandler->isDefaultController()) { + if (!RouteHandler::getInstance()->isDefaultController()) { return; } - // loading the PageMenu object as a dependency in ACP requests breaks everything - $landingPage = WCF::getDIContainer()->get(PageMenu::class)->getLandingPage(); + $landingPage = PageMenu::getInstance()->getLandingPage(); if ($landingPage === null) { return; } @@ -277,8 +242,8 @@ class RequestHandler extends SingletonFactory { // resolve implicit application abbreviation for landing page controller $landingPageApplication = $landingPage->getApplication(); - $primaryApplication = $this->applicationHandler->getPrimaryApplication(); - $primaryApplicationAbbr = $this->applicationHandler->getAbbreviation($primaryApplication->packageID); + $primaryApplication = ApplicationHandler::getInstance()->getPrimaryApplication(); + $primaryApplicationAbbr = ApplicationHandler::getInstance()->getAbbreviation($primaryApplication->packageID); if ($landingPageApplication == 'wcf') { $landingPageApplication = $primaryApplicationAbbr; } @@ -286,7 +251,7 @@ class RequestHandler extends SingletonFactory { // check if currently invoked application matches the landing page if ($landingPageApplication == $application) { $routeData['controller'] = $landingPage->getController(); - $routeData['controller'] = $this->controllerMap->lookup($routeData['controller']); + $routeData['controller'] = ControllerMap::getInstance()->lookup($routeData['controller']); return; } @@ -298,9 +263,9 @@ class RequestHandler extends SingletonFactory { } // set default controller - $applicationObj = WCF::getApplicationObject($this->applicationHandler->getApplication($application)); + $applicationObj = WCF::getApplicationObject(ApplicationHandler::getInstance()->getApplication($application)); $routeData['controller'] = preg_replace('~^.*?\\\([^\\\]+)(?:Action|Form|Page)$~', '\\1', $applicationObj->getPrimaryController()); - $routeData['controller'] = $this->controllerMap->lookup($routeData['controller']); + $routeData['controller'] = ControllerMap::getInstance()->lookup($routeData['controller']); } /** diff --git a/wcfsetup/install/files/lib/system/request/RouteHandler.class.php b/wcfsetup/install/files/lib/system/request/RouteHandler.class.php index 107106b6d6..c6bec80ec9 100644 --- a/wcfsetup/install/files/lib/system/request/RouteHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RouteHandler.class.php @@ -53,33 +53,18 @@ class RouteHandler extends SingletonFactory { */ protected static $secure = null; - /** - * @var ApplicationHandler - */ - protected $applicationHandler; - /** * list of application abbreviation and default controller name * @var array */ protected $defaultControllers = null; - /** - * @var EventHandler - */ - protected $eventHandler; - /** * true, if default controller is used (support for custom landing page) * @var boolean */ protected $isDefaultController = false; - /** - * @var RequestHandler - */ - protected $requestHandler; - /** * list of available routes * @var IRoute[] @@ -92,42 +77,20 @@ class RouteHandler extends SingletonFactory { */ protected $routeData = null; - /** - * RouteHandler constructor. - * - * @param ApplicationHandler $applicationHandler - * @param EventHandler $eventHandler - */ - public function __construct(ApplicationHandler $applicationHandler, EventHandler $eventHandler) { - $this->applicationHandler = $applicationHandler; - $this->eventHandler = $eventHandler; - - parent::__construct(); - } - /** * Sets default routes. */ - public function setDefaultRoutes() { - $route = WCF::getDIContainer()->make(DynamicRequestRoute::class); + protected function init() { + $route = new DynamicRequestRoute(); $route->setIsACP(true); $this->addRoute($route); - $route = WCF::getDIContainer()->make(DynamicRequestRoute::class); + $route = new DynamicRequestRoute(); $route->setIsACP(false); $this->addRoute($route); // fire event - $this->eventHandler->fireAction($this, 'didInit'); - } - - /** - * Sets the required request handler, setter function to avoid circular dependencies. - * - * @param RequestHandler $requestHandler - */ - public function setRequestHandler(RequestHandler $requestHandler) { - $this->requestHandler = $requestHandler; + EventHandler::getInstance()->fireAction($this, 'didInit'); } /** @@ -318,9 +281,8 @@ class RouteHandler extends SingletonFactory { public static function getPathInfo() { if (self::$pathInfo === null) { self::$pathInfo = ''; - $requestHandler = WCF::getDIContainer()->get(RequestHandler::class); - if (!URL_LEGACY_MODE || $requestHandler->isACPRequest()) { + if (!URL_LEGACY_MODE || RequestHandler::getInstance()->isACPRequest()) { // WCF 2.1: ?Foo/Bar/ if (!empty($_SERVER['QUERY_STRING'])) { // don't use parse_str as it replaces dots with underscores @@ -343,7 +305,7 @@ class RouteHandler extends SingletonFactory { } // WCF 2.0: index.php/Foo/Bar/ - if ((URL_LEGACY_MODE && !$requestHandler->isACPRequest()) || ($requestHandler->isACPRequest() && empty(self::$pathInfo))) { + if ((URL_LEGACY_MODE && !RequestHandler::getInstance()->isACPRequest()) || (RequestHandler::getInstance()->isACPRequest() && empty(self::$pathInfo))) { if (isset($_SERVER['PATH_INFO'])) { self::$pathInfo = $_SERVER['PATH_INFO']; } @@ -395,7 +357,7 @@ class RouteHandler extends SingletonFactory { if ($this->defaultControllers === null) { $this->defaultControllers = array(); - foreach ($this->applicationHandler->getApplications() as $application) { + foreach (ApplicationHandler::getInstance()->getApplications() as $application) { $app = WCF::getApplicationObject($application); if (!$app) { diff --git a/wcfsetup/install/files/lib/system/request/route/DynamicRequestRoute.class.php b/wcfsetup/install/files/lib/system/request/route/DynamicRequestRoute.class.php index 60b45f32b3..0258c90775 100644 --- a/wcfsetup/install/files/lib/system/request/route/DynamicRequestRoute.class.php +++ b/wcfsetup/install/files/lib/system/request/route/DynamicRequestRoute.class.php @@ -5,7 +5,6 @@ use wcf\system\menu\page\PageMenu; use wcf\system\request\ControllerMap; use wcf\system\request\RequestHandler; use wcf\system\request\RouteHandler; -use wcf\system\WCF; /** * Dynamic route implementation to resolve HTTP requests, handling controllers using a distinct pattern. @@ -18,22 +17,12 @@ use wcf\system\WCF; * @category Community Framework */ class DynamicRequestRoute implements IRequestRoute { - /** - * @var ApplicationHandler - */ - protected $applicationHandler; - /** * schema for outgoing links * @var array */ protected $buildSchema = []; - /** - * @var ControllerMap - */ - protected $controllerMap; - /** * route is restricted to ACP * @var boolean @@ -52,11 +41,6 @@ class DynamicRequestRoute implements IRequestRoute { */ protected $primaryApplication = ''; - /** - * @var RequestHandler - */ - protected $requestHandler; - /** * list of required components * @var array @@ -69,28 +53,6 @@ class DynamicRequestRoute implements IRequestRoute { */ protected $routeData = []; - /** - * @var RouteHandler; - */ - protected $routeHandler; - - /** - * DynamicRequestRoute constructor. - * - * @param ApplicationHandler $applicationHandler - * @param ControllerMap $controllerMap - * @param RequestHandler $requestHandler - * @param RouteHandler $routeHandler - */ - public function __construct(ApplicationHandler $applicationHandler, ControllerMap $controllerMap, RequestHandler $requestHandler, RouteHandler $routeHandler) { - $this->applicationHandler = $applicationHandler; - $this->controllerMap = $controllerMap; - $this->requestHandler = $requestHandler; - $this->routeHandler = $routeHandler; - - $this->init(); - } - /** * Sets default routing information. */ @@ -134,7 +96,6 @@ class DynamicRequestRoute implements IRequestRoute { $buildSchema = ltrim($buildSchema, '/'); $components = preg_split('~({(?:[a-z]+)})~', $buildSchema, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); - $delimiters = ['/', '-', '.', '_']; foreach ($components as $component) { $type = 'component'; @@ -184,16 +145,15 @@ class DynamicRequestRoute implements IRequestRoute { if (count($components) == 1 && isset($components['controller'])) { $ignoreController = false; - if (!$this->requestHandler->isACPRequest()) { - // loading the PageMenu object as a dependency in ACP requests breaks everything - $landingPage = WCF::getDIContainer()->get(PageMenu::class)->getLandingPage(); + if (!RequestHandler::getInstance()->isACPRequest()) { + $landingPage = PageMenu::getInstance()->getLandingPage(); if ($this->primaryApplication === '') { - $primaryApplication = $this->applicationHandler->getPrimaryApplication(); - $this->primaryApplication = $this->applicationHandler->getAbbreviation($primaryApplication->packageID); + $primaryApplication = ApplicationHandler::getInstance()->getPrimaryApplication(); + $this->primaryApplication = ApplicationHandler::getInstance()->getAbbreviation($primaryApplication->packageID); } // check if this is the default controller - if (strcasecmp($this->routeHandler->getDefaultController($application), $components['controller']) === 0) { + if (strcasecmp(RouteHandler::getInstance()->getDefaultController($application), $components['controller']) === 0) { // check if this matches the primary application if ($this->primaryApplication === $application) { if (strcasecmp($landingPage->getController(), $components['controller']) === 0) { @@ -328,7 +288,7 @@ class DynamicRequestRoute implements IRequestRoute { /** * @see IRoute::matches() */ - public function matches($requestURL) { + public function matches($application, $requestURL) { if (preg_match($this->pattern, $requestURL, $matches)) { foreach ($matches as $key => $value) { if (!is_numeric($key)) { @@ -352,6 +312,6 @@ class DynamicRequestRoute implements IRequestRoute { * @return string */ protected function getControllerName($application, $controller) { - return $this->controllerMap->lookup($controller); + return ControllerMap::getInstance()->lookup($controller); } } diff --git a/wcfsetup/install/files/lib/system/request/route/LookupRequestRoute.class.php b/wcfsetup/install/files/lib/system/request/route/LookupRequestRoute.class.php index 9cc69afda3..ac69ec6d15 100644 --- a/wcfsetup/install/files/lib/system/request/route/LookupRequestRoute.class.php +++ b/wcfsetup/install/files/lib/system/request/route/LookupRequestRoute.class.php @@ -6,17 +6,8 @@ use wcf\system\request\ControllerMap; use wcf\util\FileUtil; class LookupRequestRoute implements IRequestRoute { - /** - * @var ControllerMap - */ - protected $controllerMap; - protected $routeData = []; - public function __construct(ControllerMap $controllerMap) { - $this->controllerMap = $controllerMap; - } - /** * @inheritDoc */ @@ -44,12 +35,12 @@ class LookupRequestRoute implements IRequestRoute { if (preg_match($regex, $requestURL, $matches)) { if (!empty($matches['id'])) { // check for static controller URLs - $this->routeData = $this->controllerMap->resolveCustomController($application, $matches['controller']); + $this->routeData = ControllerMap::getInstance()->resolveCustomController($application, $matches['controller']); } if (empty($this->routeData)) { // try to match the entire url - $this->routeData = $this->controllerMap->resolveCustomController($application, $requestURL); + $this->routeData = ControllerMap::getInstance()->resolveCustomController($application, $requestURL); } } diff --git a/wcfsetup/install/files/lib/system/request/route/StaticRequestRoute.class.php b/wcfsetup/install/files/lib/system/request/route/StaticRequestRoute.class.php index 3b16940da4..087c2eac2d 100644 --- a/wcfsetup/install/files/lib/system/request/route/StaticRequestRoute.class.php +++ b/wcfsetup/install/files/lib/system/request/route/StaticRequestRoute.class.php @@ -1,10 +1,6 @@ controllerMap = $controllerMap; - } - /** * @see \wcf\system\request\route\IRequestRoute::setIsACP() */ @@ -97,10 +73,10 @@ class StaticRequestRoute extends DynamicRequestRoute { /** * @see \wcf\system\request\IRoute::matches() */ - public function matches($requestURL) { - if (parent::matches($requestURL)) { + public function matches($application, $requestURL) { + if (parent::matches($application, $requestURL)) { $this->routeData['application'] = $this->staticApplication; - $this->routeData['controller'] = $this->controllerMap->lookup($this->staticController); + $this->routeData['controller'] = ControllerMap::getInstance()->lookup($this->staticController); $this->routeData['isDefaultController'] = false; return true; diff --git a/wcfsetup/install/files/lib/system/session/ACPSessionFactory.class.php b/wcfsetup/install/files/lib/system/session/ACPSessionFactory.class.php index aa11ef2fbd..7371b22ffe 100644 --- a/wcfsetup/install/files/lib/system/session/ACPSessionFactory.class.php +++ b/wcfsetup/install/files/lib/system/session/ACPSessionFactory.class.php @@ -13,51 +13,30 @@ use wcf\system\event\EventHandler; * @category Community Framework */ class ACPSessionFactory { - /** - * @var EventHandler - */ - protected $eventHandler; - /** * session editor class name * @var string */ protected $sessionEditor = 'wcf\data\acp\session\ACPSessionEditor'; - /** - * @var SessionHandler - */ - protected $sessionHandler; - - /** - * ACPSessionFactory constructor. - * - * @param EventHandler $eventHandler - * @param SessionHandler $sessionHandler - */ - public function __construct(EventHandler $eventHandler, SessionHandler $sessionHandler) { - $this->eventHandler = $eventHandler; - $this->sessionHandler = $sessionHandler; - } - /** * Loads the object of the active session. */ public function load() { // get session $sessionID = $this->readSessionID(); - $this->sessionHandler->load($this->sessionEditor, $sessionID); + SessionHandler::getInstance()->load($this->sessionEditor, $sessionID); // call beforeInit event if (!defined('NO_IMPORTS')) { - $this->eventHandler->fireAction($this, 'beforeInit'); + EventHandler::getInstance()->fireAction($this, 'beforeInit'); } $this->init(); // call afterInit event if (!defined('NO_IMPORTS')) { - $this->eventHandler->fireAction($this, 'afterInit'); + EventHandler::getInstance()->fireAction($this, 'afterInit'); } } @@ -74,7 +53,7 @@ class ACPSessionFactory { * Initializes the session system. */ protected function init() { - $this->sessionHandler->initSession(); + SessionHandler::getInstance()->initSession(); } /** diff --git a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php index 6b07b360c8..3440a6366a 100644 --- a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php +++ b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php @@ -874,13 +874,13 @@ class SessionHandler extends SingletonFactory { 'requestMethod' => $this->requestMethod, 'lastActivityTime' => TIME_NOW ); - /*if (!class_exists('wcf\system\CLIWCF', false) && PACKAGE_ID && RequestHandler::getInstance()->getActiveRequest() && RequestHandler::getInstance()->getActiveRequest()->getRequestObject() instanceof ITrackablePage && RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->isTracked()) { + if (!class_exists('wcf\system\CLIWCF', false) && PACKAGE_ID && RequestHandler::getInstance()->getActiveRequest() && RequestHandler::getInstance()->getActiveRequest()->getRequestObject() instanceof ITrackablePage && RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->isTracked()) { $data['controller'] = RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->getController(); $data['parentObjectType'] = RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->getParentObjectType(); $data['parentObjectID'] = RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->getParentObjectID(); $data['objectType'] = RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->getObjectType(); $data['objectID'] = RequestHandler::getInstance()->getActiveRequest()->getRequestObject()->getObjectID(); - }*/ + } if ($this->variablesChanged) { $data['sessionVariables'] = serialize($this->variables); } -- 2.20.1