Updated Extbase and Fluid to 1.3.0beta1. See their ChangeLog for details.
authorSebastian Kurfürst <sebastian.kurfuerst@typo3.org>
Tue, 16 Nov 2010 11:56:00 +0000 (11:56 +0000)
committerSebastian Kurfürst <sebastian.kurfuerst@typo3.org>
Tue, 16 Nov 2010 11:56:00 +0000 (11:56 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9394 709f56b5-9817-0410-a4d7-c38de5d9e867

210 files changed:
ChangeLog
typo3/sysext/extbase/ChangeLog.txt
typo3/sysext/extbase/Classes/Configuration/AbstractConfigurationManager.php
typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php
typo3/sysext/extbase/Classes/Configuration/ConfigurationManager.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Configuration/ConfigurationManagerInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Configuration/FrontendConfigurationManager.php
typo3/sysext/extbase/Classes/Core/Bootstrap.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Dispatcher.php
typo3/sysext/extbase/Classes/Domain/Model/FrontendUser.php
typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php
typo3/sysext/extbase/Classes/MVC/Controller/ActionController.php
typo3/sysext/extbase/Classes/MVC/Controller/Argument.php
typo3/sysext/extbase/Classes/MVC/Controller/Arguments.php
typo3/sysext/extbase/Classes/MVC/Controller/ArgumentsValidator.php
typo3/sysext/extbase/Classes/MVC/Controller/ControllerInterface.php
typo3/sysext/extbase/Classes/MVC/Controller/FlashMessages.php
typo3/sysext/extbase/Classes/MVC/Dispatcher.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/Request.php
typo3/sysext/extbase/Classes/MVC/RequestHandlerInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/RequestHandlerResolver.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/RequestInterface.php
typo3/sysext/extbase/Classes/MVC/Response.php
typo3/sysext/extbase/Classes/MVC/ResponseInterface.php
typo3/sysext/extbase/Classes/MVC/View/AbstractView.php
typo3/sysext/extbase/Classes/MVC/View/EmptyView.php
typo3/sysext/extbase/Classes/MVC/View/NotFoundView.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/View/ViewInterface.php
typo3/sysext/extbase/Classes/MVC/Web/AbstractRequestHandler.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/Web/BackendRequestHandler.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/Web/FrontendRequestHandler.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/MVC/Web/Request.php
typo3/sysext/extbase/Classes/MVC/Web/RequestBuilder.php
typo3/sysext/extbase/Classes/MVC/Web/Routing/UriBuilder.php
typo3/sysext/extbase/Classes/Object/Container/ClassInfo.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Container/ClassInfoCache.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Container/ClassInfoFactory.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Container/Container.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Container/Exception/CannotInitializeCacheException.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Container/Exception/TooManyRecursionLevelsException.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Container/Exception/UnknownObjectException.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/Exception/UnknownObject.php [deleted file]
typo3/sysext/extbase/Classes/Object/Exception/WrongScope.php
typo3/sysext/extbase/Classes/Object/Manager.php [deleted file]
typo3/sysext/extbase/Classes/Object/ManagerInterface.php [deleted file]
typo3/sysext/extbase/Classes/Object/ObjectManager.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/ObjectManagerInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Object/RegistryInterface.php [deleted file]
typo3/sysext/extbase/Classes/Object/TransientRegistry.php [deleted file]
typo3/sysext/extbase/Classes/Persistence/Backend.php
typo3/sysext/extbase/Classes/Persistence/IdentityMap.php
typo3/sysext/extbase/Classes/Persistence/LazyLoadingProxy.php
typo3/sysext/extbase/Classes/Persistence/LazyObjectStorage.php
typo3/sysext/extbase/Classes/Persistence/Manager.php
typo3/sysext/extbase/Classes/Persistence/ManagerInterface.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapFactory.php
typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php
typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModelFactory.php
typo3/sysext/extbase/Classes/Persistence/Query.php
typo3/sysext/extbase/Classes/Persistence/QueryFactory.php
typo3/sysext/extbase/Classes/Persistence/QueryInterface.php
typo3/sysext/extbase/Classes/Persistence/QueryResult.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QueryResultInterface.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/QuerySettingsInterface.php
typo3/sysext/extbase/Classes/Persistence/Repository.php
typo3/sysext/extbase/Classes/Persistence/RepositoryInterface.php
typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php
typo3/sysext/extbase/Classes/Persistence/Typo3QuerySettings.php
typo3/sysext/extbase/Classes/Property/Mapper.php
typo3/sysext/extbase/Classes/Reflection/Service.php
typo3/sysext/extbase/Classes/Security/Channel/RequestHashService.php
typo3/sysext/extbase/Classes/Utility/ClassLoader.php
typo3/sysext/extbase/Classes/Utility/ExtbaseRequirementsCheck.php
typo3/sysext/extbase/Classes/Utility/Extension.php
typo3/sysext/extbase/Classes/Utility/Localization.php
typo3/sysext/extbase/Classes/Utility/TypoScript.php
typo3/sysext/extbase/Classes/Validation/Validator/AbstractValidator.php
typo3/sysext/extbase/Classes/Validation/Validator/GenericObjectValidator.php
typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php
typo3/sysext/extbase/RELEASE_NOTES.txt [deleted file]
typo3/sysext/extbase/Resources/Private/MVC/NotFoundView_Template.html [new file with mode: 0644]
typo3/sysext/extbase/Tests/BaseTestCase.php
typo3/sysext/extbase/Tests/Configuration/BackendConfigurationManager_testcase.php
typo3/sysext/extbase/Tests/Configuration/FrontendConfigurationManager_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/ActionController_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/Argument_testcase.php
typo3/sysext/extbase/Tests/MVC/Controller/Arguments_testcase.php
typo3/sysext/extbase/Tests/MVC/DispatcherTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Object/Container/ClassInfoFactoryTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Object/Container/ContainerTest.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Object/Container/Fixtures/Testclasses.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Persistence/QueryResult_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Persistence/Query_testcase.php
typo3/sysext/extbase/Tests/Persistence/Repository_testcase.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Utility/Extension_testcase.php
typo3/sysext/extbase/Tests/Validation/ValidatorResolver_testcase.php
typo3/sysext/extbase/ext_autoload.php
typo3/sysext/extbase/ext_emconf.php [changed mode: 0644->0755]
typo3/sysext/extbase/ext_localconf.php
typo3/sysext/extbase/ext_tables.php
typo3/sysext/extbase/ext_tables.sql
typo3/sysext/extbase/ext_typoscript_setup.txt
typo3/sysext/extbase/last_synched_target
typo3/sysext/fluid/ChangeLog.txt
typo3/sysext/fluid/Classes/Compatibility/DocbookGeneratorService.php
typo3/sysext/fluid/Classes/Compatibility/ObjectManager.php [deleted file]
typo3/sysext/fluid/Classes/Compatibility/TemplateParserBuilder.php
typo3/sysext/fluid/Classes/Core/Parser/Interceptor/Escape.php
typo3/sysext/fluid/Classes/Core/Parser/ParsingState.php
typo3/sysext/fluid/Classes/Core/Parser/SyntaxTree/ViewHelperNode.php
typo3/sysext/fluid/Classes/Core/Parser/TemplateParser.php
typo3/sysext/fluid/Classes/Core/Rendering/RenderingContext.php
typo3/sysext/fluid/Classes/Core/Rendering/RenderingContextInterface.php
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractTagBasedViewHelper.php
typo3/sysext/fluid/Classes/Core/ViewHelper/AbstractViewHelper.php
typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/AbstractWidgetViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/AjaxWidgetContextHolder.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Bootstrap.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/MissingControllerException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/RenderingContextNotFoundException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/WidgetContextNotFoundException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/Exception/WidgetRequestNotFoundException.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetContext.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetRequest.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetRequestBuilder.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/Core/Widget/WidgetRequestHandler.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/View/AbstractTemplateView.php
typo3/sysext/fluid/Classes/View/StandaloneView.php
typo3/sysext/fluid/Classes/View/TemplateView.php
typo3/sysext/fluid/Classes/View/TemplateViewInterface.php [deleted file]
typo3/sysext/fluid/Classes/ViewHelpers/CObjectViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/FormViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/CropViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Format/HtmlViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/ImageViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/RenderChildrenViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Uri/ImageViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Widget/AutocompleteViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/Controller/AutocompleteController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/Controller/PaginateController.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/LinkViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/PaginateViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/Widget/UriViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Configuration/TypoScript/setup.txt [new file with mode: 0644]
typo3/sysext/fluid/Resources/Private/Templates/ViewHelpers/Widget/Autocomplete/Index.html [new file with mode: 0644]
typo3/sysext/fluid/Resources/Private/Templates/ViewHelpers/Widget/Paginate/Index.html [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Parser/ParsingStateTest.php
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/AbstractNodeTest.php
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/TextNodeTest.php
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/ViewHelperNodeComparatorTest.php
typo3/sysext/fluid/Tests/Unit/Core/Parser/SyntaxTree/ViewHelperNodeTest.php
typo3/sysext/fluid/Tests/Unit/Core/Parser/TemplateParserPatternTest.php
typo3/sysext/fluid/Tests/Unit/Core/Parser/TemplateParserTest.php
typo3/sysext/fluid/Tests/Unit/Core/Rendering/RenderingContextTest.php
typo3/sysext/fluid/Tests/Unit/Core/TagBasedViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/Core/TagBuilderTest.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/AbstractViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/ArgumentDefinitionTest.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/ConditionViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/TemplateVariableContainerTest.php
typo3/sysext/fluid/Tests/Unit/Core/ViewHelper/ViewHelperVariableContainerTest.php
typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/AjaxWidgetContextHolderTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetContextTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetRequestBuilderTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetRequestHandlerTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/Core/Widget/WidgetRequestTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/View/AbstractTemplateViewTest.php
typo3/sysext/fluid/Tests/Unit/View/StandaloneViewTest.php
typo3/sysext/fluid/Tests/Unit/View/TemplateViewTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/AliasViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/BaseViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/CountViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/CycleViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ElseViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ForViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/AbstractFormFieldViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/AbstractFormViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/CheckboxViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/ErrorsViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/HiddenViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/RadioViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/SelectViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/SubmitViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/TextareaViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/TextboxViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Form/UploadViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/FormViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/CurrencyViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/DateViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/Nl2brViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/NumberViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/PaddingViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Format/PrintfViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/GroupedForViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/IfViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Link/ExternalViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/RenderChildrenViewHelperTest.php [new file with mode: 0644]
typo3/sysext/fluid/Tests/Unit/ViewHelpers/RenderViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ThenViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/Uri/ExternalViewHelperTest.php
typo3/sysext/fluid/Tests/Unit/ViewHelpers/ViewHelperBaseTestcase.php
typo3/sysext/fluid/ext_autoload.php
typo3/sysext/fluid/ext_emconf.php
typo3/sysext/fluid/ext_tables.php [new file with mode: 0644]
typo3/sysext/fluid/ext_typoscript_setup.txt [new file with mode: 0644]
typo3/sysext/fluid/last_synched_target

index 524966f..0b803fe 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-11-16  Sebastian Kurfuerst  <sebastian@typo3.org>
+
+       * Updated Extbase and Fluid to 1.3.0beta1. See their ChangeLog for details.
+
 2010-11-16  Steffen Kamper  <steffen@typo3.org>
 
        * Added feature #16396: Implement a Grid View + wizard to enable the backend layout to be adapted to the frontend look and feel (Thanks to Joey Hasenau, Martin Ficzel and Thomas Hempel)
index 3936f9c..86d9730 100644 (file)
@@ -1,5 +1,480 @@
-ChangeLog for Fluid
-===================
+ChangeLog for Extbase
+=====================
+
+Changes for 1.3.0 Beta 1
+========================
+included in TYPO3 4.5.0 Beta 1.
+
+Extbase 1.3.0 Beta 1 has a lot new and greatly improved features, and also many bugfixes.
+The highlights are outlined below, and explained in-depth a little further down.
+
+NOTE: This release brings new table definitions, so please visit the install tool or the Extension
+Manager and update the tables of Extbase.
+
+*** EVERY FEATURE IS DESCRIBED IN DEPTH BELOW ***
+
+* Dependency Injection
+* Dispatcher Refactoring & Completely re-done Configuration Manager
+       This means that Tx_Extbase_Dispatcher is now DEPRECATED!
+       Additionally, if you defined the TypoScript setup for a plugin by hand (which you should not),
+       the syntax has changed a bit there.
+* QueryResult refactoring (needed for Fluid Widgets)
+       THIS COULD BE A BREAKING CHANGE FOR YOU!
+
+Additionally, the following smaller features were implemented:
+
+* Configurable plugin namespaces (#8365)
+* Automatic target page determination (#9121)
+* Improved resolveView() mechanism
+* Allowing plugins to be registered as new content element (#10666)
+* Default Orderings & QuerySettings (#10319)
+
+Breaking Changes:
+
+* The UriBuilder now uses the current cObject instead of creating a new instance in the constructor. This is a breaking change if you instantiated the UriBuilder in your code. Please use the Extbase ObjectManager or inject the ConfigurationManager manually.
+* fixed typo in getter and setter of Tx_Extbase_Domain_Model_FrontendUser::lastlogin
+* Flashmessages now share a scope throughout the extension. Before, every plugin had it's own scope leading to the messages only being output when entering the same plugin again (e.g. redirecting from one plugin to another would never display the messages)
+
+Known issues:
+
+* The Unit Tests do not fully work again, we will fix that in the next days.
+* There might be still issues with the support of backend modules, we are working on that!
+
+Dependency Injection
+--------------------
+
+Instead of creating objects through t3lib_div::makeInstance, and connecting them together manually,
+you yan now use Dependency Injection (DI) for that. Let's give an example: If my class "Tx_Foo_Controller_MyController"
+needs another class "Tx_Foo_Service_LoggingService", it can get an instance of the logging service
+by Dependency Injection, by specifying the following code:
+
+class Tx_Foo_Controller_MyController {
+       protected $loggingService;
+
+       /**
+        * @param Tx_Foo_Service_LoggingService $loggingService
+        */
+       public function injectLoggingService(Tx_Foo_Service_LoggingService $loggingService) {
+               $this->loggingService = $loggingService;
+       }
+}
+
+The DI container finds that the class "MyController" has an method whose name starts with "inject",
+and thus passes the logging service to MyController.
+It is important that you can *only retrieve Singletons* through the inject annotations. If you need
+to instanciate a prototype object, it is important to *not* use t3lib_div::makeInstance() anymore
+(as it bypasses the DI container), but instead you need to inject the ObjectManager, and ask it
+to create your prototype object using the create() method. Example:
+
+class Tx_Foo_Controller_MyController {
+       protected $logFile;
+
+       /**
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->logFile = $objectManager->create('Tx_Foo_Domain_Model_LogFile');
+       }
+}
+
+In the above example, you have seen that we reference not the concrete implementation *ObjectManager*,
+but instead the *ObjectManagerInterface*. If a name ends with "...Interface", Extbase DI automatically
+strips away the "Interface" from the name, and expects to find a concrete implementation of that interface.
+This is generally a very good practice: For your core classes, you should always reference an *interface*,
+and let the DI container instanciate the concrete class.
+
+Additionally, Extbase DI allows to *replace* certain implementation classes by other classes through
+configuration in TypoScript. Let's give an example, and then you can see the concept:
+
+config.tx_extbase.objects {
+       Tx_Extbase_Persistence_Storage_BackendInterface {
+               className = Tx_Extbase_Persistence_Storage_Typo3DbBackend
+       }
+}
+
+This essentially means to the DI container: "At all places where you encounter a "BackendInterface",
+you should instanciate the "Typo3DbBackend" class."
+
+However, note that this setting can only be configured *globally* right now, it is not possible
+to override that on a per-extension basis.
+
+Generally, the Extbase DI container provides a subset of the functionality of FLOW3's dependency injection.
+
+Dispatcher Refactoring & Completely re-done Configuration Manager
+-----------------------------------------------------------------
+
+In the last versions of Extbase, the Dispatcher (Tx_Extbase_Dispatcher) was the main entry point to Extbase.
+However, as we did not have Dependency Injection at that point, it became really complex and did lots of things
+which it should not do in the first place. That's why we greatly improved that part. Now, any Extbase extension
+is invoked using the Tx_Extbase_Core_Bootstrap. Additionally, the TypoScript used for the registration of any
+Extbase extension has been cleaned up and adjusted:
+
+lib.foo = USER
+lib.foo {
+       userFunc = tx_extbase_core_bootstrap->run
+       extensionName = YourExtension
+       pluginName = YourPlugin
+}
+
+Additionally, you can also override the list of Switchable Controller Actions through TypoScript:
+
+lib.foo = USER
+lib.foo {
+       userFunc = tx_extbase_core_bootstrap->run
+       extensionName = YourExtension
+       pluginName = YourPlugin
+       switchableControllerActions {
+               Standard {
+                       1 = action2
+                       2 = action3
+               }
+       }
+}
+
+Of course, you cannot call actions which were not defined previously in the plugin; so the Switchable
+Controller Actions in TypoScript can be only used to shrink the number of actions available.
+
+NOTE: If you manually defined the above snippet, notice that there is a NON-BACKWARDS-COMPATIBLE change
+in there. But you did that at your own risk, as that was never public API ;)
+
+If you used Tx_Extbase_Dispatcher before in your own code, it should still work, but it is deprecated.
+Instead, instead
+
+OLD: Tx_Extbase_Dispatcher::getConfigurationManager()
+NEW: inject Tx_Extbase_Configuration_ConfigurationManagerInterface into your class
+
+OLD: Tx_Extbase_Dispatcher::getPersistenceManager()
+NEW: inject Tx_Extbase_Persistence_ManagerInterface into your class
+
+OLD: Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration()
+NEW: inject Tx_Extbase_Configuration_ConfigurationManagerInterface into your class,
+     and call $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+     on the ConfigurationManager.
+
+Please note that the Configuration Manager is STILL NO PUBLIC API, and its method signature has also changed.
+
+QueryResult refactoring (needed for Fluid Widgets)
+--------------------------------------------------
+
+Before this change, a call of $query->execute() inside a repository immediately executed the query and
+returned the result as array.
+Now, queries are executed lazily at the first moment where you really need them. This means that $query->execute()
+returns an object of type Tx_Extbase_Persistence_QueryResultInterface, which behaves like an array, meaning you
+can use foreach() to loop over the query result.
+However, due to an inconsistency of PHP, the array_* methods, and the iteration methods like current(),
+next(), ... do NOT work on objects which implement ArrayAccess -- that's the reason why the QueryResult
+refactoring is a breaking change.
+
+Now, however, the following is possible:
+* Return the first query result: $query->execute()->getFirst()
+* Get the underlying query: $query->execute()->getQuery()
+* Convert the result to array: $query->execute()->toArray()
+
+This change is a prerequisite for Fluid Widgets to work. See the Fluid ChangeLog for details.
+
+
+Configurable Plugin Namespaces
+------------------------------
+
+By default each Extbase plugin has a unique URI prefix to avoid collisions with other plugins on your website.
+This so called plugin namespace usually has the format tx_yourextension_yourplugin.
+With Extbase 1.3 it is possible to override this namespace. This comes in handy if want to interact with 3rd party
+extensions, for example with tt_news:
+
+plugin.tx_yourextension.view.pluginNamespace = tx_ttnews
+
+This sets the plugin namespace of all your plugins inside the extension to "tx_ttnews", making it possibl
+to directly access tt_news parameters in your controller:
+
+/**
+ * @param integer $tt_news tt_news Article uid
+ * @return void
+ */
+public function yourAction($tt_news) {
+       // interact with $tt_news uid
+}
+
+This works with automatic mapping to Domain models too of course:
+
+/**
+ * @param Tx_YourExtension_Domain_Model_NewsArticle $tt_news tt_news Article
+ * @return void
+ */
+public function yourAction(Tx_YourExtension_Domain_Model_NewsArticle $tt_news) {
+       // interact with $tt_news object
+}
+
+You can also override the plugin namespace for a single instance by adding the section <view.pluginNamespace> to your
+plugin FlexForm.
+
+
+Automatic target page determination
+-----------------------------------
+
+In TYPO3 v5 we won't have the notion of page uids. To accustom developers to this change, we're trying to free you from
+the need to specify target pages from within your Extension. Of course you can put all your functionality into one fully
+fledged plugin, then you won't have to deal with target pages as the current page is used by default.
+
+But sometimes you want to be able to change the surrounding contents of a special view of your extension (e.g. the
+subcontent column of a details page). As before you can still specify the target page explicitly like:
+
+<f:link.action action="foo" pageUid="123" />
+
+With Extbase 1.3 you can also use a new feature called "automatic target page determination". It is disabled by default,
+but you can enable it with the following TypoScript:
+
+plugin.tx_yourextension.view.defaultPid = auto
+
+Then Extbase will search the page tree for a plugin that is configured to handle the specified action and you can omit
+the "pageUid" parameter in your links. Of course, this does not work if you use the same plugin multiple times in your
+page tree. In this case you can override the default page ID for the respective plugins:
+
+plugin.tx_yourextension_yourplugin.view.defaultPid = 123
+
+Note: By default this feature is not activated, because that would be a breaking change in some cases
+
+
+Improved resolveView() mechanism
+--------------------------------
+
+Another feature we backported from FLOW3 is the improved view resolving.
+You can now change the default view implementation *per format* by inserting the following line in your Controller:
+
+protected $viewFormatToObjectNameMap = array(
+       'json' => 'Tx_YourExtension_View_JsonView',
+       'html' => 'Tx_YourExtension_View_HtmlView'
+);
+
+
+Allowing plugins to be registered as new content element
+--------------------------------------------------------
+
+This is done using an additional parameter to Tx_Extbase_Utility_Extension::configurePlugin
+that allows you to specify the plugin type. Example:
+
+Tx_Extbase_Utility_Extension::configurePlugin(
+       $_EXTKEY,
+       'BlogList',
+       array('Blog' => 'index'),
+       array(),
+       Tx_Extbase_Utility_Extension::PLUGIN_TYPE_CONTENT_ELEMENT
+);
+(The default value for the pluginType parameter is Tx_Extbase_Utility_Extension::PLUGIN_TYPE_PLUGIN)
+
+Default Orderings & QuerySettings
+---------------------------------
+
+It is now possible to change the default orderings of a repository without you having to modify the query by setting
+the $defaultOrderings property of your Repository to a non-empty array:
+
+protected $defaultOrderings = array(
+       'title' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING,
+       'date' => 'title' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING
+);
+
+This will change the default ordering for all queries created by this repository. Of course you can override the
+ordering by calling $query->setOrderings() in your custom finder method.
+
+Besides it's now possible to change the default query settings of a repository. This way you could for instance disable
+"respect storage pid" for all queries. We added a life-cycle method "initializeObject" to the repository which will be
+executed as soon as the repository is created. Just override it like the following:
+
+public function initializeObject() {
+       $querySettings = $this->objectManager->create('Tx_Extbase_Persistence_Typo3QuerySettings');
+       $querySettings->setRespectStoragePage(FALSE);
+       $this->setDefaultQuerySettings($querySettings);
+}
+
+Of course, QuerySettings can be overridden too in your custom finder method by calling $query->setQuerySettings();
+
+
+Full Changes:
+-------------
+
+[+FEATURE] Extbase (Utility): Allow plugins to be registered as new content element
+       Added a fifth parameter to Tx_Extbase_Utility_Extension::configurePlugin that allows
+       you to specify the plugin type (currently "list_type" and "CType" are supported).
+       Thanks to Marc Bastian Heinrichs, Rens Admiraal & Franz Koch for your help!
+       Resolves: #10666
+[+BUGFIX] Extbase (Utility): Added condition to Tx_Extbase_Utility_Extension::getTargetPidByPlugin() in order to only select tt_content entries that are of CType "list". Thanks to Marc Bastian Heinrichs
+[!!!][~TASK] Extbase (Configuration): Major rework of the ConfigurationManager
+       Configuration of controllers and actions is now stored in a global registry
+       ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']). But you
+       should never access this directly. Instead always retrieve the frameworkConfiguration
+       from the ConfigurationManager.
+       Inserting an Extbase plugin is now as simple as:
+       lib.foo = USER
+       lib.foo {
+         userFunc = tx_extbase_core_bootstrap->run
+         extensionName = YourExtension
+         pluginName = YourPlugin
+       }
+       This is not really a breaking change as it does not change the public API. But it's not unlikely that it changes the behavior of your Extension in case you modified the TypoScript, that is generated by Tx_Extbase_Utility_Extension::configurePlugin().
+       NOTE: Unit tests of Extbase and Fluid v4 are broken currently. We'll be fixing those asap
+[~TAKS] Extbase (MVC): FrontendRequestHandler now retrieves the current cObject through the ConfigurationManager
+[+BUGFIX] Extbase (MVC): FrontendRequestHandler was refering to $this->frameworkConfiguration which wasn't available
+[-API] Extbase (MVC): marked Tx_Extbase_MVC_Web_Request::getContentObjectData() deprecated as should retrieve the current cObject through the ConfigurationManager
+[+TASK] Extbase (MVC): modified the Tx_Extbase_MVC_Web_RequestBuilder so that it's possible to change the action only by specifying the action parameter. Before you had to specify the controller as well, even if it was the default controller
+[+BUGFIX] Extbase (MVC): Flashmessages now share a scope throughout the extension. Before, every plugin had it's own scope leading to the messages only being output when entering the same plugin again (e.g. redirecting from one plugin to another would never display the messages)
+[~TASK] Extbase (Core): The Flashmessages now get persisted in the Bootstrap in resetSingletons()
+[-TASK] Extbase (Core): Removed some commented lines from Bootstrap
+[FEATURE] Extbase (Object): Make DI Class Mapping configurable through TS
+       It is now possible to configure the Dependency Injection class mapping by specifying:
+       config.tx_extbase.objects.[FullyQualifiedObjectName].className = [NewClassName]
+       This has the effect of effectively replacing [FullyQualifiedObjectName] with
+       [NewClassName].
+       Resolves: #10559
+[-TASK] Extbase (Utility): Removed two obsolete checks for $GLOBALS['TSFE']->tmpl->setup['tt_content.']['list.']['20.'] in Tx_Extbase_Utility_Extension
+[~TASK] Extbase: added two doc comments that were missing
+[+BUGFIX] Extbase (Persistence): Extbase still used PHPs current() on some QueryResults in Persistence/Repository. Replaced these by calls to the getFirst() method of the QueryResult
+[+TASK] Extbase (Persistence): added a private field to the QueryResult to make the above case easier to debug: When calling current() on an Iterator, PHP returns the first field of that object instead of calling the current() method of the Iterator interface.. With our somewhat pragmatic approach you'll see the warning if you debug the results of current($query->execute())
+[+BUGFIX] Extbase (Persistence): Replaced two occurrences of Query->count() by Query->execute()->count() to avoid deprecated warnings in the Core
+[+BUGFIX] Extbase (MVC): view configuration (templateRootPath, ...) has to be set before View::canRender() is called
+[!!!][+TASK] Extbase (MVC): The UriBuilder now uses the current cObject instead of creating a new instance in the constructor. This is a breaking change if you instantiated the UriBuilder in your code. Please use the Extbase ObjectManager or inject the ConfigurationManager manually.
+[+BUGFIX] Extbase (Reflection): ReflectionService now uses a cacheIdentifier per Extension. Besides the Bootstrap now resets the ReflectionService after dispatching a request. This resolves #10146
+[+TASK] Extbase (Configuration): The ConfigurationManager now holds the current cObject. You can retrieve it via ConfigurationManagerInterface::getContentObject()
+[+BUGFIX] Extbase (Configuration): When loading configuration of other plugins, the context specific configuration (e.g. flexform settings) are no longer merged with the frameworkConfiguration
+[+BUGFIX] Extbase (MVC): Controllers are no Singletons by default. If a controller contains stateful fields (e.g. $this->settings) this breaks multiple plugins on one page
+[+TASK] Extbase (Persistence): QuerySettings now also store the storage page id(s). This is required for the upcoming Ajax Widgets
+[+BUGFIX] Extbase: fixed php warning in Tx_Extbase_Persistence_LazyLoadingProxy when loading the real instance would return NULL. Resolves #10683
+[+BUGFIX] Extbase: use 3rd parameter = TRUE of t3lib_div::trimExplode to split switchableControllerActionParts from flexform. Thanks to Georg Ringer. Resolves #10688
+[+TASK] Extbase: Replaced "public static" by "static public" in various places to be CGL conform
+[+TASK] Extbase: Marked Utitlity_Extension camelCase/underscore helper functions deprecated
+[+TASK] Extbase: Removed obsolete FIXME comments, whitespace fixes
+[!!!] Extbase: Reintegrating branch "dispatcher" to trunk. Resolves: #10605
+       Branch history:
+[+FEATURE] Extbase (Configuration): Extend ConfigurationManager so that it can load configuration of different plugins
+[+FEATURE] Extbase (Configuration): 1st level cache for ConfigurationManager. Resolves: #10717. Resolves: #10716
+[+TASK] Extbase: cleaned up Configuration* implementation, replaced t3lib_div::makeInstance() calls
+       Streamlined ConfigurationManager API and enforced its usage throughout the Extbase classes.
+       Replaced all t3lib_div::makeInstance() calls by $objectManager->create()/$objectManager->get() throughout the Extbase classes.
+       Some smaller tweaks and fixes. Resolves: #10655. Resolves: #10712
+[TASK] Extbase (Object): Make tests work again. Resolves: #10709
+[TASK] Extbase (Object): Updated autoload.php and emconf. Relates to: #10561
+[TASK] Extbase (Object): Use typed exceptions. Relates to: #10561
+[TASK] Extbase (Object): CGL cleanup
+       Additionally, removed support for @inject annotations at methods. Relates to: #10561
+[TASK] Extbase (Object): Remove getParents. Relates to: #10561
+[TASK] Extbase (Object): Remove isSingleton. Relates to: #10561
+[TASK] Extbase (Object): Remove injectExtensionSettings feature. Relates to: #10561
+[TASK] Extbase (Object): Change namespaces to Tx_Extbase_Object_Container. Relates to: #10561
+[TASK] Extbase (Object): Add Container to Extbase. Relates to: #10561
+[+TASK] Extbase (Core): moved Tx_Extbase_Bootstrap to Tx_Extbase_Core_Bootstrap
+       Moving Bootstrap to be compliant with FLOW3
+       Removed obsolete Classes. Resolves: #10704
+[+TASK] Extbase: Merged current trunk (r2689) with local modifications into dispatcher branch
+       Note: This still needs a cleanup and some fixes (see FIXME comments) before it can be merged back to the trunk. Relates to: #10605. Relates to: #10655
+[+TASK] Extbase (Configuration): Moved CONFIGURATION_TYPE_* constraints to ConfigurationManagerInterface. Resolves #10604.
+[~TASK] Extbase (Configuration): The concrete configuration management strategy gets instanciate only once now.
+[+FEATURE] Extbase (MVC): Decoupled framework settings from Dispatcher.
+       With the new dependency injection feature you can get the Configuration Manager injected by adding the lines
+       protected $configurationManager;
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+       You can get various types of configuration invoking
+       $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManager::CONFIGURATION_TYPE_EXTBASE)
+       where the class constant must be either CONFIGURATION_TYPE_EXTBASE (for Extbase settings), or CONFIGURATION_TYPE_SETTINGS (for the current module/plugin settings), or CONFIGURATION_TYPE_TYPOSCRIPT (for a raw TS array). Resolves #4741.
+[~TAKS] Extbase: Removed obsolete code.
+[~TASK] Extbase: Added core patch for mod.php (see previous commit).
+[+TASK] Extbase: Changed the way a module gets called.
+       - You can now specify a function name to be invoked by mod.php:
+$TBE_MODULES['_dispatcher'][] = 'Tx_Extbase_Bootstrap->callModule';
+       - This requires a core patch.
+[~TASK] Extbase: Changed configuration of the RequestHandler class names to TypoScript.
+       - The request handlers can now be registered in TypoScript with the setting:
+          config.tx_extbase.mvc.requestHandlers.[RequestHandlerClassName] = [RequestHandlerClassName].
+       - There are now two RequestHandlers in Extbase: FrontendRequestHandler and BackendRequestHandler. Common functionality is in the AbstractRequestHandler.
+[+API][+FEATURE] Extbase (Utility): Implemented mechanism to register RequestHandlers.
+[+TASK] Extbase: Backported Request Handler Resolver.
+[~TASK] Extbase: Added "deprecated" annotation to Dispatcher.
+[~TASK] Extbase: Added missing comment.
+[+BUGFIX] Extbase (Reflection): The ReflectionService now gets injected to the dispatcher. Related to #10146.
+[+BUGFIX] Extbase (Reflection): Changed the way the Reflection Service and it's cache gets initialized.
+       * Removed check for pre-initialized Reflection Service in the Bootstrap.
+       * Now using a fixed cache key ('ReflectionData').
+       Related to #10146.
+[~TASK] Extbase: First step of the Dispatcher refactoring.
+       * Added and adapted some Unit Tests.
+       * Moved the Dispatcher to MVC.
+       * Added a backwards compatibility Dispatcher on root level.
+       * Added a Bootstrap class.
+       * Removed all backend module support for now.
+       Related to #7153.
+[+TASK] Extbase: Added branch for the dispatcher refactoring.
+[!!!][+BUGFIX] Extbase: fixed typo in getter and setter of Tx_Extbase_Domain_Model_FrontendUser::lastlogin . Thanks to Christian Schwan. Resolves #9345
+[+FEATURE] Extbase (MVC): Backport possibility to change the view object class name more easily
+       Backported FLOW3s improved resolveView() mechanism. Tx_Fluid_View_TemplateView is still the default implementation, but can be easily changed by setting $defaultViewObjectName in your controller. Besides it's possible to specifying different views depending on the current request format by setting $viewFormatToObjectNameMap.
+       NOTE: If the view can't be rendered, the new template based "NotFoundView" will be created. So instead of the invisible HTML comments of the EmptyView, you'll get a more meaningful error message if the template file could not be found
+       Resolves: #8990
+[!!!][+FEATURE] Extbase (Persistence): Backport QueryResult from FLOW3
+       Now Query::execute() returns an instance of QueryResultInterface that allows it to modify the query before actually accessing the records that it retrieves. This is required for the upcoming "Fluid widgets" backport (#10568).
+       NOTE: This change is not backwards compatible, if you work with PHPs array_* functions on the query result. To work around this issue, you'll have to convert the query result to an array before by calling the QueryResult::toArray() method. We're planning to add a compatibility mode, but that's not yet implemented.
+       Resolves: #10566
+[+BUGFIX] Extbase (Object): Minor fix in ObjectManager to make it compatible with PHP 5.2.x
+       Relates to: #9062
+[+BUGFIX] Extbase (Object): Refactor Object Manager
+       The Object Manager is now at the same location and
+       has the same API as in FLOW3.
+[+BUGFIX] Extbase: Major cleanups to Dependency Injection and Persistence
+       Now, DI finally works with Persistence, cleaning
+       this greatly up. Additionally, all internal
+       t3lib_div::makeInstance calls have been replaced.
+       Now, dependency injection is actually usable.
+       Additionally, we completely thought over which
+       persistence classes need to be singleton and which
+       should be prototype, leading finally to a
+       coherent design in the persistence layer.
+[+BUGFIX] Extbase: remove non-used interfaces
+       Removed classes which were not used.
+       Relates to: #9062
+       Resolves: #10585
+       Resolves: #10564
+       * Cleaned up Persistence Backend
+       * Cleaned up QOM Factory
+[+BUGFIX] Extbase (MVC): Fix arguments object
+       The arguments object is now correctly inheriting from ArrayObject
+       Resolves: #10562
+[+BUGFIX] Extbase (MVC): Make database connection work again
+       Resolves: #10585
+[+FEATURE] Extbase (DI): merging DI into trunk. (resolves #10558)
+[+TASK] Extbase: Undefined identifier in Tx_Extbase_Persistence_Storage_Typo3DbBackend::removeRow
+       Method clearPageCache was given an undefined variable $uid as second parameter.
+       Resolves: #10570
+[+TASK] Extbase: $query->contains generate incomplete SQL
+       Use FIND_IN_SET instead of a self-constructed query of LIKE statements
+       Resolves: #8959
+[+BUGFIX] Extbase (Persistence): Removed method createQuery from the QOMFactory. It is neither part of the API nor is it used by Extbase. Resolves #10215
+[+BUGFIX] Extbase (Property): Minor fix in PHP doc comment
+       Fix the order of @param annotation in Tx_Extbase_Property_Mapper::mapAndValidate()
+       Resolves: #5887
+[~CONFIGURATION] Extbase (MVC): Changed default value for automatic target page determination
+       The page id gets automatically detected if plugin.tx_extensionname_pluginname.view.defaultPid
+       is an empty string (was "auto" before). This ensures backwards compatibility.
+       Resolves #9121
+[TASK] Extbase: moved Release Notes to ChangeLog.txt.
+[+FEATURE] Extbase (MVC): Automatic target page determination
+       you can use the "pageUid" argument of the link.* and uri.* view helpers
+       to link to a different page. That is deprecated though as we won't have
+       the notion of "page uids" in v5. Instead the target page is now determined
+       automatically.
+       If the target page can't be determined because more than one active
+       plugin is capable of handling the action an exception will be thrown.
+       In that case you'll have to define the target page either by using the
+       pageUid argument or - preferably - by setting
+       plugin.tx_extensionname_pluginname.view.defaultPid to a fixed page uid.
+       Note: This feature still has to be documented!
+       Resolves: #9121
+[+FEATURE] Extbase (MVC): Configurable plugin namespace
+       until now the namespace (aka prefix) of Extbase plugins was
+       fixed (tx_extensionname_pluginname). This is now configurable
+       via TypoScript. Just write:
+       plugin.tx_extensionname_pluginname.view.pluginNamespace = my_custom_namespace
+       to change the prefix for a specific plugin or
+       plugin.tx_extensionname.view.pluginNamespace = my_custom_namespace
+       to change if for the whole extension.
+       Note: This feature still has to be documented!
+       Resolves: #8365
 
 Changes for 1.3.0 Alpha 2
 =========================
@@ -49,7 +524,44 @@ Full Changes:
 [+BUGFIX] Extbase (Persistence): Fixed a problem where localized objects inside an aggregate are not translated. Resolves #8555.
 [~TASK] Extbase: Removed new lines at the end of php files.
 
+RELEASE NOTES of Extbase v1.0.0
+===============================
+
+This package contains the Extbase Framework for Extensions. You may
+also want to install the BlogExample (blog_example) to experiment
+with. This little example extension demonstrates some of the main
+features of Extbase. The documentation is bundled in a separate
+extension called doc_extbase. Both, the blog_example and the
+doc_extbase can downloaded via TER.
+
+http://typo3.org/extensions/repository/view/blog_example/current/
+http://typo3.org/extensions/repository/view/doc_extbase/current/
+
+Currently Extbase is in ALPHA state. Do not expect everything in the
+right place and shape. And keep in mind that the API may change
+until TYPO3 v4.3beta1 is released.
+
+If you have any feature requests or encountered issues regarding
+this package please use the facilities on forge to report.
+
+We are very open to answer your questions. Please use the newsgroup
+
+typo3.projects.typo3v4mvc on lists.netfielders.de
+
+so other developers can react to your comments and also
+profit from the postet solutions. Do not contact a member of the
+development team via private email (or skype, or visits, or ...)
+until he accepted this channel. We all do coding for Extbase on
+our sparetime and must handle our regular work load - and don't
+forget about our families ;-).
+
+We hope you have fun with this package!
+
+-- Your Extbase Development Team
 
 HOW TO CREATE THE CHANGELOG
 ===========================
-git log [startRevision]..HEAD --pretty=format:"%s%n%b%n" | grep -v "^$" | grep -v "git-svn-id"
\ No newline at end of file
+git log [startRevision]..HEAD --pretty=format:"%s%n%b%n" | grep -v "^$" | grep -v "git-svn-id"
+
+Verify that the merge into the Core succeeded:
+diff -urNw --exclude=".git" --exclude=".svn" -I "@version"  ../../../typo3/sysext/extbase/ .
index e53a47e..e8c5e84 100644 (file)
@@ -29,7 +29,7 @@
  * @subpackage Configuration
  * @version $ID:$
  */
-abstract class Tx_Extbase_Configuration_AbstractConfigurationManager {
+abstract class Tx_Extbase_Configuration_AbstractConfigurationManager implements t3lib_Singleton {
 
        /**
         * Default backend storage PID
@@ -37,25 +37,77 @@ abstract class Tx_Extbase_Configuration_AbstractConfigurationManager {
        const DEFAULT_BACKEND_STORAGE_PID = 0;
 
        /**
-        * The TypoScript parser
-        *
-        * @var t3lib_TSparser
+        * Storage of the raw TypoScript configuration
+        * @var array
+        */
+       protected $configuration = array();
+
+       /**
+        * @var tslib_cObj
+        */
+       protected $contentObject;
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * name of the extension this Configuration Manager instance belongs to
+        * @var string
+        */
+       protected $extensionName;
+
+       /**
+        * name of the plugin this Configuration Manager instance belongs to
+        * @var string
         */
-       protected $typoScriptParser;
+       protected $pluginName;
 
        /**
-        * Storage for the settings, loaded by loadSettings()
+        * 1st level configuration cache
         *
         * @var array
         */
-       protected $settings;
+       protected $configurationCache = array();
 
        /**
-        * Constructs the configuration manager
+        * @param Tx_Extbase_Object_ManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * @param tslib_cObj $contentObject
+        * @return void
+        */
+       public function setContentObject(tslib_cObj $contentObject = NULL) {
+               $this->contentObject = $contentObject;
+       }
+
+       /**
+        * @return tslib_cObj
+        */
+       public function getContentObject() {
+               return $this->contentObject;
+       }
+
+       /**
+        * Sets the specified raw configuration coming from the outside.
+        * Note that this is a low level method and only makes sense to be used by Extbase internally.
         *
+        * @param array $configuration The new configuration
+        * @return void
         */
-       public function __construct() {
-               $this->typoScriptParser = t3lib_div::makeInstance('t3lib_TSparser');
+       public function setConfiguration(array $configuration = array()) {
+               // reset 1st level cache
+               $this->configurationCache = array();
+
+               $this->extensionName = $configuration['extensionName'];
+               $this->pluginName = $configuration['pluginName'];
+               $this->configuration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($configuration);
        }
 
        /**
@@ -64,37 +116,103 @@ abstract class Tx_Extbase_Configuration_AbstractConfigurationManager {
         * The Extbase framework configuration HAS TO be retrieved using this method, as they are come from different places than the normal settings.
         * Framework configuration is, in contrast to normal settings, needed for the Extbase framework to operate correctly.
         *
-        * @param array $pluginConfiguration The current incoming extbase configuration
+        * @param string $extensionName if specified, the configuration for the given extension will be returned (plugin.tx_extensionname)
+        * @param string $pluginName if specified, the configuration for the given plugin will be returned (plugin.tx_extensionname_pluginname)
         * @return array the Extbase framework configuration
         */
-       public function getFrameworkConfiguration($pluginConfiguration) {
-               $frameworkConfiguration = array();
-               $frameworkConfiguration['persistence']['storagePid'] = self::DEFAULT_BACKEND_STORAGE_PID;
+       public function getConfiguration($extensionName = NULL, $pluginName = NULL) {
+               // 1st level cache
+               if ($extensionName !== NULL) {
+                       if ($pluginName === NULL) {
+                               throw new Tx_Extbase_Configuration_Exception('You\'ll have to specify either both, extensionName and pluginName, or neither.', 1289852422);
+                       }
+                       $configurationCacheKey = strtolower($extensionName . '_' . $pluginName);
+               } else {
+                       $configurationCacheKey = strtolower($this->extensionName . '_' . $this->pluginName);
+               }
+               if (isset($this->configurationCache[$configurationCacheKey])) {
+                       return $this->configurationCache[$configurationCacheKey];
+               }
 
-               $setup = $this->loadTypoScriptSetup();
-               $extbaseConfiguration = $setup['config.']['tx_extbase.'];
-               if (is_array($extbaseConfiguration)) {
-                       $extbaseConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($extbaseConfiguration);
-                       $frameworkConfiguration = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration, $extbaseConfiguration);
+               $frameworkConfiguration = $this->getExtbaseConfiguration();
+               if (!isset($frameworkConfiguration['persistence']['storagePid'])) {
+                       $frameworkConfiguration['persistence']['storagePid'] = self::DEFAULT_BACKEND_STORAGE_PID;
                }
 
-               if (isset($pluginConfiguration['settings'])) {
-                       $pluginConfiguration = $this->resolveTyposcriptReference($pluginConfiguration, 'settings');
+               if ($extensionName !== NULL) {
+                       $pluginConfiguration = $this->getPluginConfiguration($extensionName, $pluginName);
+                       $pluginConfiguration['controllerConfiguration'] = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName][$pluginName]['controllers'];
+               } else {
+                       $pluginConfiguration = $this->getPluginConfiguration($this->extensionName, $this->pluginName);
+                       $pluginConfiguration = t3lib_div::array_merge_recursive_overrule($pluginConfiguration, $this->configuration);
+                       $pluginConfiguration['controllerConfiguration'] = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$this->extensionName][$this->pluginName]['controllers'];
+                       if (isset($this->configuration['switchableControllerActions'])) {
+                               $this->overrideSwitchableControllerActions($pluginConfiguration, $this->configuration['switchableControllerActions']);
+                       }
                }
-               if (!is_array($pluginConfiguration['settings.'])) $pluginConfiguration['settings.'] = array(); // We expect that the settings are arrays on various places
-               if (isset($pluginConfiguration['persistence'])) {
-                       $pluginConfiguration = $this->resolveTyposcriptReference($pluginConfiguration, 'persistence');
+               $frameworkConfiguration = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration, $pluginConfiguration);
+
+               // only load context specific configuration when retrieving configuration of the current plugin
+               if ($extensionName === NULL || ($extensionName === $this->extensionName && $pluginName === $this->pluginName)) {
+                       $frameworkConfiguration = $this->getContextSpecificFrameworkConfiguration($frameworkConfiguration);
                }
-               if (isset($pluginConfiguration['view'])) {
-                       $pluginConfiguration = $this->resolveTyposcriptReference($pluginConfiguration, 'view');
+
+               // 1st level cache
+               $this->configurationCache[$configurationCacheKey] = $frameworkConfiguration;
+               return $frameworkConfiguration;
+       }
+
+       /**
+        * Returns the TypoScript configuration found in config.tx_extbase
+        *
+        * @return array
+        */
+       protected function getExtbaseConfiguration() {
+               $setup = $this->getTypoScriptSetup();
+               $extbaseConfiguration = array();
+               if (isset($setup['config.']['tx_extbase.'])) {
+                       $extbaseConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($setup['config.']['tx_extbase.']);
                }
-               if (isset($pluginConfiguration['_LOCAL_LANG'])) {
-                       $pluginConfiguration = $this->resolveTyposcriptReference($pluginConfiguration, '_LOCAL_LANG');
+               return $extbaseConfiguration;
+       }
+
+       /**
+        * Returns the TypoScript configuration found in plugin.tx_yourextension_yourplugin
+        * merged with the global configuration of your extension from plugin.tx_yourextension
+        *
+        * @param string $extensionName
+        * @param string $pluginName
+        * @return array
+        */
+       protected function getPluginConfiguration($extensionName, $pluginName) {
+               $setup = $this->getTypoScriptSetup();
+               $pluginConfiguration = array();
+               if (is_array($setup['plugin.']['tx_' . strtolower($extensionName) . '.'])) {
+                       $pluginConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . strtolower($extensionName) . '.']);
                }
-               $frameworkConfiguration = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration, Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($pluginConfiguration));
+               $pluginSignature = strtolower($extensionName . '_' . $pluginName);
+               if (is_array($setup['plugin.']['tx_' . $pluginSignature . '.'])) {
+                       $pluginConfiguration = t3lib_div::array_merge_recursive_overrule($pluginConfiguration, Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($setup['plugin.']['tx_' . $pluginSignature . '.']));
+               }
+               return $pluginConfiguration;
+       }
 
-               $frameworkConfiguration = $this->getContextSpecificFrameworkConfiguration($frameworkConfiguration);
-               return $frameworkConfiguration;
+       /**
+        * @param array $frameworkConfiguration
+        * @param array $overriddenSwitchableControllerActions in the format array('Controller1' => array('action1', 'action2'), 'Controller2' => ...)
+        * @return void
+        */
+       protected function overrideSwitchableControllerActions(array &$frameworkConfiguration, array $switchableControllerActions) {
+               $overriddenSwitchableControllerActions = array();
+               foreach ($switchableControllerActions as $controllerName => $actions) {
+                       $overriddenSwitchableControllerActions[$controllerName] = array('actions' => $actions);
+                       $nonCacheableActions = $frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'];
+                       $overriddenNonCacheableActions = array_intersect($nonCacheableActions, $actions);
+                       if (!empty($overriddenNonCacheableActions)) {
+                               $overriddenSwitchableControllerActions[$controllerName]['nonCacheableActions'] = $overriddenNonCacheableActions;
+                       }
+               }
+               $frameworkConfiguration['controllerConfiguration'] = $overriddenSwitchableControllerActions;
        }
 
        /**
@@ -108,34 +226,13 @@ abstract class Tx_Extbase_Configuration_AbstractConfigurationManager {
         * @param array $frameworkConfiguration The framework configuration until now
         * @return array context specific configuration which will override the configuration obtained by TypoScript
         */
-       abstract protected function getContextSpecificFrameworkConfiguration($frameworkConfiguration);
+       abstract protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration);
 
        /**
         * Returns TypoScript Setup array from current Environment.
         *
         * @return array the TypoScript setup
         */
-       abstract public function loadTypoScriptSetup();
-
-       /**
-        * Resolves the TypoScript reference for $pluginConfiguration[$setting].
-        * In case the setting is a string and starts with "<", we know that this is a TypoScript reference which
-        * needs to be resolved separately.
-        *
-        * @param array $pluginConfiguration The whole plugin configuration
-        * @param string $setting The key inside the $pluginConfiguration to check
-        * @return array The modified plugin configuration
-        */
-       protected function resolveTyposcriptReference($pluginConfiguration, $setting) {
-               if (is_string($pluginConfiguration[$setting]) && substr($pluginConfiguration[$setting], 0, 1) === '<') {
-                       $key = trim(substr($pluginConfiguration[$setting], 1));
-                       $setup = $this->loadTypoScriptSetup();
-                       list(, $newValue) = $this->typoScriptParser->getVal($key, $setup);
-
-                       unset($pluginConfiguration[$setting]);
-                       $pluginConfiguration[$setting . '.'] = $newValue;
-               }
-               return $pluginConfiguration;
-       }
+       abstract protected function getTypoScriptSetup();
 }
 ?>
\ No newline at end of file
index 5a05f19..d17b855 100644 (file)
@@ -29,7 +29,7 @@
  * @subpackage Configuration
  * @version $ID:$
  */
-class Tx_Extbase_Configuration_BackendConfigurationManager extends Tx_Extbase_Configuration_AbstractConfigurationManager implements t3lib_Singleton {
+class Tx_Extbase_Configuration_BackendConfigurationManager extends Tx_Extbase_Configuration_AbstractConfigurationManager {
 
        /**
         * @var array
@@ -39,9 +39,9 @@ class Tx_Extbase_Configuration_BackendConfigurationManager extends Tx_Extbase_Co
        /**
         * Returns TypoScript Setup array from current Environment.
         *
-        * @return array the TypoScript setup
+        * @return array the raw TypoScript setup
         */
-       public function loadTypoScriptSetup() {
+       public function getTypoScriptSetup() {
                if ($this->typoScriptSetupCache === NULL) {
                        $template = t3lib_div::makeInstance('t3lib_TStemplate');
                                // do not log time-performance information
@@ -91,7 +91,7 @@ class Tx_Extbase_Configuration_BackendConfigurationManager extends Tx_Extbase_Co
         * We do not want to override anything in the backend.
         * @return array
         */
-       protected function getContextSpecificFrameworkConfiguration($frameworkConfiguration) {
+       protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration) {
                return $frameworkConfiguration;
        }
 }
diff --git a/typo3/sysext/extbase/Classes/Configuration/ConfigurationManager.php b/typo3/sysext/extbase/Classes/Configuration/ConfigurationManager.php
new file mode 100644 (file)
index 0000000..aac52d6
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A configuration manager following the strategy pattern (GoF315). It hides the concrete
+ * implementation of the configuration manager and provides an unified acccess point.
+ *
+ * Use the shutdown() method to drop the concrete implementation.
+ *
+ * @package Extbase
+ * @subpackage Configuration
+ * @version $ID:$
+ */
+class Tx_Extbase_Configuration_ConfigurationManager implements Tx_Extbase_Configuration_ConfigurationManagerInterface {
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * @var Tx_Extbase_Configuration_AbstractConfigurationManager
+        **/
+       protected $concreteConfigurationManager;
+
+       /**
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+               $this->initializeConcreteConfigurationManager();
+       }
+
+       /**
+        * @return void
+        */
+       protected function initializeConcreteConfigurationManager() {
+               if (TYPO3_MODE === 'FE') {
+                       $this->concreteConfigurationManager = $this->objectManager->get('Tx_Extbase_Configuration_FrontendConfigurationManager');
+               } else {
+                       $this->concreteConfigurationManager = $this->objectManager->get('Tx_Extbase_Configuration_BackendConfigurationManager');
+               }
+       }
+
+       /**
+        * @param tslib_cObj $contentObject
+        * @return void
+        */
+       public function setContentObject(tslib_cObj $contentObject = NULL) {
+               $this->concreteConfigurationManager->setContentObject($contentObject);
+       }
+
+       /**
+        * @return tslib_cObj
+        */
+       public function getContentObject() {
+               return $this->concreteConfigurationManager->getContentObject();
+       }
+
+       /**
+        * Sets the specified raw configuration coming from the outside.
+        * Note that this is a low level method and only makes sense to be used by Extbase internally.
+        *
+        * @param array $configuration The new configuration
+        * @return void
+        */
+       public function setConfiguration(array $configuration = array()) {
+               $this->concreteConfigurationManager->setConfiguration($configuration);
+       }
+
+       /**
+        * Returns the specified configuration.
+        * The actual configuration will be merged from different sources in a defined order.
+        *
+        * Note that this is a low level method and only makes sense to be used by Extbase internally.
+        *
+        * @param string $configurationType The kind of configuration to fetch - must be one of the CONFIGURATION_TYPE_* constants
+        * @param string $extensionName if specified, the configuration for the given extension will be returned.
+        * @param string $pluginName if specified, the configuration for the given plugin will be returned.
+        * @return array The configuration
+        */
+       public function getConfiguration($configurationType, $extensionName = NULL, $pluginName = NULL) {
+               switch ($configurationType) {
+                       case self::CONFIGURATION_TYPE_SETTINGS :
+                               $configuration = $this->concreteConfigurationManager->getConfiguration($extensionName, $pluginName);
+                               return $configuration['settings'];
+                       case self::CONFIGURATION_TYPE_FRAMEWORK :
+                               return $this->concreteConfigurationManager->getConfiguration($extensionName, $pluginName);
+                       case self::CONFIGURATION_TYPE_FULL_TYPOSCRIPT :
+                               return $this->concreteConfigurationManager->getTypoScriptSetup();
+                       default :
+                               throw new Tx_Extbase_Configuration_Exception_InvalidConfigurationTypeException('Invalid configuration type "' . $configurationType . '"', 1206031879);
+               }
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Configuration/ConfigurationManagerInterface.php b/typo3/sysext/extbase/Classes/Configuration/ConfigurationManagerInterface.php
new file mode 100644 (file)
index 0000000..0c28e70
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ *
+ *
+ * @package Extbase
+ * @subpackage Configuration
+ * @version $ID:$
+ */
+interface Tx_Extbase_Configuration_ConfigurationManagerInterface extends t3lib_Singleton {
+
+       const CONFIGURATION_TYPE_FRAMEWORK = 'Framework';
+       const CONFIGURATION_TYPE_SETTINGS = 'Settings';
+       const CONFIGURATION_TYPE_FULL_TYPOSCRIPT = 'FullTypoScript';
+
+       /**
+        * @param tslib_cObj $contentObject
+        * @return void
+        */
+       public function setContentObject(tslib_cObj $contentObject = NULL);
+
+       /**
+        * @return tslib_cObj
+        */
+       public function getContentObject();
+
+       /**
+        * Returns the specified configuration.
+        * The actual configuration will be merged from different sources in a defined order.
+        *
+        * Note that this is a low level method and only makes sense to be used by Extbase internally.
+        *
+        * @param string $configurationType The kind of configuration to fetch - must be one of the CONFIGURATION_TYPE_* constants
+        * @return array The configuration
+        */
+       public function getConfiguration($configurationType);
+
+       /**
+        * Sets the specified raw configuration coming from the outside.
+        * Note that this is a low level method and only makes sense to be used by Extbase internally.
+        *
+        * @param array $configuration The new configuration
+        * @return void
+        */
+       public function setConfiguration(array $configuration = array());
+
+}
+?>
\ No newline at end of file
index ad03677..fb7cda8 100644 (file)
 class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_Configuration_AbstractConfigurationManager {
 
        /**
-        * @var tslib_cObj
-        */
-       protected $contentObject;
-
-       /**
-        * @param tslib_cObj $contentObject
-        * @return void
-        */
-       public function setContentObject(tslib_cObj $contentObject) {
-               $this->contentObject = $contentObject;
-       }
-
-       /**
         * Returns TypoScript Setup array from current Environment.
         *
-        * @return array the TypoScript setup
+        * @return array the raw TypoScript setup
         */
-       public function loadTypoScriptSetup() {
+       public function getTypoScriptSetup() {
                return $GLOBALS['TSFE']->tmpl->setup;
        }
 
@@ -63,7 +50,7 @@ class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_C
         * @param array $frameworkConfiguration The framework configuration to modify
         * @return array the modified framework configuration
         */
-       protected function getContextSpecificFrameworkConfiguration($frameworkConfiguration) {
+       protected function getContextSpecificFrameworkConfiguration(array $frameworkConfiguration) {
                $frameworkConfiguration = $this->overrideStoragePidIfStartingPointIsSet($frameworkConfiguration);
                $frameworkConfiguration = $this->overrideConfigurationFromPlugin($frameworkConfiguration);
                $frameworkConfiguration = $this->overrideConfigurationFromFlexform($frameworkConfiguration);
@@ -78,7 +65,7 @@ class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_C
         * @param array $frameworkConfiguration the framework configurations
         * @return array the framework configuration with overriden storagePid
         */
-       protected function overrideStoragePidIfStartingPointIsSet($frameworkConfiguration) {
+       protected function overrideStoragePidIfStartingPointIsSet(array $frameworkConfiguration) {
                $pages = $this->contentObject->data['pages'];
                if (is_string($pages) && strlen($pages) > 0) {
                        $list = array();
@@ -107,8 +94,9 @@ class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_C
         * @return array the framework configuration with overridden data from typoscript
         */
        protected function overrideConfigurationFromPlugin(array $frameworkConfiguration) {
-               $setup = $this->loadTypoScriptSetup();
-               $pluginConfiguration =  $setup['plugin.']['tx_' . strtolower($frameworkConfiguration['extensionName'] . '_' . $frameworkConfiguration['pluginName']) . '.'];
+               $setup = $this->getTypoScriptSetup();
+               $pluginSignature = strtolower($frameworkConfiguration['extensionName'] . '_' . $frameworkConfiguration['pluginName']);
+               $pluginConfiguration = $setup['plugin.']['tx_' . $pluginSignature . '.'];
                if (is_array($pluginConfiguration)) {
                        $pluginConfiguration = Tx_Extbase_Utility_TypoScript::convertTypoScriptArrayToPlainArray($pluginConfiguration);
                        $frameworkConfiguration = $this->mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $pluginConfiguration, 'settings');
@@ -183,7 +171,7 @@ class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_C
         * @param string $configurationPartName The name of the configuration part which should be merged.
         * @return array the processed framework configuration
         */
-       protected function mergeConfigurationIntoFrameworkConfiguration($frameworkConfiguration, $configuration, $configurationPartName) {
+       protected function mergeConfigurationIntoFrameworkConfiguration(array $frameworkConfiguration, array $configuration, $configurationPartName) {
                if (is_array($frameworkConfiguration[$configurationPartName]) && is_array($configuration[$configurationPartName])) {
                        $frameworkConfiguration[$configurationPartName] = t3lib_div::array_merge_recursive_overrule($frameworkConfiguration[$configurationPartName], $configuration[$configurationPartName]);
                }
@@ -194,48 +182,32 @@ class Tx_Extbase_Configuration_FrontendConfigurationManager extends Tx_Extbase_C
        /**
         * Overrides the switchable controller actions from the flexform.
         *
-        * @param $frameworkConfiguration The original framework configuration
-        * @param $flexformConfiguration The full flexform configuration
+        * @param array $frameworkConfiguration The original framework configuration
+        * @param array $flexformConfiguration The full flexform configuration
         * @return array the modified framework configuration, if needed
         * @todo: Check that the controller has been before inside the switchableControllerActions.
         */
-       protected function overrideSwitchableControllerActionsFromFlexform($frameworkConfiguration, $flexformConfiguration) {
-               if (isset($flexformConfiguration['switchableControllerActions']) && !is_array($flexformConfiguration['switchableControllerActions'])) {
-
-                       // As "," is the flexform field value delimiter, we need to use ";" as in-field delimiter. That's why we need to replace ; by  , first.
-                       $switchableControllerActionPartsFromFlexform = t3lib_div::trimExplode(',', str_replace(';', ',', $flexformConfiguration['switchableControllerActions']));
+       protected function overrideSwitchableControllerActionsFromFlexform(array $frameworkConfiguration, array $flexformConfiguration) {
+               if (!isset($flexformConfiguration['switchableControllerActions']) || is_array($flexformConfiguration['switchableControllerActions'])) {
+                       return $frameworkConfiguration;
+               }
 
-                       $newSwitchableControllerActionsFromFlexform = array();
-                       foreach ($switchableControllerActionPartsFromFlexform as $switchableControllerActionPartFromFlexform) {
-                               list($controller, $action) = explode('->', $switchableControllerActionPartFromFlexform);
-                               if (empty($controller) || empty($action)) {
-                                       throw new Tx_Extbase_Configuration_Exception_ParseError('Controller or action were empty when overriding switchableControllerActions from flexform.', 1257146403);
-                               }
+               // As "," is the flexform field value delimiter, we need to use ";" as in-field delimiter. That's why we need to replace ; by  , first.
+               $switchableControllerActionPartsFromFlexform = t3lib_div::trimExplode(',', str_replace(';', ',', $flexformConfiguration['switchableControllerActions']), TRUE);
 
-                               $newSwitchableControllerActionsFromFlexform[$controller][] = $action;
+               $newSwitchableControllerActionsFromFlexform = array();
+               foreach ($switchableControllerActionPartsFromFlexform as $switchableControllerActionPartFromFlexform) {
+                       list($controller, $action) = explode('->', $switchableControllerActionPartFromFlexform);
+                       if (empty($controller) || empty($action)) {
+                               throw new Tx_Extbase_Configuration_Exception_ParseError('Controller or action were empty when overriding switchableControllerActions from flexform.', 1257146403);
                        }
+                       $newSwitchableControllerActionsFromFlexform[$controller][] = $action;
+               }
 
-                       if (count($newSwitchableControllerActionsFromFlexform)) {
-                               $overriddenSwitchableControllerActions = array();
-                               foreach ($newSwitchableControllerActionsFromFlexform as $controller => $actions) {
-                                       $overriddenSwitchableControllerActions[$controller] = array(
-                                               'controller' => $controller,
-                                               'actions' => implode(',', $actions)
-                                       );
-                                       $nonCacheableActions = t3lib_div::trimExplode(',', $frameworkConfiguration['switchableControllerActions'][$controller]['nonCacheableActions']);
-                                       $overriddenNonCacheableActions = array_intersect($nonCacheableActions, $actions);
-                                       if (!empty($overriddenNonCacheableActions)) {
-                                               $overriddenSwitchableControllerActions[$controller]['nonCacheableActions'] = implode(',', $overriddenNonCacheableActions);
-                                       }
-                               }
-                               $frameworkConfiguration['switchableControllerActions'] = $overriddenSwitchableControllerActions;
-
-                               // We want the first controller/action be the default.
-                               unset($frameworkConfiguration['controller']);
-                               unset($frameworkConfiguration['action']);
-                       }
+               if (count($newSwitchableControllerActionsFromFlexform)) {
+                       $this->overrideSwitchableControllerActions($frameworkConfiguration, $newSwitchableControllerActionsFromFlexform);
                }
                return $frameworkConfiguration;
        }
 }
-?>
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Core/Bootstrap.php b/typo3/sysext/extbase/Classes/Core/Bootstrap.php
new file mode 100644 (file)
index 0000000..709f0ff
--- /dev/null
@@ -0,0 +1,296 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Creates a request an dispatches it to the controller which was specified
+ * by TS Setup, Flexform and returns the content to the v4 framework.
+ *
+ * This class is the main entry point for extbase extensions.
+ *
+ * @package Extbase
+ * @version $ID:$
+ */
+class Tx_Extbase_Core_Bootstrap {
+
+       /**
+        * Back reference to the parent content object
+        * This has to be public as it is set directly from TYPO3
+        *
+        * @var tslib_cObj
+        */
+       public $cObj;
+
+       /**
+        * The application context
+        * @var string
+        */
+       protected $context;
+
+       /**
+        * @var Tx_Extbase_Configuration_ConfigurationManager
+        */
+       protected $configurationManager;
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * @var t3lib_cache_Manager
+        */
+       protected $cacheManager;
+
+       /**
+        * @var Tx_Extbase_Reflection_Service
+        */
+       protected $reflectionService;
+
+       /**
+        * @var Tx_Extbase_Persistence_Manager
+        */
+       protected $persistenceManager;
+
+       /**
+        * @var boolean
+        */
+       protected $isInitialized = FALSE;
+
+       /**
+        * Explicitly initializes all necessary Extbase objects by invoking the various initialize* methods.
+        *
+        * Usually this method is only called from unit tests or other applications which need a more fine grained control over
+        * the initialization and request handling process. Most other applications just call the run() method.
+        *
+        * @param array $configuration The TS configuration array
+        * @return void
+        * @see run()
+        * @api
+        */
+       public function initialize($configuration) {
+               $this->initializeClassLoader();
+               $this->initializeObjectManager();
+               $this->initializeConfiguration($configuration);
+               $this->configureObjectManager();
+               $this->initializeCache();
+               $this->initializeReflection();
+               $this->initializePersistence();
+               $this->initializeBackwardsCompatibility();
+               $this->isInitialized = TRUE;
+       }
+
+       /**
+        * Initializes the autoload mechanism of Extbase. This is supplement to the core autoloader.
+        *
+        * @return void
+        * @see initialize()
+        */
+       protected function initializeClassLoader() {
+               if (!class_exists('Tx_Extbase_Utility_ClassLoader', FALSE)) {
+                       require(t3lib_extmgm::extPath('extbase') . 'Classes/Utility/ClassLoader.php');
+               }
+
+               $classLoader = new Tx_Extbase_Utility_ClassLoader();
+               spl_autoload_register(array($classLoader, 'loadClass'));
+       }
+
+       /**
+        * Initializes the Object framework.
+        *
+        * @return void
+        * @see initialize()
+        */
+       protected function initializeObjectManager() {
+               $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
+       }
+
+       /**
+        * Initializes the Object framework.
+        *
+        * @return void
+        * @see initialize()
+        */
+       public function initializeConfiguration($configuration) {
+               $this->configurationManager = $this->objectManager->get('Tx_Extbase_Configuration_ConfigurationManagerInterface');
+               $contentObject = isset($this->cObj) ? $this->cObj : t3lib_div::makeInstance('tslib_cObj');
+               $this->configurationManager->setContentObject($contentObject);
+               $this->configurationManager->setConfiguration($configuration);
+       }
+
+       /**
+        * Configures the object manager object configuration from
+        * config.tx_extbase.objects
+        *
+        * @return void
+        * @see initialize()
+        */
+       public function configureObjectManager() {
+               $typoScriptSetup = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
+               if (isset($typoScriptSetup['config.']['tx_extbase.']['objects.']) && is_array($typoScriptSetup['config.']['tx_extbase.']['objects.'])) {
+                       $objectConfiguration = $typoScriptSetup['config.']['tx_extbase.']['objects.'];
+
+                       foreach ($objectConfiguration as $classNameWithDot => $classConfiguration) {
+                               if (isset($classConfiguration['className'])) {
+                                       $originalClassName = substr($classNameWithDot, 0, -1);
+                                       Tx_Extbase_Object_Container_Container::getContainer()->registerImplementation($originalClassName, $classConfiguration['className']);
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Initializes the cache framework
+        *
+        * @return void
+        * @see initialize()
+        */
+       protected function initializeCache() {
+               t3lib_cache::initializeCachingFramework();
+               $this->cacheManager = $GLOBALS['typo3CacheManager'];
+               try {
+                       $this->cacheManager->getCache('cache_extbase_reflection');
+               } catch (t3lib_cache_exception_NoSuchCache $exception) {
+                       $GLOBALS['typo3CacheFactory']->create(
+                               'cache_extbase_reflection',
+                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['frontend'],
+                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['backend'],
+                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['options']
+                       );
+               }
+       }
+
+       /**
+        * Initializes the Reflection Service
+        *
+        * @return void
+        * @see initialize()
+        */
+       protected function initializeReflection() {
+               $this->reflectionService = $this->objectManager->get('Tx_Extbase_Reflection_Service');
+               $this->reflectionService->setDataCache($this->cacheManager->getCache('cache_extbase_reflection'));
+               $this->reflectionService->initialize();
+       }
+
+       /**
+        * Initializes the persistence framework
+        *
+        * @return void
+        * @see initialize()
+        */
+       public function initializePersistence() {
+               $this->persistenceManager = $this->objectManager->get('Tx_Extbase_Persistence_Manager'); // singleton
+       }
+
+       /**
+        * Initializes the backwards compatibility. This is necessary because the
+        * old Dispatcher provided several static methods.
+        *
+        * @return void
+        * @see initialize()
+        */
+       protected function initializeBackwardsCompatibility() {
+               $dispatcher = t3lib_div::makeInstance('Tx_Extbase_Dispatcher');
+               $dispatcher->injectConfigurationManager($this->configurationManager);
+               $dispatcher->injectPersistenceManager($this->persistenceManager);
+       }
+
+       /**
+        * Runs the the Extbase Framework by resolving an appropriate Request Handler and passing control to it.
+        * If the Framework is not initialized yet, it will be initialized.
+        *
+        * @param string $content The content
+        * @param array $configuration The TS configuration array
+        * @return string $content The processed content
+        * @api
+        */
+       public function run($content, $configuration) {
+               //var_dump(Tx_Extbase_Utility_Extension::createAutoloadRegistryForExtension('extbase', t3lib_extMgm::extPath('extbase'), array(
+               //      'tx_extbase_basetestcase' => '$extensionClassesPath . \'../Tests/BaseTestCase.php\''
+               //)));
+               //die("autoload registry");
+
+               $this->initialize($configuration);
+
+               $requestHandlerResolver = $this->objectManager->get('Tx_Extbase_MVC_RequestHandlerResolver');
+               $requestHandler = $requestHandlerResolver->resolveRequestHandler();
+
+               $response = $requestHandler->handleRequest();
+
+               // If response is NULL after handling the request we need to stop
+               // This happens for instance, when a USER object was converted to a USER_INT
+               // @see Tx_Extbase_MVC_Web_FrontendRequestHandler::handleRequest()
+               if ($response === NULL) {
+                       $this->reflectionService->shutdown();
+                       return;
+               }
+               if (count($response->getAdditionalHeaderData()) > 0) {
+                       $GLOBALS['TSFE']->additionalHeaderData[] = implode(chr(10), $response->getAdditionalHeaderData());
+               }
+               $response->sendHeaders();
+               $content = $response->getContent();
+
+               $this->resetSingletons();
+               return $content;
+       }
+
+       /**
+        * Resets global singletons for the next plugin
+        *
+        * @return void
+        */
+       protected function resetSingletons() {
+               $this->persistenceManager->persistAll();
+               $this->objectManager->get('Tx_Extbase_MVC_Controller_FlashMessages')->persist();
+               $this->reflectionService->shutdown();
+       }
+
+        /**
+         * This method forwards the call to run(). This method is invoked by the mod.php
+         * function of TYPO3.
+         *
+         * @return TRUE
+         * @see run()
+         **/
+       public function callModule($moduleName) {
+
+               // Check permissions and exit if the user has no permission for entry
+               $GLOBALS['BE_USER']->modAccess($config, TRUE);
+               if (t3lib_div::_GP('id')) {
+                       // Check page access
+                       $id = intval(t3lib_div::_GP('id'));
+                       $permClause = $GLOBALS['BE_USER']->getPagePermsClause(TRUE);
+                       $access = is_array(t3lib_BEfunc::readPageAccess($id, $permClause));
+                       if (!$access) {
+                               t3lib_BEfunc::typo3PrintError('No Access', 'You don\'t have access to this page', 0);
+                       }
+               }
+
+
+               $configuration = array();
+               $configuration['module.']['tx_extbase.']['moduleName'] = $moduleName;
+               $this->run('', $configuration);
+               return TRUE;
+       }
+}
+?>
\ No newline at end of file
index 226edae..d888046 100644 (file)
 ***************************************************************/
 
 /**
- * Creates a request an dispatches it to the controller which was specified
- * by TS Setup, Flexform and returns the content to the v4 framework.
+ * This class was the main entry point for extbase extensions before v1.3.0. It was replaced by the class
+ * Tx_Extbase_Bootstrap in combination with the class Tx_Extbase_MVC_Dispatcher to separate responsibilities.
  *
- * This class is the main entry point for extbase extensions.
+ * The use of static functions is deprecated since 1.3.0 and will be removed in 1.5.0.
  *
  * @package Extbase
  * @version $ID:$
+ * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
+ * @see Tx_Extbase_Bootstrap, Tx_Extbase_MVC_Dispatcher
  */
 class Tx_Extbase_Dispatcher {
 
        /**
-        * Back reference to the parent content object
-        * This has to be public as it is set directly from TYPO3
-        *
-        * @var tslib_cObj
-        */
-       public $cObj;
-
-       /**
-        * @var Tx_Extbase_Utility_ClassLoader
-        */
-       protected $classLoader;
-
-       /**
-        * @var Tx_Extbase_Configuration_AbstractConfigurationManager
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
         */
        protected static $configurationManager;
 
        /**
-        * @var t3lib_cache_Manager
-        */
-       protected $cacheManager;
-
-       /**
-        * @var Tx_Extbase_Reflection_Service
-        */
-       protected static $reflectionService;
-
-       /**
         * @var Tx_Extbase_Persistence_Manager
         */
        protected static $persistenceManager;
 
        /**
-        * The configuration for the Extbase framework
-        * @var array
-        */
-       protected static $extbaseFrameworkConfiguration;
-
-
-       /**
-        * Constructs this Dispatcher and registers the autoloader
-        */
-       public function __construct() {
-               t3lib_cache::initializeCachingFramework();
-               $this->initializeClassLoader();
-               $this->initializeCache();
-               $this->initializeReflection();
-       }
-
-       /**
-        * Creates a request an dispatches it to a controller.
-        *
-        * @param string $content The content
-        * @param array $configuration The TS configuration array
-        * @return string $content The processed content
-        */
-       public function dispatch($content, $configuration) {
-               // FIXME Remove the next lines. These are only there to generate the ext_autoload.php file
-               //$extutil = new Tx_Extbase_Utility_Extension;
-               //$extutil->createAutoloadRegistryForExtension('extbase', t3lib_extMgm::extPath('extbase'));
-               //$extutil->createAutoloadRegistryForExtension('fluid', t3lib_extMgm::extPath('fluid'));
-
-               $this->timeTrackPush('Extbase is called.','');
-               $this->timeTrackPush('Extbase gets initialized.','');
-
-               if (!is_array($configuration)) {
-                       t3lib_div::sysLog('Extbase was not able to dispatch the request. No configuration.', 'extbase', t3lib_div::SYSLOG_SEVERITY_ERROR);
-                       return $content;
-               }
-
-               $this->initializeConfigurationManagerAndFrameworkConfiguration($configuration);
-
-               $requestBuilder = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_RequestBuilder');
-               $request = $requestBuilder->initialize(self::$extbaseFrameworkConfiguration);
-               $request = $requestBuilder->build();
-               if (isset($this->cObj->data) && is_array($this->cObj->data)) {
-                       // we need to check the above conditions as cObj is not available in Backend.
-                       $request->setContentObjectData($this->cObj->data);
-                       if ($this->isCacheable($request->getControllerName(), $request->getControllerActionName())) {
-                               $request->setIsCached(TRUE);
-                       } else {
-                               if ($this->cObj->getUserObjectType() === tslib_cObj::OBJECTTYPE_USER) {
-                                       $this->cObj->convertToUserIntObject();
-                                       // tslib_cObj::convertToUserIntObject() will recreate the object, so we have to stop the request here
-                                       return;
-                               }
-                               $request->setIsCached(FALSE);
-                       }
-               }
-               $response = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Response');
-
-               // Request hash service
-               $requestHashService = t3lib_div::makeInstance('Tx_Extbase_Security_Channel_RequestHashService'); // singleton
-               $requestHashService->verifyRequest($request);
-
-               $persistenceManager = self::getPersistenceManager();
-
-               $this->timeTrackPull();
-
-               $this->timeTrackPush('Extbase dispatches request.','');
-               $dispatchLoopCount = 0;
-               while (!$request->isDispatched()) {
-                       if ($dispatchLoopCount++ > 99) throw new Tx_Extbase_MVC_Exception_InfiniteLoop('Could not ultimately dispatch the request after '  . $dispatchLoopCount . ' iterations.', 1217839467);
-                       $controller = $this->getPreparedController($request);
-                       try {
-                               $controller->processRequest($request, $response);
-                       } catch (Tx_Extbase_MVC_Exception_StopAction $ignoredException) {
-                       }
-               }
-               $this->timeTrackPull();
-
-               $this->timeTrackPush('Extbase persists all changes.','');
-               $flashMessages = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_FlashMessages'); // singleton
-               $flashMessages->persist();
-               $persistenceManager->persistAll();
-               $this->timeTrackPull();
-
-               self::$reflectionService->shutdown();
-
-               if (count($response->getAdditionalHeaderData()) > 0) {
-                       $GLOBALS['TSFE']->additionalHeaderData[$request->getControllerExtensionName()] = implode("\n", $response->getAdditionalHeaderData());
-               }
-               $response->sendHeaders();
-               $this->timeTrackPull();
-               return $response->getContent();
-       }
-
-       /**
-        * Determines whether the current action can be cached
-        *
-        * @param string $controllerName
-        * @param string $actionName
-        * @return boolean TRUE if the given action should be cached, otherwise FALSE
-        */
-       protected function isCacheable($controllerName, $actionName) {
-               if (isset(self::$extbaseFrameworkConfiguration['switchableControllerActions'][$controllerName]['nonCacheableActions'])
-                       && in_array($actionName, t3lib_div::trimExplode(',', self::$extbaseFrameworkConfiguration['switchableControllerActions'][$controllerName]['nonCacheableActions']))) {
-                               return FALSE;
-               }
-               return TRUE;
-       }
-
-       /**
-        * Initializes the autoload mechanism of Extbase. This is supplement to the core autoloader.
+        * Injects the Configuration Manager
         *
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface An instance of the Configuration Manager
         * @return void
         */
-       protected function initializeClassLoader() {
-               if (!class_exists('Tx_Extbase_Utility_ClassLoader')) {
-                       require(t3lib_extmgm::extPath('extbase') . 'Classes/Utility/ClassLoader.php');
-               }
-
-               $classLoader = new Tx_Extbase_Utility_ClassLoader();
-               spl_autoload_register(array($classLoader, 'loadClass'));
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               self::$configurationManager = $configurationManager;
        }
 
        /**
-        * Initializes the configuration manager and the Extbase settings
+        * Injects the Persistence Manager
         *
-        * @param $configuration The current incoming configuration
+        * @param Tx_Extbase_Persistence_Manager An instance of the Persistence Manager
         * @return void
         */
-       protected function initializeConfigurationManagerAndFrameworkConfiguration($configuration) {
-               if (TYPO3_MODE === 'FE') {
-                       self::$configurationManager = t3lib_div::makeInstance('Tx_Extbase_Configuration_FrontendConfigurationManager');
-                       self::$configurationManager->setContentObject($this->cObj);
-               } else {
-                       self::$configurationManager = t3lib_div::makeInstance('Tx_Extbase_Configuration_BackendConfigurationManager');
-               }
-               self::$extbaseFrameworkConfiguration = self::$configurationManager->getFrameworkConfiguration($configuration);
-       }
-
-       /**
-        * Initializes the cache framework
-        *
-        * @return void
-        */
-       protected function initializeCache() {
-               $this->cacheManager = $GLOBALS['typo3CacheManager'];
-               try {
-                       $this->cacheManager->getCache('cache_extbase_reflection');
-               } catch (t3lib_cache_exception_NoSuchCache $exception) {
-                       $GLOBALS['typo3CacheFactory']->create(
-                               'cache_extbase_reflection',
-                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['frontend'],
-                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['backend'],
-                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['options']
-                       );
-               }
-       }
-
-       /**
-        * Initializes the Reflection Service
-        *
-        * @return void
-        */
-       protected function initializeReflection() {
-               self::$reflectionService = t3lib_div::makeInstance('Tx_Extbase_Reflection_Service');
-               self::$reflectionService->setCache($this->cacheManager->getCache('cache_extbase_reflection'));
-               if (!self::$reflectionService->isInitialized()) {
-                       self::$reflectionService->initialize();
-               }
-       }
-
-       /**
-        * Builds and returns a controller
-        *
-        * @param Tx_Extbase_MVC_Web_Request $request
-        * @return Tx_Extbase_MVC_Controller_ControllerInterface The prepared controller
-        */
-       protected function getPreparedController(Tx_Extbase_MVC_Web_Request $request) {
-               $controllerObjectName = $request->getControllerObjectName();
-               $controller = t3lib_div::makeInstance($controllerObjectName);
-               if (!$controller instanceof Tx_Extbase_MVC_Controller_ControllerInterface) {
-                       throw new Tx_Extbase_MVC_Exception_InvalidController('Invalid controller "' . $request->getControllerObjectName() . '". The controller must implement the Tx_Extbase_MVC_Controller_ControllerInterface.', 1202921619);
-               }
-               $propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper');
-               $propertyMapper->injectReflectionService(self::$reflectionService);
-               $controller->injectPropertyMapper($propertyMapper);
-
-               $controller->injectSettings(is_array(self::$extbaseFrameworkConfiguration['settings']) ? self::$extbaseFrameworkConfiguration['settings'] : array());
-
-               $flashMessageContainer = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_FlashMessages'); // singleton
-               $flashMessageContainer->reset();
-               $controller->injectFlashMessageContainer($flashMessageContainer);
-
-               $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager');
-               $validatorResolver = t3lib_div::makeInstance('Tx_Extbase_Validation_ValidatorResolver');
-               $validatorResolver->injectObjectManager($objectManager);
-               $validatorResolver->injectReflectionService(self::$reflectionService);
-               $controller->injectValidatorResolver($validatorResolver);
-               $controller->injectReflectionService(self::$reflectionService);
-               $controller->injectObjectManager($objectManager);
-               return $controller;
-       }
-
-       /**
-        * This function prepares and returns the Persistance Manager
-        *
-        * @return Tx_Extbase_Persistence_Manager A (singleton) instance of the Persistence Manager
-        */
-       public static function getPersistenceManager() {
-               if (self::$persistenceManager === NULL) {
-                       $identityMap = t3lib_div::makeInstance('Tx_Extbase_Persistence_IdentityMap');
-                       $persistenceSession = t3lib_div::makeInstance('Tx_Extbase_Persistence_Session'); // singleton
-
-                       $dataMapFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapFactory');
-                       $dataMapFactory->injectReflectionService(self::$reflectionService);
-
-                       $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper'); // singleton
-                       $dataMapper->injectIdentityMap($identityMap);
-                       $dataMapper->injectSession($persistenceSession);
-                       $dataMapper->injectReflectionService(self::$reflectionService);
-                       $dataMapper->injectDataMapFactory($dataMapFactory);
-
-                       $storageBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Storage_Typo3DbBackend', $GLOBALS['TYPO3_DB']); // singleton
-                       $storageBackend->injectDataMapper($dataMapper);
-
-                       $qomFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_QueryObjectModelFactory', $storageBackend);
-
-                       $dataMapper->setQomFactory($qomFactory);
-
-                       $persistenceBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Backend', $persistenceSession, $storageBackend); // singleton
-                       $persistenceBackend->injectDataMapper($dataMapper);
-                       $persistenceBackend->injectIdentityMap($identityMap);
-                       $persistenceBackend->injectReflectionService(self::$reflectionService);
-                       $persistenceBackend->injectQueryFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory'));
-                       $persistenceBackend->injectQomFactory($qomFactory);
-
-                       $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager'); // singleton
-
-                       $persistenceManager = t3lib_div::makeInstance('Tx_Extbase_Persistence_Manager'); // singleton
-                       $persistenceManager->injectBackend($persistenceBackend);
-                       $persistenceManager->injectSession($persistenceSession);
-                       $persistenceManager->injectObjectManager($objectManager);
-
-                       self::$persistenceManager = $persistenceManager;
-               }
-
-               return self::$persistenceManager;
+       public function injectPersistenceManager(Tx_Extbase_Persistence_Manager $persistenceManager) {
+               self::$persistenceManager = $persistenceManager;
        }
 
        /**
-        * This function returns the Configuration Manager. It is instanciated for
-        * each call to dispatch() only once.
+        * Returns the Configuration Manager.
         *
         * @return Tx_Extbase_Configuration_Manager An instance of the Configuration Manager
+        * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
         */
-       public static function getConfigurationManager() {
+       static public function getConfigurationManager() {
+               t3lib_div::logDeprecatedFunction();
                return self::$configurationManager;
        }
 
        /**
-        * This function returns the settings of Extbase
-        *
-        * @return array The settings
-        */
-       public static function getExtbaseFrameworkConfiguration() {
-               return self::$extbaseFrameworkConfiguration;
-       }
-
-       /**
-        * Calls an Extbase Backend module.
+        * Returns the Persistance Manager
         *
-        * @param string $module The name of the module
-        * @return void
-        */
-       public function callModule($module) {
-               if (isset($GLOBALS['TBE_MODULES']['_configuration'][$module])) {
-                       $config = $GLOBALS['TBE_MODULES']['_configuration'][$module];
-
-                       // Check permissions and exit if the user has no permission for entry
-                       $GLOBALS['BE_USER']->modAccess($config, TRUE);
-                       if (t3lib_div::_GP('id')) {
-                               // Check page access
-                               $id = t3lib_div::_GP('id');
-                               $permClause = $GLOBALS['BE_USER']->getPagePermsClause(TRUE);
-                               $access = is_array(t3lib_BEfunc::readPageAccess($id, $permClause));
-                               if (!$access) {
-                                       t3lib_BEfunc::typo3PrintError('No Access', 'You don\'t have access to this page', 0);
-                               }
-                       }
-
-                       // Resolve the controller/action to use
-                       $controllerAction = $this->resolveControllerAction($module);
-
-                       // As for SCbase modules, output of the controller/action pair should be echoed
-                       echo $this->transfer($module, $controllerAction['controllerName'], $controllerAction['actionName']);
-                       return TRUE;
-               } else {
-                       return FALSE;
-               }
-       }
-
-       /**
-        * Resolves the controller and action to use for current call.
-        * This takes into account any function menu that has being called.
-        *
-        * @param string $module The name of the module
-        * @return array The controller/action pair to use for current call
+        * @return Tx_Extbase_Persistence_Manager An instance of the Persistence Manager
+        * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
         */
-       protected function resolveControllerAction($module) {
-               $configuration = $GLOBALS['TBE_MODULES']['_configuration'][$module];
-               $fallbackControllerAction = $this->getFallbackControllerAction($configuration);
-
-                       // Extract dispatcher settings from request
-               $argumentPrefix = strtolower('tx_' . $configuration['extensionName'] . '_' . $configuration['name']);
-               $dispatcherParameters = t3lib_div::_GPmerged($argumentPrefix);
-               $dispatcherControllerAction = $this->getDispatcherControllerAction($configuration, $dispatcherParameters);
-
-                       // Extract module function settings from request
-               $moduleFunctionControllerAction = $this->getModuleFunctionControllerAction($module, $fallbackControllerAction['controllerName']);
-
-                       // Dispatcher controller/action has precedence over default controller/action
-               $controllerAction = t3lib_div::array_merge_recursive_overrule($fallbackControllerAction, $dispatcherControllerAction, FALSE, FALSE);
-                       // Module function controller/action has precedence
-               $controllerAction = t3lib_div::array_merge_recursive_overrule($controllerAction, $moduleFunctionControllerAction, FALSE, FALSE);
-
-               return $controllerAction;
-       }
-
-       /**
-        * Returns the fallback controller/action pair to be used when request does not contain
-        * any controller/action to be used or the provided parameters are not valid.
-        *
-        * @param array $configuration The module configuration
-        * @return array The controller/action pair
-        */
-       protected function getFallbackControllerAction($configuration) {
-                       // Extract module settings from its registration in ext_tables.php
-               $controllers = array_keys($configuration['controllerActions']);
-               $defaultController = array_shift($controllers);
-               $actions = t3lib_div::trimExplode(',', $configuration['controllerActions'][$defaultController], TRUE);
-               $defaultAction = $actions[0];
-
-               return array(
-                       'controllerName' => $defaultController,
-                       'actionName' => $defaultAction,
-               );
-       }
-
-       /**
-        * Returns the controller/action pair that was specified by the request if it is valid,
-        * otherwise, will just return a blank controller/action pair meaning the default
-        * controller/action should be used instead.
-        *
-        * @param array $configuration The module configuration
-        * @param array $dispatcherParameters The dispatcher parameters
-        * @return array The controller/action pair
-        */
-       protected function getDispatcherControllerAction($configuration, $dispatcherParameters) {
-               $controllerAction = array(
-                       'controllerName' => '',
-                       'actionName' => '',
-               );
-
-               if (!isset($dispatcherParameters['controllerName'])) {
-                               // Early return: should use fallback controller/action
-                       return $controllerAction;
-               }
-
-                       // Extract configured controllers from module's registration in ext_tables.php
-               $controllers = array_keys($configuration['controllerActions']);
-
-               $controller = $dispatcherParameters['controllerName'];
-               if (in_array($controller, $controllers)) {
-                               // Update return value as selected controller is valid
-                       $controllerAction['controllerName'] = $controller;
-                       $actions = t3lib_div::trimExplode(',', $configuration['controllerActions'][$controller], TRUE);
-                       if (isset($dispatcherParameters['actionName'])) {
-                                       // Extract configured actions for selected controllers
-                               $action = $dispatcherParameters['actionName'];
-                               if (in_array($action, $actions)) {
-                                               // Requested action is valid for selected controller
-                                       $controllerAction['actionName'] = $action;
-                               } else {
-                                               // Use first action of selected controller as fallback action
-                                       $controllerAction['actionName'] = $actions[0];
-                               }
-                       } else {
-                                       // Use first action of selected controller as fallback action
-                               $controllerAction['actionName'] = $actions[0];
-                       }
-               }
-
-               return $controllerAction;
-       }
-
-       /**
-        * Returns the controller/action pair to use if a module function parameter is found
-        * in the request, otherwise, will just return a blank controller/action pair.
-        *
-        * @param string $module The name of the module
-        * @param string $defaultController The module's default controller
-        * @return array The controller/action pair
-        */
-       protected function getModuleFunctionControllerAction($module, $defaultController) {
-               $controllerAction = array(
-                       'controllerName' => '',
-                       'actionName' => '',
-               );
-
-               $set = t3lib_div::_GP('SET');
-               if (!$set) {
-                               // Early return
-                       return $controllerAction;
-               }
-
-               $moduleFunction = $set['function'];
-               $matches = array();
-               if (preg_match('/^(.*)->(.*)$/', $moduleFunction, $matches)) {
-                       $controllerAction['controllerName'] = $matches[1];
-                       $controllerAction['actionName'] = $matches[2];
-               } else {
-                               // Support for external SCbase module function rendering
-                       $functions = $GLOBALS['TBE_MODULES_EXT']['_configuration'][$module]['MOD_MENU']['function'];
-                       if (isset($functions[$moduleFunction])) {
-                               $controllerAction['controllerName'] = $defaultController;
-                               $controllerAction['actionName'] = 'extObj';
-                       }
-               }
-
-               return $controllerAction;
-       }
-
-       /**
-        * Transfers the request to an Extbase backend module, calling
-        * a given controller/action.
-        *
-        * @param string $module The name of the module
-        * @param string $controller The controller to use
-        * @param string $action The controller's action to execute
-        * @return string The module rendered view
-        */
-       protected function transfer($module, $controller, $action) {
-               $config = $GLOBALS['TBE_MODULES']['_configuration'][$module];
-
-               $extbaseConfiguration = array(
-                       'userFunc' => 'tx_extbase_dispatcher->dispatch',
-                       'pluginName' => $module,
-                       'extensionName' => $config['extensionName'],
-                       'controller' => $controller,
-                       'action' => $action,
-                       'switchableControllerActions.' => array(),
-                       'settings' => '< module.tx_' . strtolower($config['extensionName']) . '.settings',
-                       'persistence' => '< module.tx_' . strtolower($config['extensionName']) . '.persistence',
-                       'view' => '< module.tx_' . strtolower($config['extensionName']) . '.view',
-               );
-
-               $i = 1;
-               foreach ($config['controllerActions'] as $controller => $actions) {
-                               // Add an "extObj" action for the default controller to handle external
-                               // SCbase modules which add function menu entries
-                       if ($i == 1) {
-                               $actions .= ',extObj';
-                       }
-                       $extbaseConfiguration['switchableControllerActions.'][$controller . '.'] = array(
-                               'controller' => $controller,
-                               'actions' => $actions,
-                       );
-                       $i++;
-               }
-
-                       // BACK_PATH is the path from the typo3/ directory from within the
-                       // directory containing the controller file. We are using mod.php dispatcher
-                       // and thus we are already within typo3/ because we call typo3/mod.php
-               $GLOBALS['BACK_PATH'] = '';
-               return $this->dispatch('', $extbaseConfiguration);
+       static public function getPersistenceManager() {
+               t3lib_div::logDeprecatedFunction();
+               return self::$persistenceManager;
        }
 
        /**
-        * Push some information to time tracking if in Frontend
+        * Returns the settings of Extbase
         *
-        * @param string $name
-        * @todo correct variable names
-        * @return void
-        */
-       protected function timeTrackPush($name, $param2) {
-               if (isset($GLOBALS['TT'])) {
-                       $GLOBALS['TT']->push($name, $param2);
-               }
-       }
-
-       /**
-        * Time track pull
-        * @todo complete documentation of this method.
+        * @return array The configuration for the Extbase framework
+        * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
         */
-       protected function timeTrackPull() {
-               if (isset($GLOBALS['TT'])) {
-                       $GLOBALS['TT']->pull();
-               }
+       static public function getExtbaseFrameworkConfiguration() {
+               t3lib_div::logDeprecatedFunction();
+               return self::$configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
        }
 
 }
index 3266f22..d46cb88 100644 (file)
@@ -574,24 +574,24 @@ class Tx_Extbase_Domain_Model_FrontendUser extends Tx_Extbase_DomainObject_Abstr
        }
 
        /**
-        * Sets the lastLogin value
+        * Sets the lastlogin value
         *
-        * @param DateTime $lastLogin
+        * @param DateTime $lastlogin
         * @return void
         * @api
         */
-       public function setLastLogin(DateTime $lastLogin) {
-               $this->lastLogin = $lastLogin;
+       public function setLastlogin(DateTime $lastlogin) {
+               $this->lastlogin = $lastlogin;
        }
 
        /**
-        * Returns the lastLogin value
+        * Returns the lastlogin value
         *
         * @return DateTime
         * @api
         */
-       public function getLastLogin() {
-               return $this->lastLogin;
+       public function getLastlogin() {
+               return $this->lastlogin;
        }
 
        /**
index 1158107..c579879 100644 (file)
@@ -34,9 +34,8 @@
  * @api
  */
 abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbase_MVC_Controller_ControllerInterface {
-
        /**
-        * @var Tx_Extbase_Object_ManagerInterface
+        * @var Tx_Extbase_Object_ObjectManagerInterface
         */
        protected $objectManager;
 
@@ -105,6 +104,12 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
        protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
 
        /**
+        * @var Tx_Extbase_MVC_Controller_ControllerContext
+        * @api
+        */
+       protected $controllerContext;
+
+       /**
         * The flash messages. DEPRECATED. Use $this->flashMessageContainer instead.
         *
         * @var Tx_Extbase_MVC_Controller_FlashMessages
@@ -121,23 +126,24 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
        protected $flashMessageContainer;
 
        /**
+        * @var Tx_Extbase_Configuration_ConfigurationManager
+        */
+       protected $configurationManager;
+
+       /**
         * Constructs the controller.
         */
        public function __construct() {
-               $this->initializeObjects();
                list(, $this->extensionName) = explode('_', get_class($this));
        }
 
        /**
-        * Initializes objects this class depends on
-        *
+        * @param Tx_Extbase_Configuration_ConfigurationManager $configurationManager
         * @return void
         */
-       protected function initializeObjects() {
-               $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager');
-               $this->arguments = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_Arguments');
-               $this->arguments->injectPersistenceManager(Tx_Extbase_Dispatcher::getPersistenceManager());
-               $this->arguments->injectQueryFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory'));
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManager $configurationManager) {
+               $this->configurationManager = $configurationManager;
+               $this->settings = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
        }
 
        /**
@@ -151,23 +157,14 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
        }
 
        /**
-        * Injects the settings of the extension.
-        *
-        * @param array $settings Settings container of the current extension
-        * @return void
-        */
-       public function injectSettings(array $settings) {
-               $this->settings = $settings;
-       }
-
-       /**
         * Injects the object manager
         *
-        * @param Tx_Extbase_Object_ManagerInterface $objectManager
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
         * @return void
         */
-       public function injectObjectManager(Tx_Extbase_Object_ManagerInterface $objectManager) {
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
                $this->objectManager = $objectManager;
+               $this->arguments = $this->objectManager->create('Tx_Extbase_MVC_Controller_Arguments');
        }
 
        /**
@@ -202,7 +199,7 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
         * @return boolean TRUE if this request type is supported, otherwise FALSE
         * @api
         */
-       public function canProcessRequest(Tx_Extbase_MVC_Request $request) {
+       public function canProcessRequest(Tx_Extbase_MVC_RequestInterface $request) {
                foreach ($this->supportedRequestTypes as $supportedRequestType) {
                        if ($request instanceof $supportedRequestType) return TRUE;
                }
@@ -218,18 +215,19 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
         * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
         * @api
         */
-       public function processRequest(Tx_Extbase_MVC_Request $request, Tx_Extbase_MVC_Response $response) {
+       public function processRequest(Tx_Extbase_MVC_RequestInterface $request, Tx_Extbase_MVC_ResponseInterface $response) {
                if (!$this->canProcessRequest($request)) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType(get_class($this) . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes) , 1187701131);
 
                $this->request = $request;
                $this->request->setDispatched(TRUE);
                $this->response = $response;
 
-               $this->uriBuilder = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Routing_UriBuilder');
+               $this->uriBuilder = $this->objectManager->create('Tx_Extbase_MVC_Web_Routing_UriBuilder');
                $this->uriBuilder->setRequest($request);
 
                $this->initializeControllerArgumentsBaseValidators();
                $this->mapRequestArgumentsToControllerArguments();
+               $this->controllerContext = $this->buildControllerContext();
        }
 
        /**
@@ -239,7 +237,7 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
         * @api
         */
        protected function buildControllerContext() {
-               $controllerContext = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_ControllerContext');
+               $controllerContext = $this->objectManager->create('Tx_Extbase_MVC_Controller_ControllerContext');
                $controllerContext->setRequest($this->request);
                $controllerContext->setResponse($this->response);
                if ($this->arguments !== NULL) {
@@ -388,7 +386,7 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
                        if ($this->arguments[$propertyName]->isRequired() === FALSE) $optionalPropertyNames[] = $propertyName;
                }
 
-               $validator = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_ArgumentsValidator');
+               $validator = $this->objectManager->create('Tx_Extbase_MVC_Controller_ArgumentsValidator');
                $this->propertyMapper->mapAndValidate($allPropertyNames, $this->request->getArguments(), $this->arguments, $optionalPropertyNames, $validator);
 
                $this->argumentsMappingResults = $this->propertyMapper->getMappingResults();
index 380b1e9..47cdcc1 100644 (file)
@@ -40,10 +40,8 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
        protected $reflectionService;
 
        /**
-        * By default a Fluid TemplateView is provided, if a template is available,
-        * then a view with the same name as the current action will be looked up.
-        * If none is available the $defaultViewObjectName will be used and finally
-        * an EmptyView will be created.
+        * The current view, as resolved by resolveView()
+        *
         * @var Tx_Extbase_MVC_View_ViewInterface
         * @api
         */
@@ -58,12 +56,24 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
        protected $viewObjectNamePattern = 'Tx_@extension_View_@controller_@action@format';
 
        /**
-        * The default view object to use if neither a Fluid template nor an action
-        * specific view object could be found.
+        * A list of formats and object names of the views which should render them.
+        *
+        * Example:
+        *
+        * array('html' => 'Tx_MyExtension_View_MyHtmlView', 'json' => 'F3...
+        *
+        * @var array
+        */
+       protected $viewFormatToObjectNameMap = array();
+
+       /**
+        * The default view object to use if none of the resolved views can render
+        * a response for the current request.
+        *
         * @var string
         * @api
         */
-       protected $defaultViewObjectName = NULL;
+       protected $defaultViewObjectName = 'Tx_Fluid_View_TemplateView';
 
        /**
         * Name of the action method
@@ -99,7 +109,7 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
         * @param Tx_Extbase_MVC_Request $request The current request
         * @return boolean TRUE if this request type is supported, otherwise FALSE
         */
-       public function canProcessRequest(Tx_Extbase_MVC_Request $request) {
+       public function canProcessRequest(Tx_Extbase_MVC_RequestInterface $request) {
                return parent::canProcessRequest($request);
 
        }
@@ -111,14 +121,14 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
         * @param Tx_Extbase_MVC_Response $response The response, modified by this handler
         * @return void
         */
-       public function processRequest(Tx_Extbase_MVC_Request $request, Tx_Extbase_MVC_Response $response) {
+       public function processRequest(Tx_Extbase_MVC_RequestInterface $request, Tx_Extbase_MVC_ResponseInterface $response) {
                if (!$this->canProcessRequest($request)) throw new Tx_Extbase_MVC_Exception_UnsupportedRequestType(get_class($this) . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes) , 1187701131);
 
                $this->request = $request;
                $this->request->setDispatched(TRUE);
                $this->response = $response;
 
-               $this->uriBuilder = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Routing_UriBuilder');
+               $this->uriBuilder = $this->objectManager->create('Tx_Extbase_MVC_Web_Routing_UriBuilder');
                $this->uriBuilder->setRequest($request);
 
                $this->actionMethodName = $this->resolveActionMethodName();
@@ -134,6 +144,7 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
 
                $this->mapRequestArgumentsToControllerArguments();
                $this->checkRequestHash();
+               $this->controllerContext = $this->buildControllerContext();
                $this->view = $this->resolveView();
                if ($this->view !== NULL) $this->initializeView($this->view);
                $this->callActionMethod();
@@ -251,28 +262,27 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
         * @api
         */
        protected function resolveView() {
-               $view = $this->objectManager->getObject('Tx_Fluid_View_TemplateView');
-               $controllerContext = $this->buildControllerContext();
-               $view->setControllerContext($controllerContext);
-
-               // Template Path Override
-               $extbaseFrameworkConfiguration = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
-               if (isset($extbaseFrameworkConfiguration['view']['templateRootPath']) && strlen($extbaseFrameworkConfiguration['view']['templateRootPath']) > 0) {
-                       $view->setTemplateRootPath(t3lib_div::getFileAbsFileName($extbaseFrameworkConfiguration['view']['templateRootPath']));
+               $viewObjectName = $this->resolveViewObjectName();
+               if ($viewObjectName !== FALSE) {
+                       $view = $this->objectManager->create($viewObjectName);
+                       $this->setViewConfiguration($view);
+                       if ($view->canRender($this->controllerContext) === FALSE) {
+                               unset($view);
+                       }
                }
-               if (isset($extbaseFrameworkConfiguration['view']['layoutRootPath']) && strlen($extbaseFrameworkConfiguration['view']['layoutRootPath']) > 0) {
-                       $view->setLayoutRootPath(t3lib_div::getFileAbsFileName($extbaseFrameworkConfiguration['view']['layoutRootPath']));
+               if (!isset($view) && $this->defaultViewObjectName != '') {
+                       $view = $this->objectManager->create($this->defaultViewObjectName);
+                       $this->setViewConfiguration($view);
+                       if ($view->canRender($this->controllerContext) === FALSE) {
+                               unset($view);
+                       }
                }
-               if (isset($extbaseFrameworkConfiguration['view']['partialRootPath']) && strlen($extbaseFrameworkConfiguration['view']['partialRootPath']) > 0) {
-                       $view->setPartialRootPath(t3lib_div::getFileAbsFileName($extbaseFrameworkConfiguration['view']['partialRootPath']));
+               if (!isset($view)) {
+                       $view = $this->objectManager->create('Tx_Extbase_MVC_View_NotFoundView');
+                       $view->assign('errorMessage', 'No template was found. View could not be resolved for action "' . $this->request->getControllerActionName() . '"');
                }
+               $view->setControllerContext($this->controllerContext);
 
-               if ($view->hasTemplate() === FALSE) {
-                       $viewObjectName = $this->resolveViewObjectName();
-                       if (class_exists($viewObjectName) === FALSE) $viewObjectName = 'Tx_Extbase_MVC_View_EmptyView';
-                       $view = $this->objectManager->getObject($viewObjectName);
-                       $view->setControllerContext($controllerContext);
-               }
                if (method_exists($view, 'injectSettings')) {
                        $view->injectSettings($this->settings);
                }
@@ -282,6 +292,30 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
        }
 
        /**
+        * @param Tx_Extbase_MVC_View_ViewInterface $view
+        * @return void
+        */
+       protected function setViewConfiguration(Tx_Extbase_MVC_View_ViewInterface $view) {
+                       // Template Path Override
+               $extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if (isset($extbaseFrameworkConfiguration['view']['templateRootPath'])
+                       && strlen($extbaseFrameworkConfiguration['view']['templateRootPath']) > 0
+                       && method_exists($view, 'setTemplateRootPath')) {
+                       $view->setTemplateRootPath(t3lib_div::getFileAbsFileName($extbaseFrameworkConfiguration['view']['templateRootPath']));
+               }
+               if (isset($extbaseFrameworkConfiguration['view']['layoutRootPath'])
+                       && strlen($extbaseFrameworkConfiguration['view']['layoutRootPath']) > 0
+                       && method_exists($view, 'setLayoutRootPath')) {
+                       $view->setLayoutRootPath(t3lib_div::getFileAbsFileName($extbaseFrameworkConfiguration['view']['layoutRootPath']));
+               }
+               if (isset($extbaseFrameworkConfiguration['view']['partialRootPath'])
+                       && strlen($extbaseFrameworkConfiguration['view']['partialRootPath']) > 0
+                       && method_exists($view, 'setPartialRootPath')) {
+                       $view->setPartialRootPath(t3lib_div::getFileAbsFileName($extbaseFrameworkConfiguration['view']['partialRootPath']));
+               }
+       }
+
+       /**
         * Determines the fully qualified view object name.
         *
         * @return mixed The fully qualified view object name or FALSE if no matching view could be found.
@@ -293,15 +327,16 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
                $possibleViewName = str_replace('@extension', $extensionName, $possibleViewName);
                $possibleViewName = str_replace('@controller', $this->request->getControllerName(), $possibleViewName);
                $possibleViewName = str_replace('@action', ucfirst($this->request->getControllerActionName()), $possibleViewName);
+               $format = $this->request->getFormat();
 
                $viewObjectName = str_replace('@format', ucfirst($this->request->getFormat()), $possibleViewName);
                if (class_exists($viewObjectName) === FALSE) {
                        $viewObjectName = str_replace('@format', '', $possibleViewName);
                }
-               if (class_exists($viewObjectName) === FALSE && $this->defaultViewObjectName !== NULL) {
-                       $viewObjectName = $this->defaultViewObjectName;
+               if (class_exists($viewObjectName) === FALSE && isset($this->viewFormatToObjectNameMap[$format])) {
+                       $viewObjectName = $this->viewFormatToObjectNameMap[$format];
                }
-               return $viewObjectName;
+               return class_exists($viewObjectName) ? $viewObjectName : FALSE;
        }
 
        /**
@@ -413,7 +448,7 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
         * @return void
         */
        protected function clearCacheOnError() {
-               $extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
+               $extbaseSettings = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
                if (isset($extbaseSettings['persistence']['enableAutomaticCacheClearing']) && $extbaseSettings['persistence']['enableAutomaticCacheClearing'] === '1') {
                        if (isset($GLOBALS['TSFE'])) {
                                $pageUid = $GLOBALS['TSFE']->id;
index 70817e4..b2d9b1a 100644 (file)
 class Tx_Extbase_MVC_Controller_Argument {
 
        /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
         * @var Tx_Extbase_Persistence_QueryFactory
         */
        protected $queryFactory;
@@ -134,14 +139,29 @@ class Tx_Extbase_MVC_Controller_Argument {
        }
 
        /**
-        * Initializes this object
+        * Injects the object manager
         *
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * @param Tx_Extbase_Property_Mapper $propertyMapper
         * @return void
         */
-       public function initializeObject() {
-               $this->reflectionService = t3lib_div::makeInstance('Tx_Extbase_Reflection_Service');
-               $this->propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper');
-               $this->propertyMapper->injectReflectionService($this->reflectionService);
+       public function injectPropertyMapper(Tx_Extbase_Property_Mapper $propertyMapper) {
+               $this->propertyMapper = $propertyMapper;
+       }
+
+       /**
+        * @param Tx_Extbase_Reflection_Service $reflectionService 
+        * @return void
+        */
+       public function injectReflectionService(Tx_Extbase_Reflection_Service $reflectionService) {
+               $this->reflectionService = $reflectionService;
                $this->dataTypeClassSchema = (strstr($this->dataType, '_') !== FALSE) ? $this->reflectionService->getClassSchema($this->dataType) : NULL;
        }
 
@@ -286,11 +306,11 @@ class Tx_Extbase_MVC_Controller_Argument {
         */
        public function setNewValidatorConjunction(array $objectNames) {
                if ($this->validator === NULL) {
-                       $this->validator = t3lib_div::makeInstance('Tx_Extbase_Validation_Validator_ConjunctionValidator');
+                       $this->validator = $this->objectManager->create('Tx_Extbase_Validation_Validator_ConjunctionValidator');
                }
                foreach ($objectNames as $objectName) {
                        if (!class_exists($objectName)) $objectName = 'Tx_Extbase_Validation_Validator_' . $objectName;
-                       $this->validator->addValidator(t3lib_div::makeInstance($objectName));
+                       $this->validator->addValidator($this->objectManager->get($objectName));
                }
                return $this;
        }
@@ -379,12 +399,10 @@ class Tx_Extbase_MVC_Controller_Argument {
                $query = $this->queryFactory->create($this->dataType);
                $query->getQuerySettings()->setRespectSysLanguage(FALSE);
                $query->getQuerySettings()->setRespectStoragePage(FALSE);
-               $result = $query->matching($query->equals('uid', $uid))->execute();
-               $object = NULL;
-               if (count($result) > 0) {
-                       $object = current($result);
-               }
-               return $object;
+               return $query->matching(
+                       $query->equals('uid', $uid))
+                       ->execute()
+                       ->getFirst();
        }
 
        /**
index 08f154a..f9e4998 100644 (file)
  * @scope prototype
  */
 class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
-
-       /**
-        * @var Tx_Extbase_Persistence_ManagerInterface
-        */
-       protected $persistenceManager;
-
        /**
-        * @var Tx_Extbase_Persistence_QueryFactory
+        * @var Tx_Extbase_Object_ObjectManagerInterface
         */
-       protected $queryFactory;
+       protected $objectManager;
 
        /**
         * @var array Names of the arguments contained by this object
@@ -51,23 +45,20 @@ class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
        protected $argumentNames = array();
 
        /**
-        * Injects the persistence manager
-        *
-        * @param Tx_Extbase_Persistence_ManagerInterface $persistenceManager
-        * @return void
+        * Constructor. If this one is removed, reflection breaks.
         */
-       public function injectPersistenceManager(Tx_Extbase_Persistence_ManagerInterface $persistenceManager) {
-               $this->persistenceManager = $persistenceManager;
+       public function __construct() {
+               parent::__construct();
        }
 
        /**
-        * Injects a QueryFactory instance
+        * Injects the object manager
         *
-        * @param Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
         * @return void
         */
-       public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory) {
-               $this->queryFactory = $queryFactory;
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
        }
 
        /**
@@ -151,7 +142,7 @@ class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
         * @return Tx_Extbase_MVC_Controller_Argument The new argument
         */
        public function addNewArgument($name, $dataType = 'Text', $isRequired = FALSE, $defaultValue = NULL) {
-               $argument = $this->createArgument($name, $dataType);
+               $argument = $this->objectManager->create('Tx_Extbase_MVC_Controller_Argument', $name, $dataType);
                $argument->setRequired($isRequired);
                $argument->setDefaultValue($defaultValue);
                $this->addArgument($argument);
@@ -159,21 +150,6 @@ class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject {
        }
 
        /**
-        * Creates a new argument. This is a replacement for $this->objectFactory->create() of FLOW3.
-        *
-        * @param string $name Name of the argument
-        * @param string $dataType Name of one of the built-in data types
-        * @return Tx_Extbase_MVC_Controller_Argument The created argument
-        */
-       protected function createArgument($name, $dataType) {
-               $argument = new Tx_Extbase_MVC_Controller_Argument($name, $dataType);
-               $argument->injectPersistenceManager($this->persistenceManager);
-               $argument->injectQueryFactory($this->queryFactory);
-               $argument->initializeObject();
-               return $argument;
-       }
-
-       /**
         * Adds the specified controller argument to this composite object.
         * If an argument with the same name exists already, it will be replaced by the
         * new argument object.
index 847c7a9..d2bbea7 100644 (file)
@@ -105,7 +105,7 @@ class Tx_Extbase_MVC_Controller_ArgumentsValidator extends Tx_Extbase_Validation
         */
        protected function addErrorsForArgument(array $errors, $argumentName) {
                if (!isset($this->errors[$argumentName])) {
-                       $this->errors[$argumentName] = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_ArgumentError', $argumentName);
+                       $this->errors[$argumentName] = new Tx_Extbase_MVC_Controller_ArgumentError($argumentName);
                }
                $this->errors[$argumentName]->addErrors($errors);
        }
index d4bd200..7a4359d 100644 (file)
  * Interface for controllers
  *
  * @package Extbase
- * @subpackage MVC\Controller
  * @version $ID:$
  * @api
  */
 interface Tx_Extbase_MVC_Controller_ControllerInterface {
 
        /**
-        * Sets / injects the settings of the package this controller belongs to.
-        *
-        * Needed to emulate settings injection.
-        *
-        * @param array $settings Settings container of the current package
-        * @return void
-        */
-       public function injectSettings(array $settings);
-
-       /**
         * Checks if the current request type is supported by the controller.
         *
-        * @param Tx_Extbase_MVC_Request $request The current request
+        * @param Tx_Extbase_MVC_RequestInterface $request The current request
         * @return boolean TRUE if this request type is supported, otherwise FALSE
         * @api
         */
-       public function canProcessRequest(Tx_Extbase_MVC_Request $request);
+       public function canProcessRequest(Tx_Extbase_MVC_RequestInterface $request);
 
        /**
         * Processes a general request. The result can be returned by altering the given response.
         *
         * @param Tx_Extbase_MVC_Request $request The request object
-        * @param Tx_Extbase_MVC_Response $response The response, modified by the controller
+        * @param Tx_Extbase_MVC_ResponseInterface $response The response, modified by the controller
         * @return void
         * @throws Tx_Extbase_MVC_Exception_UnsupportedRequestType if the controller doesn't support the current request type
         * @api
         */
-       public function processRequest(Tx_Extbase_MVC_Request $request, Tx_Extbase_MVC_Response $response);
+       public function processRequest(Tx_Extbase_MVC_RequestInterface $request, Tx_Extbase_MVC_ResponseInterface $response);
 
 }
 ?>
\ No newline at end of file
index c4392b2..f1ddba5 100644 (file)
@@ -58,6 +58,19 @@ class Tx_Extbase_MVC_Controller_FlashMessages implements t3lib_Singleton {
        protected $flashMessageStorageKey = NULL;
 
        /**
+        * @var Tx_Extbase_Configuration_ConfigurationManager
+        */
+       protected $configurationManager;
+
+       /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
         * Add another flash message.
         *
         * @param string $message
@@ -65,7 +78,9 @@ class Tx_Extbase_MVC_Controller_FlashMessages implements t3lib_Singleton {
         * @api
         */
        public function add($message) {
-               if (!is_string($message)) throw new InvalidArgumentException('The flash message must be string, ' . gettype($message) . ' given.', 1243258395);
+               if (!is_string($message)) {
+                       throw new InvalidArgumentException('The flash message must be string, ' . gettype($message) . ' given.', 1243258395);
+               }
                $this->initialize();
                $this->flashMessages[] = $message;
        }
@@ -111,8 +126,8 @@ class Tx_Extbase_MVC_Controller_FlashMessages implements t3lib_Singleton {
        protected function initialize() {
                if ($this->initialized) return;
 
-               $frameworkConfiguration = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
-               $this->flashMessageStorageKey = 'Tx_Extbase_MVC_Controller_FlashMessages_messages_' . $frameworkConfiguration['extensionName'] . $frameworkConfiguration['pluginName'];
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               $this->flashMessageStorageKey = 'Tx_Extbase_MVC_Controller_FlashMessages_messages_' . $frameworkConfiguration['extensionName'];
 
                $flashMessages = $this->loadFlashMessagesFromSession();
                if (is_array($flashMessages)) {
@@ -126,7 +141,6 @@ class Tx_Extbase_MVC_Controller_FlashMessages implements t3lib_Singleton {
         * Loads the flash messages from the current user session.
         */
        protected function loadFlashMessagesFromSession() {
-               $flashMessages = NULL;
                if (TYPO3_MODE === 'FE') {
                        $flashMessages = $GLOBALS['TSFE']->fe_user->getKey('ses', $this->flashMessageStorageKey);
                } else {
diff --git a/typo3/sysext/extbase/Classes/MVC/Dispatcher.php b/typo3/sysext/extbase/Classes/MVC/Dispatcher.php
new file mode 100644 (file)
index 0000000..ddd32ab
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Dispatches requests to the controller which was specified by the request and
+ * returns the response the controller generated.
+ *
+ */
+class Tx_Extbase_MVC_Dispatcher implements t3lib_Singleton {
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface A reference to the object manager
+        */
+       protected $objectManager;
+
+       /**
+        * @var Tx_Extbase_Reflection_Service
+        */
+       protected $reflectionService;
+
+       /**
+        * @var array
+        */
+       protected $settings = array();
+
+       /**
+        * Constructs the global dispatcher
+        *
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager A reference to the object manager
+        */
+       public function __construct(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * Injects the Reflection Service
+        *
+        * @param Tx_Extbase_Reflection_Service $reflectionService
+        * @return void
+        */
+       public function injectReflectionService(Tx_Extbase_Reflection_Service $reflectionService) {
+               $this->reflectionService = $reflectionService;
+       }
+
+       /**
+        * Dispatches a request to a controller and initializes the security framework.
+        *
+        * @param Tx_Extbase_MVC_RequestInterface $request The request to dispatch
+        * @param Tx_Extbase_MVC_ResponseInterface $response The response, to be modified by the controller
+        * @return void
+        */
+       public function dispatch(Tx_Extbase_MVC_RequestInterface $request, Tx_Extbase_MVC_ResponseInterface $response) {
+               $dispatchLoopCount = 0;
+               while (!$request->isDispatched()) {
+                       if ($dispatchLoopCount++ > 99) throw new Tx_Extbase_MVC_Exception_InfiniteLoop('Could not ultimately dispatch the request after '  . $dispatchLoopCount . ' iterations.', 1217839467);
+                       $controller = $this->resolveController($request);
+                       try {
+                               $controller->processRequest($request, $response);
+                       } catch (Tx_Extbase_MVC_Exception_StopAction $ignoredException) {
+                       }
+               }
+       }
+
+       /**
+        * Finds and instanciates a controller that matches the current request.
+        * If no controller can be found, an instance of NotFoundControllerInterface is returned.
+        *
+        * @param Tx_Extbase_MVC_RequestInterface $request The request to dispatch
+        * @return Tx_Extbase_MVC_Controller_ControllerInterface
+        * @author Bastian Waidelich <bastian@typo3.org>
+        * @author Robert Lemke <robert@typo3.org>
+        */
+       protected function resolveController(Tx_Extbase_MVC_RequestInterface $request) {
+               $controllerObjectName = $request->getControllerObjectName();
+               $controller = $this->objectManager->get($controllerObjectName);
+               if (!$controller instanceof Tx_Extbase_MVC_Controller_ControllerInterface) {
+                       throw new Tx_Extbase_MVC_Exception_InvalidController('Invalid controller "' . $request->getControllerObjectName() . '". The controller must implement the Tx_Extbase_MVC_Controller_ControllerInterface.', 1202921619);
+               }
+               return $controller;
+       }
+
+}
+?>
\ No newline at end of file
index dde8536..e4d4484 100644 (file)
@@ -43,7 +43,7 @@ class Tx_Extbase_MVC_Request implements Tx_Extbase_MVC_RequestInterface {
         *
         * @var string
         */
-       protected $controllerObjectNamePattern = 'Tx_@extension_Controller_@controllerController';
+       protected $controllerObjectNamePattern = 'Tx_@extension_@subpackage_Controller_@controllerController';
 
        /**
         * @var string Key of the plugin which identifies the plugin. It must be a string containing [a-z0-9]
@@ -56,6 +56,13 @@ class Tx_Extbase_MVC_Request implements Tx_Extbase_MVC_RequestInterface {
        protected $controllerExtensionName = NULL;
 
        /**
+        * Subpackage key of the controller which is supposed to handle this request.
+        *
+        * @var string
+        */
+       protected $controllerSubpackageKey = NULL;
+
+       /**
         * @var string Object name of the controller which is supposed to handle this request.
         */
        protected $controllerName = 'Standard';
@@ -120,7 +127,9 @@ class Tx_Extbase_MVC_Request implements Tx_Extbase_MVC_RequestInterface {
         */
        public function getControllerObjectName() {
                $lowercaseObjectName = str_replace('@extension', $this->controllerExtensionName, $this->controllerObjectNamePattern);
+               $lowercaseObjectName = str_replace('@subpackage', $this->controllerSubpackageKey, $lowercaseObjectName);
                $lowercaseObjectName = str_replace('@controller', $this->controllerName, $lowercaseObjectName);
+               $lowercaseObjectName = str_replace('__', '_', $lowercaseObjectName);
                // TODO implement getCaseSensitiveObjectName()
                $objectName = $lowercaseObjectName;
                if ($objectName === FALSE) throw new Tx_Extbase_MVC_Exception_NoSuchController('The controller object "' . $lowercaseObjectName . '" does not exist.', 1220884009);
@@ -129,6 +138,32 @@ class Tx_Extbase_MVC_Request implements Tx_Extbase_MVC_RequestInterface {
        }
 
        /**
+        * Explicitly sets the object name of the controller
+        *
+        * @param string $controllerObjectName The fully qualified controller object name
+        * @return void
+        */
+       public function setControllerObjectName($controllerObjectName) {
+               $matches = array();
+               preg_match('/
+                       ^Tx
+                       _(?P<extensionName>[^_]+)
+                       _
+                       (
+                               Controller
+                       |
+                               (?P<subpackageKey>.+)_Controller
+                       )
+                       _(?P<controllerName>[a-z_]+)Controller
+                       $/ix', $controllerObjectName, $matches
+               );
+
+               $this->controllerExtensionName = $matches['extensionName'];
+               $this->controllerSubpackageKey = (isset($matches['subpackageKey'])) ? $matches['subpackageKey'] : NULL;
+               $this->controllerName = $matches['controllerName'];
+       }
+
+       /**
         * Sets the plugin name.
         *
         * @param string $extensionName The plugin name.
@@ -180,7 +215,27 @@ class Tx_Extbase_MVC_Request implements Tx_Extbase_MVC_RequestInterface {
         * @api
         */
        public function getControllerExtensionKey() {
-               return Tx_Extbase_Utility_Extension::convertCamelCaseToLowerCaseUnderscored($this->controllerExtensionName);
+               return t3lib_div::camelCaseToLowerCaseUnderscored($this->controllerExtensionName);
+       }
+
+       /**
+        * Sets the subpackage key of the controller.
+        *
+        * @param string $subpackageKey The subpackage key.
+        * @return void
+        */
+       public function setControllerSubpackageKey($subpackageKey) {
+               $this->controllerSubpackageKey = $subpackageKey;
+       }
+
+       /**
+        * Returns the subpackage key of the specified controller.
+        * If there is no subpackage key set, the method returns NULL
+        *
+        * @return string The subpackage key
+        */
+       public function getControllerSubpackageKey() {
+               return $this->controllerSubpackageKey;
        }
 
        /**
diff --git a/typo3/sysext/extbase/Classes/MVC/RequestHandlerInterface.php b/typo3/sysext/extbase/Classes/MVC/RequestHandlerInterface.php
new file mode 100644 (file)
index 0000000..a51d727
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This class is a backport of the corresponding class of FLOW3.
+ *  All credits go to the v5 team.
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * The interface for a request handler
+ *
+ * @api
+ */
+interface Tx_Extbase_MVC_RequestHandlerInterface {
+
+       /**
+        * Handles a raw request and returns the respsonse.
+        *
+        * @return Tx_Extbase_MVC_ResponseInterface
+        * @api
+        */
+       public function handleRequest();
+
+       /**
+        * Checks if the request handler can handle the current request.
+        *
+        * @return boolean TRUE if it can handle the request, otherwise FALSE
+        * @api
+        */
+       public function canHandleRequest();
+
+       /**
+        * Returns the priority - how eager the handler is to actually handle the
+        * request. An integer > 0 means "I want to handle this request" where
+        * "100" is default. "0" means "I am a fallback solution".
+        *
+        * @return integer The priority of the request handler
+        * @api
+        */
+       public function getPriority();
+
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/MVC/RequestHandlerResolver.php b/typo3/sysext/extbase/Classes/MVC/RequestHandlerResolver.php
new file mode 100644 (file)
index 0000000..82deecb
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This class is a backport of the corresponding class of FLOW3.
+ *  All credits go to the v5 team.
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Analyzes the raw request and delivers a request handler which can handle it.
+ */
+class Tx_Extbase_MVC_RequestHandlerResolver {
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * @var Tx_Extbase_Reflection_ReflectionService
+        */
+       protected $reflectionService;
+
+       /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
+
+       /**
+        * Injects the object manager
+        *
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager A reference to the object manager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * Injects the reflection service
+        *
+        * @param Tx_Extbase_Reflection_Service $reflectionService
+        * @return void
+        */
+       public function injectReflectionService(Tx_Extbase_Reflection_Service $reflectionService) {
+               $this->reflectionService = $reflectionService;
+       }
+
+       /**
+        * Injects the configuration manager
+        *
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
+        * Analyzes the raw request and tries to find a request handler which can handle
+        * it. If none is found, an exception is thrown.
+        *
+        * @return Tx_Extbase_MVC_RequestHandler A request handler
+        * @throws Tx_Extbase_MVC_Exception
+        */
+       public function resolveRequestHandler() {
+               $availableRequestHandlerClassNames = $this->getRegisteredRequestHandlerClassNames();
+
+               $suitableRequestHandlers = array();
+               foreach ($availableRequestHandlerClassNames as $requestHandlerClassName) {
+                       $requestHandler = $this->objectManager->get($requestHandlerClassName);
+                       if ($requestHandler->canHandleRequest()) {
+                               $priority = $requestHandler->getPriority();
+                               if (isset($suitableRequestHandlers[$priority])) throw new Tx_Extbase_MVC_Exception('More than one request handler with the same priority can handle the request, but only one handler may be active at a time!', 1176475350);
+                               $suitableRequestHandlers[$priority] = $requestHandler;
+                       }
+               }
+               if (count($suitableRequestHandlers) === 0) throw new Tx_Extbase_MVC_Exception('No suitable request handler found.', 1205414233);
+               ksort($suitableRequestHandlers);
+               return array_pop($suitableRequestHandlers);
+       }
+
+       /**
+        * Returns a list of all registered request handlers.
+        *
+        * @return array
+        */
+       public function getRegisteredRequestHandlerClassNames() {
+               $settings = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               return is_array($settings['mvc']['requestHandlers']) ? $settings['mvc']['requestHandlers'] : array();
+       }
+}
+?>
\ No newline at end of file
index 73d7ca1..d75e8f2 100644 (file)
@@ -29,8 +29,6 @@
  * Contract for a request.
  *
  * @version $Id: RequestInterface.php 1729 2009-11-25 21:37:20Z stucki $
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
- * @author Robert Lemke <robert@typo3.org>
  * @scope prototype
  * @api
  */
index 04a10a1..a472580 100644 (file)
@@ -34,7 +34,7 @@
  * @scope prototype
  * @api
  */
-class Tx_Extbase_MVC_Response {
+class Tx_Extbase_MVC_Response implements Tx_Extbase_MVC_ResponseInterface {
 
        /**
         * @var string The response content
@@ -73,5 +73,15 @@ class Tx_Extbase_MVC_Response {
                return $this->content;
        }
 
+       /**
+        * Returns the content of the response.
+        *
+        * @return string
+        * @api
+        */
+       public function __toString() {
+               return $this->getContent();
+       }
+
 }
 ?>
\ No newline at end of file
index 2ac4750..a71cb42 100644 (file)
@@ -29,9 +29,6 @@
  * A generic and very basic response implementation
  *
  * @version $Id: ResponseInterface.php 1729 2009-11-25 21:37:20Z stucki $
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
- * @author Robert Lemke <robert@typo3.org>
- * @scope prototype
  * @api
  */
 interface Tx_Extbase_MVC_ResponseInterface {
@@ -62,12 +59,5 @@ interface Tx_Extbase_MVC_ResponseInterface {
         */
        public function getContent();
 
-       /**
-        * Sends the response
-        *
-        * @return void
-        * @api
-        */
-       public function send();
 }
 ?>
\ No newline at end of file
index 9d6928b..7b919ed 100644 (file)
@@ -87,6 +87,20 @@ abstract class Tx_Extbase_MVC_View_AbstractView implements Tx_Extbase_MVC_View_V
        }
 
        /**
+        * Tells if the view implementation can render the view for the given context.
+        *
+        * By default we assume that the view implementation can handle all kinds of
+        * contexts. Override this method if that is not the case.
+        *
+        * @param Tx_Extbase_MVC_Controller_ControllerContext $controllerContext
+        * @return boolean TRUE if the view has something useful to display, otherwise FALSE
+        * @api
+        */
+       public function canRender(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext) {
+               return TRUE;
+       }
+
+       /**
         * Initializes this view.
         *
         * Override this method for initializing your concrete view implementation.
index eb1dbec..27fd088 100644 (file)
  * @version $Id: EmptyView.php 1729 2009-11-25 21:37:20Z stucki $
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
-final class Tx_Extbase_MVC_View_EmptyView extends Tx_Extbase_MVC_View_AbstractView {
+final class Tx_Extbase_MVC_View_EmptyView implements Tx_Extbase_MVC_View_ViewInterface {
+
+       /**
+        * Dummy method to satisfy the ViewInterface
+        *
+        * @param Tx_Extbase_MVC_Controller_ControllerContext $controllerContext
+        * @return void
+        */
+       public function setControllerContext(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext) {
+       }
 
        /**
         * Dummy method to satisfy the ViewInterface
@@ -59,6 +68,17 @@ final class Tx_Extbase_MVC_View_EmptyView extends Tx_Extbase_MVC_View_AbstractVi
        }
 
        /**
+        * This view can be used in any case.
+        *
+        * @param Tx_Extbase_MVC_Controller_ControllerContext $controllerContext
+        * @return boolean TRUE
+        * @api
+        */
+       public function canRender(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext) {
+               return TRUE;
+       }
+
+       /**
         * Renders the empty view
         *
         * @return string An empty string
diff --git a/typo3/sysext/extbase/Classes/MVC/View/NotFoundView.php b/typo3/sysext/extbase/Classes/MVC/View/NotFoundView.php
new file mode 100644 (file)
index 0000000..3999d81
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * The not found view - a special case.
+ *
+ * @package Extbase
+ * @subpackage MVC\View
+ * @version $Id: EmptyView.php 2517 2010-08-04 17:56:45Z bwaidelich $
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Extbase_MVC_View_NotFoundView extends Tx_Extbase_MVC_View_AbstractView {
+
+       /**
+        * @var array
+        */
+       protected $variablesMarker = array('errorMessage' => 'ERROR_MESSAGE');
+
+       /**
+        * Renders the not found view
+        *
+        * @return string The rendered view
+        * @throws Tx_Extbase_MVC_Exception if no request has been set
+        * @api
+        */
+       public function render() {
+               if (!is_object($this->controllerContext->getRequest())) throw new Tx_Extbase_MVC_Exception('Can\'t render view without request object.', 1192450280);
+
+               $template = file_get_contents($this->getTemplatePathAndFilename());
+
+               if ($this->controllerContext->getRequest() instanceof Tx_Extbase_MVC_Web_Request) {
+                       $template = str_replace('###BASEURI###', t3lib_div::getIndpEnv('TYPO3_SITE_URL'), $template);
+               }
+
+               foreach ($this->variablesMarker as $variableName => $marker) {
+                       $variableValue = isset($this->variables[$variableName]) ? $this->variables[$variableName] : '';
+                       $template = str_replace('###' . $marker . '###', $variableValue, $template);
+               }
+
+               return $template;
+       }
+
+       /**
+        * Retrieves path and filename of the not-found-template
+        *
+        * @return string path and filename of the not-found-template
+        * @author Bastian Waidelich <bastian@typo3.org>
+        */
+       protected function getTemplatePathAndFilename() {
+               return t3lib_extmgm::extPath('extbase') . 'Resources/Private/MVC/NotFoundView_Template.html';
+       }
+
+       /**
+        * A magic call method.
+        *
+        * Because this not found view is used as a Special Case in situations when no matching
+        * view is available, it must be able to handle method calls which originally were
+        * directed to another type of view. This magic method should prevent PHP from issuing
+        * a fatal error.
+        *
+        * @return void
+        */
+       public function __call($methodName, array $arguments) {
+       }
+}
+?>
\ No newline at end of file
index bdb9648..eec7a95 100644 (file)
@@ -64,6 +64,15 @@ interface Tx_Extbase_MVC_View_ViewInterface {
        public function assignMultiple(array $values);
 
        /**
+        * Tells if the view implementation can render the view for the given context.
+        *
+        * @param Tx_Extbase_MVC_Controller_ControllerContext $controllerContext
+        * @return boolean TRUE if the view has something useful to display, otherwise FALSE
+        * @api
+        */
+       public function canRender(Tx_Extbase_MVC_Controller_ControllerContext $controllerContext);
+
+       /**
         * Renders the view
         *
         * @return string The rendered view
diff --git a/typo3/sysext/extbase/Classes/MVC/Web/AbstractRequestHandler.php b/typo3/sysext/extbase/Classes/MVC/Web/AbstractRequestHandler.php
new file mode 100644 (file)
index 0000000..81628c5
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This class is a backport of the corresponding class of FLOW3.
+ *  All credits go to the v5 team.
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A request handler which can handle web requests.
+ *
+ */
+abstract class Tx_Extbase_MVC_Web_AbstractRequestHandler implements Tx_Extbase_MVC_RequestHandlerInterface {
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
+
+       /**
+        * @var Tx_Extbase_MVC_Dispatcher
+        */
+       protected $dispatcher;
+
+       /**
+        * @var Tx_Extbase_MVC_Web_RequestBuilder
+        */
+       protected $requestBuilder;
+
+       /**
+        * @var Tx_Extbase_MVC_Controller_FlashMessages
+        */
+       protected $flashMessages;
+
+       /**
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectFlashMessages(Tx_Extbase_MVC_Controller_FlashMessages $flashMessages) {
+               $this->flashMessages = $flashMessages;
+       }
+
+       /**
+        * @param Tx_Extbase_MVC_Dispatcher $dispatcher
+        * @return void
+        */
+       public function injectDispatcher(Tx_Extbase_MVC_Dispatcher $dispatcher) {
+               $this->dispatcher = $dispatcher;
+       }
+
+       /**
+        * @param Tx_Extbase_MVC_Web_RequestBuilder $requestBuilder
+        * @return void
+        */
+       public function injectRequestBuilder(Tx_Extbase_MVC_Web_RequestBuilder $requestBuilder) {
+               $this->requestBuilder = $requestBuilder;
+       }
+
+       /**
+        * This request handler can handle any web request.
+        *
+        * @return boolean If the request is a web request, TRUE otherwise FALSE
+        */
+       public function canHandleRequest() {
+               return TRUE;
+       }
+
+       /**
+        * Returns the priority - how eager the handler is to actually handle the
+        * request.
+        *
+        * @return integer The priority of the request handler.
+        */
+       public function getPriority() {
+               return 100;
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/MVC/Web/BackendRequestHandler.php b/typo3/sysext/extbase/Classes/MVC/Web/BackendRequestHandler.php
new file mode 100644 (file)
index 0000000..390ba70
--- /dev/null
@@ -0,0 +1,58 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This class is a backport of the corresponding class of FLOW3.
+ *  All credits go to the v5 team.
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A request handler which can handle web requests invoked by the backend.
+ *
+ */
+class Tx_Extbase_MVC_Web_BackendRequestHandler extends Tx_Extbase_MVC_Web_AbstractRequestHandler {
+
+       /**
+        * Handles the web request. The response will automatically be sent to the client.
+        *
+        * @return void
+        */
+       public function handleRequest() {
+               $request = $this->requestBuilder->build();
+               $response = $this->objectManager->create('Tx_Extbase_MVC_Web_Response');
+
+               $this->dispatcher->dispatch($request, $response);
+
+               return $response;
+       }
+
+       /**
+        * This request handler can handle a web request invoked by the backend.
+        *
+        * @return boolean If we are in backend mode TRUE otherwise FALSE
+        */
+       public function canHandleRequest() {
+               return TYPO3_MODE === 'BE';
+       }
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/MVC/Web/FrontendRequestHandler.php b/typo3/sysext/extbase/Classes/MVC/Web/FrontendRequestHandler.php
new file mode 100644 (file)
index 0000000..15eecce
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Jochen Rau <jochen.rau@typoplanet.de>
+ *  All rights reserved
+ *
+ *  This class is a backport of the corresponding class of FLOW3.
+ *  All credits go to the v5 team.
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A request handler which can handle web requests invoked by the frontend.
+ *
+ */
+class Tx_Extbase_MVC_Web_FrontendRequestHandler extends Tx_Extbase_MVC_Web_AbstractRequestHandler {
+
+       /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
+
+       /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
+        * Handles the web request. The response will automatically be sent to the client.
+        *
+        * @return Tx_Extbase_MVC_Web_Response
+        */
+       public function handleRequest() {
+               $request = $this->requestBuilder->build();
+
+               // Request hash service
+               $requestHashService = $this->objectManager->get('Tx_Extbase_Security_Channel_RequestHashService'); // singleton
+               $requestHashService->verifyRequest($request);
+
+               if ($this->isCacheable($request->getControllerName(), $request->getControllerActionName())) {
+                       $request->setIsCached(TRUE);
+               } else {
+                       $contentObject = $this->configurationManager->getContentObject();
+                       if ($contentObject->getUserObjectType() === tslib_cObj::OBJECTTYPE_USER) {
+                               $contentObject->convertToUserIntObject();
+                               // tslib_cObj::convertToUserIntObject() will recreate the object, so we have to stop the request here
+                               return;
+                       }
+                       $request->setIsCached(FALSE);
+               }
+               $response = $this->objectManager->create('Tx_Extbase_MVC_Web_Response');
+
+               $this->dispatcher->dispatch($request, $response);
+
+               return $response;
+       }
+
+       /**
+        * This request handler can handle any web request.
+        *
+        * @return boolean If the request is a web request, TRUE otherwise FALSE
+        */
+       public function canHandleRequest() {
+               return TYPO3_MODE === 'FE';
+       }
+
+       /**
+        * Determines whether the current action can be cached
+        *
+        * @param string $controllerName
+        * @param string $actionName
+        * @return boolean TRUE if the given action should be cached, otherwise FALSE
+        */
+       protected function isCacheable($controllerName, $actionName) {
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if (isset($frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'])
+                       && in_array($actionName, $frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'])) {
+                               return FALSE;
+                       }
+               return TRUE;
+       }
+
+}
+?>
\ No newline at end of file
index 55ab89e..106bfb6 100644 (file)
@@ -63,14 +63,22 @@ class Tx_Extbase_MVC_Web_Request extends Tx_Extbase_MVC_Request {
        protected $hmacVerified = FALSE;
 
        /**
-        * @var array data of the current cObj
+        * @var boolean TRUE if the current request is cached, false otherwise.
         */
-       protected $contentObjectData = array();
+       protected $isCached = FALSE;
 
        /**
-        * @var boolean TRUE if the current request is cached, false otherwise.
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
         */
-       protected $isCached = FALSE;
+       protected $configurationManager;
+
+       /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
 
        /**
         * Sets the request method
@@ -160,25 +168,16 @@ class Tx_Extbase_MVC_Web_Request extends Tx_Extbase_MVC_Request {
        }
 
        /**
-        * Sets the data array of the current content object
-        *
-        * @param array $contentObjectData data of the current cObj
-        * @return void
-        * @author Bastian Waidelich <bastian@typo3.org>
-        */
-       public function setContentObjectData(array $contentObjectData) {
-               $this->contentObjectData = $contentObjectData;
-       }
-
-       /**
         * Returns the data array of the current content object
         *
         * @return array data of the current cObj
-        * @api (v4 only)
+        * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0. Use the ConfigurationManager to retrieve the current ContentObject
         * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function getContentObjectData() {
-               return $this->contentObjectData;
+               t3lib_div::logDeprecatedFunction();
+               $contentObject = $this->configurationManager->getContentObject();
+               return $contentObject->data;
        }
 
        /**
index 2ec9c50..d54ebce 100644 (file)
  *
  * @scope prototype
  */
-class Tx_Extbase_MVC_Web_RequestBuilder {
+class Tx_Extbase_MVC_Web_RequestBuilder implements t3lib_Singleton {
+
+       /**
+        * @var Tx_Extbase_Object_ObjectManagerInterface
+        */
+       protected $objectManager;
 
        /**
         * This is a unique key for a plugin (not the extension key!)
@@ -48,56 +53,73 @@ class Tx_Extbase_MVC_Web_RequestBuilder {
         *
         * @var string
         */
-       protected $extensionName = 'Extbase';
+       protected $extensionName;
 
        /**
         * The default controller name
         *
         * @var string
         */
-       protected $defaultControllerName = 'Standard';
+       protected $defaultControllerName;
 
        /**
         * The default action of the default controller
         *
         * @var string
         */
-       protected $defaultActionName = 'index';
+       protected $defaultActionName;
 
        /**
         * The allowed actions of the controller. This actions can be called via $_GET and $_POST.
         *
         * @var array
         */
-       protected $allowedControllerActions;
+       protected $allowedControllerActions = array();
 
-       public function initialize($configuration) {
-               if (!empty($configuration['pluginName'])) {
-                       $this->pluginName = $configuration['pluginName'];
-               }
-               if (!empty($configuration['extensionName'])) {
-                       $this->extensionName = $configuration['extensionName'];
-               }
-               if (!empty($configuration['controller'])) {
-                       $this->defaultControllerName = $configuration['controller'];
-               } elseif (is_array($configuration['switchableControllerActions'])) {
-                       $firstControllerActions = current($configuration['switchableControllerActions']);
-                       $this->defaultControllerName = $firstControllerActions['controller'];
+       /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        */
+       protected $configurationManager;
+
+       /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
+        * Injects the object manager
+        *
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
+        * @return void
+        */
+       protected function loadDefaultValues() {
+               $configuration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if (empty($configuration['extensionName'])) {
+                       throw new Tx_Extbase_MVC_Exception('"extensionName" is not properly configured. Request can\'t be dispatched!', 1289843275);
                }
-               if (!empty($configuration['action'])) {
-                       $this->defaultActionName = $configuration['action'];
-               } elseif (is_array($configuration['switchableControllerActions'])) {
-                       $firstControllerActions = current($configuration['switchableControllerActions']);
-                       $this->defaultActionName = array_shift(t3lib_div::trimExplode(',', $firstControllerActions['actions'], TRUE));
+               if (empty($configuration['pluginName'])) {
+                       throw new Tx_Extbase_MVC_Exception('"pluginName" is not properly configured. Request can\'t be dispatched!', 1289843277);
                }
+               $this->extensionName = $configuration['extensionName'];
+               $this->pluginName = $configuration['pluginName'];
+
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               $controllerConfiguration = $frameworkConfiguration['controllerConfiguration'];
+               $this->defaultControllerName = current(array_keys($controllerConfiguration));
+               $this->defaultActionName = current($controllerConfiguration[$this->defaultControllerName]['actions']);
+
                $allowedControllerActions = array();
-               if (is_array($configuration['switchableControllerActions'])) {
-                       foreach ($configuration['switchableControllerActions'] as $controller => $controllerConfiguration) {\r
-                               $controllerActions = t3lib_div::trimExplode(',', $controllerConfiguration['actions'], TRUE);\r
-                               foreach ($controllerActions as $actionName) {
-                                       $allowedControllerActions[$controller][] = $actionName;\r
-                               }
-                       }
+               foreach ($controllerConfiguration as $controllerName => $controllerActions) {
+                       $allowedControllerActions[$controllerName] = $controllerActions['actions'];
                }
                $this->allowedControllerActions = $allowedControllerActions;
        }
@@ -108,22 +130,23 @@ class Tx_Extbase_MVC_Web_RequestBuilder {
         * @return Tx_Extbase_MVC_Web_Request The web request as an object
         */
        public function build() {
-               $parameters = t3lib_div::_GPmerged('tx_' . strtolower($this->extensionName) . '_' . strtolower($this->pluginName));
+               $this->loadDefaultValues();
+               $pluginNamespace = Tx_Extbase_Utility_Extension::getPluginNamespace($this->extensionName, $this->pluginName);
+               $parameters = t3lib_div::_GPmerged($pluginNamespace);
 
                if (is_string($parameters['controller']) && array_key_exists($parameters['controller'], $this->allowedControllerActions)) {
                        $controllerName = filter_var($parameters['controller'], FILTER_SANITIZE_STRING);
-                       $allowedActions = $this->allowedControllerActions[$controllerName];
-                       if (is_string($parameters['action']) && is_array($allowedActions) && in_array($parameters['action'], $allowedActions)) {
-                               $actionName = filter_var($parameters['action'], FILTER_SANITIZE_STRING);
-                       } else {
-                               $actionName = $this->defaultActionName;
-                       }
                } else {
                        $controllerName = $this->defaultControllerName;
+               }
+               $allowedActions = $this->allowedControllerActions[$controllerName];
+               if (is_string($parameters['action']) && is_array($allowedActions) && in_array($parameters['action'], $allowedActions)) {
+                       $actionName = filter_var($parameters['action'], FILTER_SANITIZE_STRING);
+               } else {
                        $actionName = $this->defaultActionName;
-               }                               
-               
-               $request = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Request');
+               }
+
+               $request = $this->objectManager->create('Tx_Extbase_MVC_Web_Request');
                $request->setPluginName($this->pluginName);
                $request->setControllerExtensionName($this->extensionName);
                $request->setControllerName($controllerName);
@@ -135,7 +158,7 @@ class Tx_Extbase_MVC_Web_RequestBuilder {
                if (is_string($parameters['format']) && (strlen($parameters['format']))) {
                        $request->setFormat(filter_var($parameters['format'], FILTER_SANITIZE_STRING));
                }
-               
+
                foreach ($parameters as $argumentName => $argumentValue) {
                        $request->setArgument($argumentName, $argumentValue);
                }
index c79b74d..eb1817f 100644 (file)
 class Tx_Extbase_MVC_Web_Routing_UriBuilder {
 
        /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
+
+       /**
         * An instance of tslib_cObj
         *
         * @var tslib_cObj
@@ -96,12 +101,17 @@ class Tx_Extbase_MVC_Web_Routing_UriBuilder {
        protected $format = '';
 
        /**
-        * Constructs this URI Helper
-        *
-        * @param tslib_cObj $contentObject
+        * @var string
         */
-       public function __construct(tslib_cObj $contentObject = NULL) {
-               $this->contentObject = $contentObject !== NULL ? $contentObject : t3lib_div::makeInstance('tslib_cObj');
+       protected $argumentPrefix = NULL;
+
+       /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+               $this->contentObject = $this->configurationManager->getContentObject();
        }
 
        /**
@@ -249,6 +259,24 @@ class Tx_Extbase_MVC_Web_Routing_UriBuilder {
        }
 
        /**
+        * Specifies the prefix to be used for all arguments.
+        *
+        * @param string $argumentPrefix
+        * @return Tx_Extbase_MVC_Web_Routing_UriBuilder the current UriBuilder to allow method chaining
+        */
+       public function setArgumentPrefix($argumentPrefix) {
+               $this->argumentPrefix = (string)$argumentPrefix;
+               return $this;
+       }
+
+       /**
+        * @return string
+        */
+       public function getArgumentPrefix() {
+               return $this->argumentPrefix;
+       }
+
+       /**
         * If set, URIs for pages without access permissions will be created
         *
         * @param boolean $linkAccessRestrictedPages
@@ -381,6 +409,7 @@ class Tx_Extbase_MVC_Web_Routing_UriBuilder {
                $this->targetPageType = 0;
                $this->noCache = FALSE;
                $this->useCacheHash = TRUE;
+               $this->argumentPrefix = NULL;
 
                return $this;
        }
@@ -410,14 +439,24 @@ class Tx_Extbase_MVC_Web_Routing_UriBuilder {
                if ($extensionName === NULL) {
                        $extensionName = $this->request->getControllerExtensionName();
                }
+               if ($pluginName === NULL && TYPO3_MODE === 'FE') {
+                       $pluginName = Tx_Extbase_Utility_Extension::getPluginNameByAction($extensionName, $controllerArguments['controller'], $controllerArguments['action']);
+               }
                if ($pluginName === NULL) {
                        $pluginName = $this->request->getPluginName();
                }
+               if ($this->targetPageUid === NULL && TYPO3_MODE === 'FE') {
+                       $this->targetPageUid = Tx_Extbase_Utility_Extension::getTargetPidByPlugin($extensionName, $pluginName);
+               }
                if ($this->format !== '') {
                        $controllerArguments['format'] = $this->format;
                }
-               $argumentPrefix = strtolower('tx_' . $extensionName . '_' . $pluginName);
-               $prefixedControllerArguments = array($argumentPrefix => $controllerArguments);
+               $pluginNamespace = Tx_Extbase_Utility_Extension::getPluginNamespace($extensionName, $pluginName);
+               if ($this->argumentPrefix !== NULL) {
+                       $prefixedControllerArguments = array($this->argumentPrefix => $controllerArguments);
+               } else {
+                       $prefixedControllerArguments = array($pluginNamespace => $controllerArguments);
+               }
                $this->arguments = t3lib_div::array_merge_recursive_overrule($this->arguments, $prefixedControllerArguments);
 
                return $this->build();
diff --git a/typo3/sysext/extbase/Classes/Object/Container/ClassInfo.php b/typo3/sysext/extbase/Classes/Object/Container/ClassInfo.php
new file mode 100644 (file)
index 0000000..15ff738
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Extbase Team
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Value object containing the relevant informations for a class,
+ * this object is build by the classInfoFactory - or could also be restored from a cache
+ * 
+ * @author Daniel Pötzinger
+ */
+class Tx_Extbase_Object_Container_ClassInfo {
+
+       /**
+        * The classname of the class where the infos belong to
+        * @var string
+        */
+       private $className;
+
+       /**
+        * The constructor Dependencies for the class in the format:
+        *       array(
+        *     0 => array( <-- parameters for argument 1
+        *       'name' => <arg name>, <-- name of argument
+        *       'dependency' => <classname>, <-- if the argument is a class, the type of the argument
+        *       'defaultvalue' => <mixed>) <-- if the argument is optional, its default value
+        *     ),
+        *     1 => ...
+        *   )
+        * 
+        * @var array
+        */
+       private $constructorArguments;
+       
+       /**
+        * All setter injections in the format
+        *      array (<nameOfMethod> => <classNameToInject> )
+        * 
+        * @var array
+        */
+       private $injectMethods;
+
+       /**
+        * 
+        * @param string $className
+        * @param array $constructorArguments
+        * @param array $injectMethods
+        */
+       public function __construct($className, array $constructorArguments, array $injectMethods) {
+               $this->className = $className;
+               $this->constructorArguments = $constructorArguments;
+               $this->injectMethods = $injectMethods;
+       }
+       
+       /**
+        * @return the $className
+        */
+       public function getClassName() {
+               return $this->className;
+       }
+
+       /**
+        * @return the $constructorArguments
+        */
+       public function getConstructorArguments() {
+               return $this->constructorArguments;
+       }
+
+       /**
+        * @return the $injectMethods
+        */
+       public function getInjectMethods() {
+               return $this->injectMethods;
+       }
+       
+       /**
+        * @return the $injectMethods
+        */
+       public function hasInjectMethods() {
+               return (count($this->injectMethods) > 0);
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Container/ClassInfoCache.php b/typo3/sysext/extbase/Classes/Object/Container/ClassInfoCache.php
new file mode 100644 (file)
index 0000000..e621cf6
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Extbase Team
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Simple Cache for classInfos
+ *
+ * @author Daniel Pötzinger
+ */
+class Tx_Extbase_Object_Container_ClassInfoCache {
+
+       /**
+        *
+        * @var array
+        */
+       private $level1Cache=array();
+
+       /**
+        *
+        * @var t3lib_cache_frontend_VariableFrontend
+        */
+       private $level2Cache;
+
+       /**
+        * constructor
+        */
+       public function __construct() {
+               $this->initializeLevel2Cache();
+       }
+
+       /**
+        * checks if cacheentry exists for id
+        * @param string $id
+        */
+       public function has($id) {
+               return isset($this->level1Cache[$id]) || $this->level2Cache->has($id);
+       }
+
+       /**
+        * Gets the cache for the id
+        * @param string $id
+        */
+       public function get($id) {
+               if (!isset($this->level1Cache[$id])) {
+                       $this->level1Cache[$id] = $this->level2Cache->get($id);
+               }
+               return $this->level1Cache[$id];
+       }
+
+       /**
+        * sets the cache for the id
+        *
+        * @param $id
+        * @param $value
+        */
+       public function set($id,$value) {
+               $this->level1Cache[$id]=$value;
+               $this->level2Cache->set($id,$value);
+       }
+
+
+       /**
+        * Initialize the TYPO3 second level cache
+        */
+       private function initializeLevel2Cache() {
+               t3lib_cache::initializeCachingFramework();
+               try {
+                       $this->level2Cache = $GLOBALS['typo3CacheManager']->getCache('cache_extbase_object');
+               } catch (t3lib_cache_exception_NoSuchCache $exception) {
+                       $this->level2Cache = $GLOBALS['typo3CacheFactory']->create(
+                               'cache_extbase_object',
+                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_object']['frontend'],
+                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_object']['backend'],
+                               $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_object']['options']
+                       );
+               }
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Container/ClassInfoFactory.php b/typo3/sysext/extbase/Classes/Object/Container/ClassInfoFactory.php
new file mode 100644 (file)
index 0000000..3985f54
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Extbase Team
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * TYPO3 Dependency Injection container
+ *
+ * @author Daniel Pötzinger
+ */
+class Tx_Extbase_Object_Container_ClassInfoFactory {
+
+       /**
+        * Factory metod that builds a ClassInfo Object for the given classname - using reflection
+        *
+        * @param string $className The class name to build the class info for
+        * @return Tx_Extbase_Object_Container_ClassInfo the class info
+        */
+       public function buildClassInfoFromClassName($className) {
+               try {
+                       $reflectedClass = new ReflectionClass($className);
+               } catch (Exception $e) {
+                       throw new Tx_Extbase_Object_Container_Exception_UnknownObjectException('Could not analyse class:' . $className . ' maybe not loaded or no autoloader?', 1289386765);
+               }
+               $constructorArguments = $this->getConstructorArguments($reflectedClass);
+               $injectMethods = $this->getInjectMethods($reflectedClass);
+               return new Tx_Extbase_Object_Container_ClassInfo($className, $constructorArguments, $injectMethods);
+       }
+
+       /**
+        * Build a list of constructor arguments
+        *
+        * @param ReflectionClass $reflectedClass
+        * @return array of parameter infos for constructor
+        */
+       private function getConstructorArguments(ReflectionClass $reflectedClass) {
+               $reflectionMethod = $reflectedClass->getConstructor();
+               if (!is_object($reflectionMethod)) {
+                       return array();
+               }
+               $result = array();
+               foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
+                       /* @var $reflectionParameter ReflectionParameter */
+                       $info = array();
+
+                       $info['name'] = $reflectionParameter->getName();
+
+                       if ($reflectionParameter->getClass()) {
+                               $info['dependency'] = $reflectionParameter->getClass()->getName();
+                       }
+                       if ($reflectionParameter->isOptional()) {
+                               $info['defaultValue'] = $reflectionParameter->getDefaultValue();
+                       }
+
+                       $result[] = $info;
+               }
+               return $result;
+       }
+
+       /**
+        * Build a list of inject methods
+
+        * @param ReflectionClass $reflectedClass
+        * @retrn array of inject methods
+        */
+       private function getInjectMethods(ReflectionClass $reflectedClass) {
+               $result = array();
+               $reflectionMethods = $reflectedClass->getMethods();
+
+               if (is_array($reflectionMethods)) {
+                       foreach ($reflectionMethods as $reflectionMethod) {
+                               if ($reflectionMethod->isPublic() && substr($reflectionMethod->getName(), 0, 6) === 'inject') {
+                                       $reflectionParameter = $reflectionMethod->getParameters();
+                                       if (isset($reflectionParameter[0])) {
+                                               if (!$reflectionParameter[0]->getClass()) {
+                                                       throw new Exception('Method is marked as setter for Dependency Injection, but doesnt have a type annotation');
+                                               }
+                                               $result[$reflectionMethod->getName()] = $reflectionParameter[0]->getClass()->getName();
+                                       }
+                               }
+                       }
+               }
+               return $result;
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Container/Container.php b/typo3/sysext/extbase/Classes/Object/Container/Container.php
new file mode 100644 (file)
index 0000000..5de5cfe
--- /dev/null
@@ -0,0 +1,269 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Extbase Team
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * TYPO3 Dependency Injection container
+ * Initial Usage:
+ *  $container = Tx_Extbase_Object_Container_Container::getContainer()
+ *
+ * @author Daniel Pötzinger
+ */
+class Tx_Extbase_Object_Container_Container {
+
+       /**
+        * PHP singleton impelementation
+        *
+        * @var Tx_Extbase_Object_Container_Container
+        */
+       static private $containerInstance = null;
+
+       /**
+        * internal cache for classinfos
+        *
+        * @var Tx_Extbase_Object_Container_ClassInfoCache
+        */
+       private $cache;
+
+       /**
+        * registered alternative implementations of a class
+        * e.g. used to know the class for a AbstractClass or a Dependency
+        *
+        * @var array
+        */
+       private $alternativeImplementation;
+
+       /**
+        * reference to the classinfofactory, that analyses dependencys
+        * @var classInfoFactory
+        */
+       private $classInfoFactory;
+
+       /**
+        * holds references of singletons
+        * @var array
+        */
+       private $singletonInstances = array();
+
+       /**
+        * holds references of objects that still needs setter injection processing
+        * @var array
+        */
+       private $setterInjectionRegistry = array();
+
+       /**
+        * Constructor is protected since container should
+        * be a singleton.
+        *
+        * @see getContainer()
+        * @param void
+        * @return void
+        */
+       protected function __construct() {
+               $this->classInfoFactory = new Tx_Extbase_Object_Container_ClassInfoFactory();
+               $this->cache = new Tx_Extbase_Object_Container_ClassInfoCache();
+       }
+
+       /**
+        * Returns an instance of the container singleton.
+        *
+        * @return Tx_Extbase_Object_Container_Container
+        */
+       static public function getContainer() {
+               if (self::$containerInstance === NULL) {
+                       self::$containerInstance = new Tx_Extbase_Object_Container_Container();
+               }
+               return self::$containerInstance;
+       }
+
+       private function __clone() {}
+
+       /**
+        * gets an instance of the given class
+        * @param string $className
+        * @return object
+        */
+       public function getInstance($className) {
+               $givenConstructorArguments=array();
+               if (func_num_args() > 1) {
+                               $givenConstructorArguments = func_get_args();
+                               array_shift($givenConstructorArguments);
+               }
+               $object = $this->getInstanceFromClassName($className, $givenConstructorArguments, 0);
+               $this->processSetterInjectionRegistry();
+               return $object;
+       }
+
+       /**
+        * register a classname that should be used if a dependency is required.
+        * e.g. used to define default class for a interface
+        *
+        * @param string $className
+        * @param string $alternativeClassName
+        */
+       public function registerImplementation($className,$alternativeClassName) {
+               $this->alternativeImplementation[$className] = $alternativeClassName;
+       }
+
+       /**
+        * gets an instance of the given class
+        * @param string $className
+        * @param array $givenConstructorArguments
+        */
+       private function getInstanceFromClassName($className, array $givenConstructorArguments=array(), $level=0) {
+               if ($level > 30) {
+                       throw new Tx_Extbase_Object_Container_Exception_TooManyRecursionLevelsException('Too many recursion levels. This should never happen, please file a bug!' . $className, 1289386945);
+               }
+               if ($className === 'Tx_Extbase_Object_Container_Container') {
+                       return $this;
+               }
+               if (isset($this->singletonInstances[$className])) {
+                       return $this->singletonInstances[$className];
+               }
+
+               $className = $this->getClassName($className);
+
+               $classInfo = $this->getClassInfo($className);
+
+               $constructorArguments = $this->getConstructorArguments($classInfo->getConstructorArguments(), $givenConstructorArguments, $level);
+               $instance = $this->newObject($className, $constructorArguments);
+
+               if ($level > 0 && !($instance instanceof t3lib_Singleton)) {
+                       throw new Tx_Extbase_Object_Exception_WrongScope('Object "' . $className . '" is of not of scope singleton, but only singleton instances can be injected into other classes.', 1289387047);
+               }
+
+               if ($classInfo->hasInjectMethods()) {
+                       $this->setterInjectionRegistry[]=array($instance, $classInfo->getInjectMethods(), $level);
+               }
+
+               if ($instance instanceof t3lib_Singleton) {
+                       $this->singletonInstances[$className] = $instance;
+               }
+               return $instance;
+       }
+
+       /**
+        * returns a object of the given type, called with the constructor arguments.
+        * For speed improvements reflection is avoided
+        *
+        * @param string $className
+        * @param array $constructorArguments
+        */
+       private function newObject($className, array $constructorArguments) {
+               array_unshift($constructorArguments, $className);
+               return call_user_func_array(array('t3lib_div', 'makeInstance'), $constructorArguments);
+       }
+
+       /**
+        * gets array of parameter that can be used to call a constructor
+        *
+        * @param array $constructorArgumentInformation
+        * @param array $givenConstructorArguments
+        * @return array
+        */
+       private function getConstructorArguments(array $constructorArgumentInformation, array $givenConstructorArguments, $level) {
+               $parameters=array();
+               foreach ($constructorArgumentInformation as $argumentInformation) {
+                       $argumentName = $argumentInformation['name'];
+
+                       if (count($givenConstructorArguments)) {
+                               // we have a value to set
+                               $parameter = array_shift($givenConstructorArguments);
+                       } elseif (isset($argumentInformation['dependency'])) {
+                               // Inject parameter
+                               $parameter = $this->getInstanceFromClassName($argumentInformation['dependency'], array(), $level+1);
+                       } elseif (isset($argumentInformation['defaultValue'])) {
+                               // no value to set anymore, we take default value
+                               $parameter = $argumentInformation['defaultValue'];
+                       } else {
+                               throw new InvalidArgumentException('not a correct info array of constructor dependencies was passed!');
+                       }
+                       $parameters[] = $parameter;
+               }
+               return $parameters;
+       }
+
+       /**
+        * Returns the class name for a new instance, taking into account the
+        * class-extension API.
+        *
+        * @param       string          Base class name to evaluate
+        * @return      string          Final class name to instantiate with "new [classname]"
+        */
+       protected function getClassName($className) {
+               if (isset($this->alternativeImplementation[$className])) {
+                       $className = $this->alternativeImplementation[$className];
+               }
+
+               if (substr($className, -9) === 'Interface') {
+                       $className = substr($className, 0, -9);
+               }
+
+               return $className;
+       }
+
+       /**
+        * do inject dependecies to object $instance using the given methods
+        *
+        * @param object $instance
+        * @param array $setterMethods
+        * @param integer $level
+        */
+       private function handleSetterInjection($instance, array $setterMethods, $level) {
+               foreach ($setterMethods as $method => $dependency) {
+                       $instance->$method($this->getInstanceFromClassName($dependency, array(), $level+1));
+               }
+       }
+
+       /**
+        * Gets Classinfos for the className - using the cache and the factory
+        *
+        * @param string $className
+        * @return Tx_Extbase_Object_Container_ClassInfo
+        */
+       private function getClassInfo($className) {
+               if (!$this->cache->has($className)) {
+                       $this->cache->set($className, $this->classInfoFactory->buildClassInfoFromClassName($className));
+               }
+               return $this->cache->get($className);
+       }
+
+       /**
+        * does setter injection based on the data in $this->setterInjectionRegistry
+        * Its done as long till no setters are left
+        *
+        * @return void
+        */
+       private function processSetterInjectionRegistry() {
+               while (count($this->setterInjectionRegistry)>0) {
+                       $currentSetterData = $this->setterInjectionRegistry;
+                       $this->setterInjectionRegistry = array();
+                       foreach ($currentSetterData as $setterInjectionData) {
+                               $this->handleSetterInjection($setterInjectionData[0], $setterInjectionData[1], $setterInjectionData[2]);
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Container/Exception/CannotInitializeCacheException.php b/typo3/sysext/extbase/Classes/Object/Container/Exception/CannotInitializeCacheException.php
new file mode 100644 (file)
index 0000000..c81f174
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Extbase Team
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Exception thrown if cache cannot be built.
+ */
+class Tx_Extbase_Object_Container_Exception_CannotInitializeCacheException extends Tx_Extbase_Object_Exception {
+}
+?>
diff --git a/typo3/sysext/extbase/Classes/Object/Container/Exception/TooManyRecursionLevelsException.php b/typo3/sysext/extbase/Classes/Object/Container/Exception/TooManyRecursionLevelsException.php
new file mode 100644 (file)
index 0000000..9cee780
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Extbase Team
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Exception thrown if cache cannot be built.
+ */
+class Tx_Extbase_Object_Container_Exception_TooManyRecursionLevelsException extends Tx_Extbase_Object_Exception {
+}
+?>
diff --git a/typo3/sysext/extbase/Classes/Object/Container/Exception/UnknownObjectException.php b/typo3/sysext/extbase/Classes/Object/Container/Exception/UnknownObjectException.php
new file mode 100644 (file)
index 0000000..8a55729
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * "Unknown Object" Exception
+ *
+ * @package Extbase
+ * @subpackage Object\Exception
+ * @version $Id: UnknownObjectException.php 2703 2010-11-10 11:28:01Z sebastian $
+ */
+class Tx_Extbase_Object_Container_Exception_UnknownObjectException extends Tx_Extbase_Object_Exception {
+
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/Exception/UnknownObject.php b/typo3/sysext/extbase/Classes/Object/Exception/UnknownObject.php
deleted file mode 100644 (file)
index a57227c..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
-*  All rights reserved
-*
-*  This class is a backport of the corresponding class of FLOW3.
-*  All credits go to the v5 team.
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-/**
- * "Unknown Object" Exception
- *
- * @package Extbase
- * @subpackage Object\Exception
- * @version $Id: UnknownObject.php 1729 2009-11-25 21:37:20Z stucki $
- */
-class Tx_Extbase_Object_UnknownObject extends Tx_Extbase_Object_Exception {
-
-}
-
-?>
\ No newline at end of file
index 954fd33..64548c6 100644 (file)
@@ -32,7 +32,7 @@
  * @subpackage Object\Exception
  * @version $Id: WrongScope.php 1729 2009-11-25 21:37:20Z stucki $
  */
-class Tx_Extbase_Object_WrongScope extends Tx_Extbase_Object_Exception {
+class Tx_Extbase_Object_Exception_WrongScope extends Tx_Extbase_Object_Exception {
 
 }
 
diff --git a/typo3/sysext/extbase/Classes/Object/Manager.php b/typo3/sysext/extbase/Classes/Object/Manager.php
deleted file mode 100644 (file)
index 4202fca..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
-*  All rights reserved
-*
-*  This class is a backport of the corresponding class of FLOW3.
-*  All credits go to the v5 team.
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-/**
- * Implementation of the default Extbase Object Manager
- *
- * @package Extbase
- * @subpackage Object
- * @version $Id: Manager.php 1729 2009-11-25 21:37:20Z stucki $
- */
-class Tx_Extbase_Object_Manager implements Tx_Extbase_Object_ManagerInterface, t3lib_Singleton {
-
-       /**
-        * @var Tx_Extbase_Object_RegistryInterface
-        */
-       protected $singletonObjectsRegistry;
-
-       /**
-        * Constructs a new Object Manager
-        */
-       public function __construct() {
-               $this->singletonObjectsRegistry = t3lib_div::makeInstance('Tx_Extbase_Object_TransientRegistry'); // singleton
-       }
-
-       /**
-        * Returns a fresh or existing instance of the object specified by $objectName.
-        *
-        * Important:
-        *
-        * If possible, instances of Prototype objects should always be created with the
-        * Object Factory's create() method and Singleton objects should rather be
-        * injected by some type of Dependency Injection.
-        *
-        * @param string $objectName The name of the object to return an instance of
-        * @return object The object instance
-        * // TODO This is not part of the official API! Explain why.
-        */
-       public function getObject($objectName) {
-               if (in_array('t3lib_Singleton', class_implements($objectName))) {
-                       if ($this->singletonObjectsRegistry->objectExists($objectName)) {
-                               $object = $this->singletonObjectsRegistry->getObject($objectName);
-                       } else {
-                               $arguments = array_slice(func_get_args(), 1);
-                               $object = $this->makeInstance($objectName, $arguments);
-                               $this->singletonObjectsRegistry->putObject($objectName, $object);
-                       }
-               } else {
-                       $arguments = array_slice(func_get_args(), 1);
-                       $object = $this->makeInstance($objectName, $arguments);
-               }
-               return $object;
-       }
-
-       /**
-        * Speed optimized alternative to ReflectionClass::newInstanceArgs().
-        * Delegates the instanciation to the makeInstance method of t3lib_div.
-        *
-        * @param string $objectName Name of the object to instantiate
-        * @param array $arguments Arguments to pass to t3lib_div::makeInstance
-        * @return object The object
-        */
-       protected function makeInstance($objectName, array $arguments) {
-               switch (count($arguments)) {
-                       case 0: return t3lib_div::makeInstance($objectName);
-                       case 1: return t3lib_div::makeInstance($objectName, $arguments[0]);
-                       case 2: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1]);
-                       case 3: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2]);
-                       case 4: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3]);
-                       case 5: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]);
-                       case 6: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
-                       case 7: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
-                       case 8: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
-                       case 9: return t3lib_div::makeInstance($objectName, $arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
-               }
-               throw new Tx_Extbase_Object_Exception_CannotBuildObject('Object "' . $objectName . '" has too many arguments.', 1166550023);
-       }
-
-
-}
-
-?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/ManagerInterface.php b/typo3/sysext/extbase/Classes/Object/ManagerInterface.php
deleted file mode 100644 (file)
index f241bf7..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
-*  All rights reserved
-*
-*  This class is a backport of the corresponding class of FLOW3.
-*  All credits go to the v5 team.
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-/**
- * Interface for the TYPO3 Object Manager
- *
- * @package Extbase
- * @subpackage Object
- * @version $Id: ManagerInterface.php 1729 2009-11-25 21:37:20Z stucki $
- */
-interface Tx_Extbase_Object_ManagerInterface {
-
-       /**
-        * Returns a fresh or existing instance of the object specified by $objectName.
-        *
-        * Important:
-        *
-        * If possible, instances of Prototype objects should always be created with the
-        * Object Factory's create() method and Singleton objects should rather be
-        * injected by some type of Dependency Injection.
-        *
-        * @param string $objectName The name of the object to return an instance of
-        * @return object The object instance
-        */
-       public function getObject($objectName);
-
-}
-
-?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/ObjectManager.php b/typo3/sysext/extbase/Classes/Object/ObjectManager.php
new file mode 100644 (file)
index 0000000..12916a7
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Implementation of the default Extbase Object Manager
+ *
+ * @package Extbase
+ * @subpackage Object
+ */
+class Tx_Extbase_Object_ObjectManager implements Tx_Extbase_Object_ObjectManagerInterface {
+
+       /**
+        * @var Tx_Extbase_Object_Container_Container
+        */
+       protected $objectContainer;
+
+       /**
+        * Constructs a new Object Manager
+        */
+       public function __construct() {
+               $this->objectContainer = Tx_Extbase_Object_Container_Container::getContainer();
+       }
+
+       /**
+        * Returns a fresh or existing instance of the object specified by $objectName.
+        *
+        * Important:
+        *
+        * If possible, instances of Prototype objects should always be created with the
+        * Object Manager's create() method and Singleton objects should rather be
+        * injected by some type of Dependency Injection.
+        *
+        * @param string $objectName The name of the object to return an instance of
+        * @return object The object instance
+        * @api
+        */
+       public function get($objectName) {
+               $arguments = func_get_args();
+               return call_user_func_array(array($this->objectContainer, 'getInstance'), $arguments);
+       }
+
+       /**
+        * Creates a fresh instance of the object specified by $objectName.
+        *
+        * This factory method can only create objects of the scope prototype.
+        * Singleton objects must be either injected by some type of Dependency Injection or
+        * if that is not possible, be retrieved by the get() method of the
+        * Object Manager
+        *
+        * @param string $objectName The name of the object to create
+        * @return object The new object instance
+        * @throws Tx_Extbase_Object_Exception_WrongScropeException if the created object is not of scope prototype
+        * @api
+        */
+       public function create($objectName) {
+               $arguments = func_get_args();
+               $instance = call_user_func_array(array($this->objectContainer, 'getInstance'), $arguments);
+
+               if ($instance instanceof t3lib_Singleton) {
+                       throw new Tx_Extbase_Object_Exception_WrongScope('Object "' . $objectName . '" is of not of scope prototype, but only prototype is supported by create()', 1265203124);
+               }
+
+               return $instance;
+       }
+}
+
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/ObjectManagerInterface.php b/typo3/sysext/extbase/Classes/Object/ObjectManagerInterface.php
new file mode 100644 (file)
index 0000000..c408b0c
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3. 
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Interface for the TYPO3 Object Manager
+ *
+ * @package Extbase
+ * @subpackage Object
+ */
+interface Tx_Extbase_Object_ObjectManagerInterface extends t3lib_Singleton {
+    /**
+     * Returns a fresh or existing instance of the object specified by $objectName.
+     *
+     * Important:
+     *
+     * If possible, instances of Prototype objects should always be created with the
+     * Object Manager's create() method and Singleton objects should rather be
+     * injected by some type of Dependency Injection.
+     *
+     * @param string $objectName The name of the object to return an instance of
+     * @return object The object instance
+     * @api
+     */
+    public function get($objectName);
+
+       /**
+        * Creates a fresh instance of the object specified by $objectName.
+        *
+        * This factory method can only create objects of the scope prototype.
+        * Singleton objects must be either injected by some type of Dependency Injection or
+        * if that is not possible, be retrieved by the get() method of the
+        * Object Manager
+        *
+        * @param string $objectName The name of the object to create
+        * @return object The new object instance
+        * @throws Tx_Extbase_Object_Exception_WrongScropeException if the created object is not of scope prototype
+        * @api
+        */
+       public function create($objectName);
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/RegistryInterface.php b/typo3/sysext/extbase/Classes/Object/RegistryInterface.php
deleted file mode 100644 (file)
index 7149f90..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
-*  All rights reserved
-*
-*  This class is a backport of the corresponding class of FLOW3.
-*  All credits go to the v5 team.
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-/**
- * Object Object Cache Interface
- *
- * @package Extbase
- * @subpackage Object
- * @version $Id: RegistryInterface.php 1729 2009-11-25 21:37:20Z stucki $
- */
-interface Tx_Extbase_Object_RegistryInterface {
-
-       /**
-        * Returns an object from the registry. If an instance of the required
-        * object does not exist yet, an exception is thrown.
-        *
-        * @param string $objectName Name of the object to return an object of
-        * @return object The object
-        */
-       public function getObject($objectName);
-
-       /**
-        * Put an object into the registry.
-        *
-        * @param string $objectName Name of the object the object is made for
-        * @param object $object The object to store in the registry
-        * @return void
-        */
-       public function putObject($objectName, $object);
-
-       /**
-        * Remove an object from the registry.
-        *
-        * @param string $objectName Name of the object to remove the object for
-        * @return void
-        */
-       public function removeObject($objectName);
-
-       /**
-        * Checks if an object of the given object already exists in the object registry.
-        *
-        * @param string $objectName Name of the object to check for an object
-        * @return boolean TRUE if an object exists, otherwise FALSE
-        */
-       public function objectExists($objectName);
-}
-
-?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Object/TransientRegistry.php b/typo3/sysext/extbase/Classes/Object/TransientRegistry.php
deleted file mode 100644 (file)
index 93de9a9..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
-*  All rights reserved
-*
-*  This class is a backport of the corresponding class of FLOW3.
-*  All credits go to the v5 team.
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-
-/**
- * A transient Object Object Cache which provides a transient memory-based
- * registry of objects.
- *
- * @package Extbase
- * @subpackage Object
- * @version $Id: TransientRegistry.php 1729 2009-11-25 21:37:20Z stucki $
- */
-class Tx_Extbase_Object_TransientRegistry implements Tx_Extbase_Object_RegistryInterface {
-
-       /**
-        * @var array Location where objects are stored
-        */
-       protected $objects = array();
-
-       /**
-        * Returns an object from the registry. If an instance of the required
-        * object does not exist yet, an exception is thrown.
-        *
-        * @param string $objectName Name of the object to return an object of
-        * @return object The object
-        */
-       public function getObject($objectName) {
-               if (!$this->objectExists($objectName)) throw new RuntimeException('Object "' . $objectName . '" does not exist in the object registry.', 1167917198);
-               return $this->objects[$objectName];
-       }
-
-       /**
-        * Put an object into the registry.
-        *
-        * @param string $objectName Name of the object the object is made for
-        * @param object $object The object to store in the registry
-        * @return void
-        */
-       public function putObject($objectName, $object) {
-               if (!is_string($objectName) || strlen($objectName) === 0) throw new RuntimeException('No valid object name specified.', 1167919564);
-               if (!is_object($object)) throw new RuntimeException('$object must be of type Object', 1167917199);
-               $this->objects[$objectName] = $object;
-       }
-
-       /**
-        * Remove an object from the registry.
-        *
-        * @param string objectName Name of the object to remove the object for
-        * @return void
-        */
-       public function removeObject($objectName) {
-               if (!$this->objectExists($objectName)) throw new RuntimeException('Object "' . $objectName . '" does not exist in the object registry.', 1167917200);
-               unset ($this->objects[$objectName]);
-       }
-
-       /**
-        * Checks if an object of the given object already exists in the object registry.
-        *
-        * @param string $objectName Name of the object to check for an object
-        * @return boolean TRUE if an object exists, otherwise FALSE
-        */
-       public function objectExists($objectName) {
-               return isset($this->objects[$objectName]);
-       }
-
-}
-
-?>
\ No newline at end of file
index 1407c08..722ec34 100644 (file)
@@ -66,7 +66,7 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
        protected $queryFactory;
 
        /**
-        * @var Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface
+        * @var Tx_Extbase_Persistence_QOM_QueryObjectModelFactory
         */
        protected $qomFactory;
 
@@ -88,23 +88,37 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
        protected $referenceIndex;
 
        /**
-        * @var array
-        **/
-       protected $extbaseSettings;
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
 
        /**
         * Constructs the backend
         *
-        * @param Tx_Extbase_Persistence_Session $session The persistence session used to persist data
+        * @return void
         */
-       public function __construct(Tx_Extbase_Persistence_Session $session, Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend) {
-               $this->session = $session;
-               $this->storageBackend = $storageBackend;
-               $this->extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
-               if ($this->extbaseSettings['persistence']['updateReferenceIndex'] === '1') {
+       public function __construct(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+               $frameworkConfiguration = $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if ($frameworkConfiguration['persistence']['updateReferenceIndex'] === '1') {
                        $this->referenceIndex = t3lib_div::makeInstance('t3lib_refindex');
                }
-               $this->aggregateRootObjects = new Tx_Extbase_Persistence_ObjectStorage();
+       }
+
+       /**
+        * @param Tx_Extbase_Persistence_Session $session
+        * @return void
+        */
+       public function injectSession(Tx_Extbase_Persistence_Session $session) {
+               $this->session = $session;
+       }
+
+       /**
+        * @param Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend
+        * @return void
+        */
+       public function injectStorageBackend(Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend) {
+               $this->storageBackend = $storageBackend;
        }
 
        /**
@@ -150,24 +164,14 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
        /**
         * Injects the QueryObjectModelFactory
         *
-        * @param Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface $qomFactory
+        * @param Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory
         * @return void
         */
-       public function injectQomFactory(Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface $qomFactory) {
+       public function injectQomFactory(Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory) {
                $this->qomFactory = $qomFactory;
        }
 
        /**
-        * Injects the ValueFactory
-        *
-        * @param Tx_Extbase_Persistence_ValueFactoryInterface $valueFactory
-        * @return void
-        */
-       public function injectValueFactory(Tx_Extbase_Persistence_ValueFactoryInterface $valueFactory) {
-               $this->valueFactory = $valueFactory;
-       }
-
-       /**
         * Returns the repository session
         *
         * @return Tx_Extbase_Persistence_Session
@@ -188,7 +192,7 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
        /**
         * Returns the current QOM factory
         *
-        * @return Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface
+        * @return Tx_Extbase_Persistence_QOM_QueryObjectModelFactory
         */
        public function getQomFactory() {
                return $this->qomFactory;
@@ -262,12 +266,10 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                        return $this->identityMap->getObjectByIdentifier($identifier, $className);
                } else {
                        $query = $this->queryFactory->create($className);
-                       $result = $query->matching($query->withUid($identifier))->execute();
-                       $object = NULL;
-                       if (count($result) > 0) {
-                               $object = current($result);
-                       }
-                       return $object;
+                       return $query->matching(
+                               $query->withUid($identifier))
+                               ->execute()
+                               ->getFirst();
                }
        }
 
@@ -561,8 +563,10 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                $columnMap = $this->dataMapper->getDataMap($className)->getColumnMap($propertyName);
                $query = $this->queryFactory->create($className);
                $query->getQuerySettings()->setReturnRawQueryResult(TRUE);
-               $rows = $query->matching($query->withUid($object->getUid()))->execute();
-               $currentRow = current($rows);
+               $currentRow = $query->matching(
+                       $query->withUid($object->getUid()))
+                       ->execute()
+                       ->getFirst();
                $fieldValue = $currentRow[$columnMap->getColumnName()];
                return $fieldValue;
        }
@@ -672,7 +676,8 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                        $row
                        );
                $object->_setProperty('uid', (int)$uid);
-               if ($this->extbaseSettings['persistence']['updateReferenceIndex'] === '1') {
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if ($frameworkConfiguration['persistence']['updateReferenceIndex'] === '1') {
                        $this->referenceIndex->updateRefIndexTable($dataMap->getTableName(), $uid);
                }
                $this->identityMap->registerObject($object, $uid);
@@ -790,7 +795,8 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                        $dataMap->getTableName(),
                        $row
                        );
-               if ($this->extbaseSettings['persistence']['updateReferenceIndex'] === '1') {
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if ($frameworkConfiguration['persistence']['updateReferenceIndex'] === '1') {
                        $this->referenceIndex->updateRefIndexTable($dataMap->getTableName(), $row['uid']);
                }
                return $res;
@@ -861,7 +867,8 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
                                );
                }
                $this->removeRelatedObjects($object);
-               if ($this->extbaseSettings['persistence']['updateReferenceIndex'] === '1') {
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if ($frameworkConfiguration['persistence']['updateReferenceIndex'] === '1') {
                        $this->referenceIndex->updateRefIndexTable($tableName, $object->getUid());
                }
        }
@@ -904,14 +911,14 @@ class Tx_Extbase_Persistence_Backend implements Tx_Extbase_Persistence_BackendIn
         * @return int the storage Page ID where the object should be stored
         */
        protected function determineStoragePageIdForNewRecord(Tx_Extbase_DomainObject_DomainObjectInterface $object = NULL) {
-               $extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
                if ($object !== NULL) {
                        $className = get_class($object);
-                       if (isset($extbaseSettings['persistence']['classes'][$className]) && !empty($extbaseSettings['persistence']['classes'][$className]['newRecordStoragePid'])) {
-                               return (int)$extbaseSettings['persistence']['classes'][$className]['newRecordStoragePid'];
+                       if (isset($frameworkConfiguration['persistence']['classes'][$className]) && !empty($frameworkConfiguration['persistence']['classes'][$className]['newRecordStoragePid'])) {
+                               return (int)$frameworkConfiguration['persistence']['classes'][$className]['newRecordStoragePid'];
                        }
                }
-               $storagePidList = t3lib_div::intExplode(',', $extbaseSettings['persistence']['storagePid']);
+               $storagePidList = t3lib_div::intExplode(',', $frameworkConfiguration['persistence']['storagePid']);
                return (int) $storagePidList[0];
        }
 
index 02395ae..7ff55b5 100644 (file)
@@ -32,7 +32,7 @@
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @see \F3\TYPO3CR\FLOW3\Persistence\DataMapper, \F3\TYPO3CR\FLOW3\Persistence\Backend
  */
-class Tx_Extbase_Persistence_IdentityMap {
+class Tx_Extbase_Persistence_IdentityMap implements t3lib_Singleton {
 
        /**
         * @var Tx_Extbase_Persistence_ObjectStorage
index 44c9b72..5d888aa 100644 (file)
 class Tx_Extbase_Persistence_LazyLoadingProxy implements Iterator, Tx_Extbase_Persistence_LoadingStrategyInterface {
 
        /**
+        * @var Tx_Extbase_Persistence_DataMapper
+        */
+       protected $dataMapper;
+
+       /**
         * The object this property is contained in.
         *
         * @var object
@@ -70,6 +75,16 @@ class Tx_Extbase_Persistence_LazyLoadingProxy implements Iterator, Tx_Extbase_Pe
        }
 
        /**
+        * Injects the DataMapper to map nodes to objects
+        *
+        * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
+        * @return void
+        */
+       public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
+               $this->dataMapper = $dataMapper;
+       }
+
+       /**
         * Populate this proxy by asking the $population closure.
         *
         * @return object The instance (hopefully) returned
@@ -79,9 +94,9 @@ class Tx_Extbase_Persistence_LazyLoadingProxy implements Iterator, Tx_Extbase_Pe
                // usually that does not happen, but if the proxy is held from outside
                // it's parent... the result would be weird.
                if ($this->parentObject->_getProperty($this->propertyName) instanceof Tx_Extbase_Persistence_LazyLoadingProxy) {
-                       $dataMapper = Tx_Extbase_Dispatcher::getPersistenceManager()->getBackend()->getDataMapper();
-                       $objects = $dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE, FALSE);
-                       $propertyValue = $dataMapper->mapResultToPropertyValue($this->parentObject, $this->propertyName, $objects);
+                       
+                       $objects = $this->dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE, FALSE);
+                       $propertyValue = $this->dataMapper->mapResultToPropertyValue($this->parentObject, $this->propertyName, $objects);
                        $this->parentObject->_setProperty($this->propertyName, $propertyValue);
                        $this->parentObject->_memorizeCleanState($this->propertyName);
                        return $propertyValue;
@@ -99,6 +114,9 @@ class Tx_Extbase_Persistence_LazyLoadingProxy implements Iterator, Tx_Extbase_Pe
         */
        public function __call($methodName, $arguments) {
                $realInstance = $this->_loadRealInstance();
+               if (!is_object($realInstance)) {
+                       return NULL;
+               }
                return call_user_func_array(array($realInstance, $methodName), $arguments);
        }
 
index 46cc7d7..65e5cba 100644 (file)
  *
  * @package Extbase
  * @subpackage Persistence
- * @version $Id: LazyObjectStorage.php 2287 2010-05-25 11:09:54Z jocrau $
+ * @version $Id$
  */
 class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_ObjectStorage implements Tx_Extbase_Persistence_LoadingStrategyInterface {
 
        /**
+        * @var Tx_Extbase_Persistence_DataMapper
+        */
+       protected $dataMapper;
+
+       /**
         * The object this property is contained in.
         *
         * @var object
@@ -70,7 +75,7 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
        public function isInitialized() {
                return $this->isInitialized;
        }
-
+       
        /**
         * Constructs this proxy instance.
         *
@@ -85,15 +90,25 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
        }
 
        /**
-        * This is a function lazy load implementation.
+        * Injects the DataMapper to map nodes to objects
+        *
+        * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
+        * @return void
+        */
+       public function injectDataMapper(Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper) {
+               $this->dataMapper = $dataMapper;
+       }
+
+       /**
+        * This is a function lazy load implementation. 
         *
         * @return void
         */
        protected function initialize() {
                if (!$this->isInitialized) {
                        $this->isInitialized = TRUE;
-                       $dataMapper = Tx_Extbase_Dispatcher::getPersistenceManager()->getBackend()->getDataMapper();
-                       $objects = $dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE);
+
+                       $objects = $this->dataMapper->fetchRelated($this->parentObject, $this->propertyName, $this->fieldValue, FALSE);
                        foreach ($objects as $object) {
                                parent::attach($object);
                        }
@@ -101,7 +116,7 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
                        $this->parentObject->_memorizeCleanState($this->propertyName);
                }
        }
-
+               
        // Delegation to the ObjectStorage methods below
 
        /**
@@ -134,14 +149,13 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
         * @return int The number of elements in the ObjectStorage
         */
        public function count() {
-               $dataMapper = Tx_Extbase_Dispatcher::getPersistenceManager()->getBackend()->getDataMapper();
-               $columnMap = $dataMapper->getDataMap(get_class($this->parentObject))->getColumnMap($this->propertyName);
+               $columnMap = $this->dataMapper->getDataMap(get_class($this->parentObject))->getColumnMap($this->propertyName);
                $numberOfElements = NULL;
                if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
-                       $numberOfElements = $dataMapper->countRelated($this->parentObject, $this->propertyName, $this->fieldValue);
+                       $numberOfElements = $this->dataMapper->countRelated($this->parentObject, $this->propertyName, $this->fieldValue);
                } else {
                        $this->initialize();
-                       $numberOfElements = count($this->storage);
+                       $numberOfElements = count($this->storage);                      
                }
                if (is_null($numberOfElements)) {
                        throw new Tx_Extbase_Persistence_Exception('The number of elements could not be determined.', 1252514486);
@@ -236,7 +250,7 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
                $this->initialize();
                return parent::valid();
        }
-
+       
        /**
         * @see Tx_Extbase_Persistence_ObjectStorage::toArray
         */
@@ -244,6 +258,6 @@ class Tx_Extbase_Persistence_LazyObjectStorage extends Tx_Extbase_Persistence_Ob
                $this->initialize();
                return parent::toArray();
        }
-
+               
 }
 ?>
\ No newline at end of file
index 27cfd8d..99bcf2b 100644 (file)
@@ -46,7 +46,7 @@ class Tx_Extbase_Persistence_Manager implements Tx_Extbase_Persistence_ManagerIn
        protected $session;
 
        /**
-        * @var Tx_Extbase_Object_ManagerInterface
+        * @var Tx_Extbase_Object_ObjectManagerInterface
         */
        protected $objectManager;
 
@@ -81,10 +81,10 @@ class Tx_Extbase_Persistence_Manager implements Tx_Extbase_Persistence_ManagerIn
        /**
         * Injects the object manager
         *
-        * @param Tx_Extbase_Object_ManagerInterface $objectManager
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
         * @return void
         */
-       public function injectObjectManager(Tx_Extbase_Object_ManagerInterface $objectManager) {
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
                $this->objectManager = $objectManager;
        }
 
@@ -117,15 +117,6 @@ class Tx_Extbase_Persistence_Manager implements Tx_Extbase_Persistence_ManagerIn
        }
 
        /**
-        * Returns all repository class names
-        *
-        * @return array An array holding the registered repository class names
-        */
-       public function getRepositoryClassNames() {
-               return $this->repositoryClassNames;
-       }
-
-       /**
         * Returns the number of records matching the query.
         *
         * @param Tx_Extbase_Persistence_QueryInterface $query
@@ -159,9 +150,8 @@ class Tx_Extbase_Persistence_Manager implements Tx_Extbase_Persistence_ManagerIn
                $removedObjects = new Tx_Extbase_Persistence_ObjectStorage();
 
                        // fetch and inspect objects from all known repositories
-               $repositoryClassNames = $this->getRepositoryClassNames();
-               foreach ($repositoryClassNames as $repositoryClassName) {
-                       $repository = $this->objectManager->getObject($repositoryClassName);
+               foreach ($this->repositoryClassNames as $repositoryClassName) {
+                       $repository = $this->objectManager->get($repositoryClassName);
                        $aggregateRootObjects->addAll($repository->getAddedObjects());
                        $removedObjects->addAll($repository->getRemovedObjects());
                }
index 3e83f31..bbaa584 100644 (file)
@@ -57,5 +57,31 @@ interface Tx_Extbase_Persistence_ManagerInterface {
         * @api
         */
        public function persistAll();
+
+       /**
+        * Returns the number of records matching the query.
+        *
+        * @param Tx_Extbase_Persistence_QueryInterface $query
+        * @return integer
+        * @api
+        */
+       public function getObjectCountByQuery(Tx_Extbase_Persistence_QueryInterface $query);
+
+       /**
+        * Returns the object data matching the $query.
+        *
+        * @param Tx_Extbase_Persistence_QueryInterface $query
+        * @return array
+        * @api
+        */
+       public function getObjectDataByQuery(Tx_Extbase_Persistence_QueryInterface $query);
+
+       /**
+        * Registers a repository
+        *
+        * @param string $className The class name of the repository to be reigistered
+        * @return void
+        */
+       public function registerRepositoryClassName($className);
 }
 ?>
\ No newline at end of file
index f07d852..b6629b8 100644 (file)
@@ -29,7 +29,7 @@
  * @subpackage Persistence\Mapper
  * @version $ID:$
  */
-class Tx_Extbase_Persistence_Mapper_DataMapFactory {
+class Tx_Extbase_Persistence_Mapper_DataMapFactory implements t3lib_Singleton {
 
        /**
         * @var Tx_Extbase_Reflection_Service
@@ -37,6 +37,11 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
        protected $reflectionService;
 
        /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
+
+       /**
         * Injects the reflection service
         *
         * @param Tx_Extbase_Reflection_Service $reflectionService
@@ -47,6 +52,14 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
        }
 
        /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
         * Builds a data map by adding column maps for all the configured columns in the $TCA.
         * It also resolves the type of values the column is holding and the typo of relation the column
         * represents.
@@ -64,8 +77,8 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
                $tableName = strtolower($className);
                $columnMapping = array();
 
-               $extbaseFrameworkConfiguration = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
-               $classSettings = $extbaseFrameworkConfiguration['persistence']['classes'][$className];
+               $frameworkConfiguration = $this->configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               $classSettings = $frameworkConfiguration['persistence']['classes'][$className];
                if ($classSettings !== NULL) {
                        if (isset($classSettings['subclasses']) && is_array($classSettings['subclasses'])) {
                                $subclasses = $classSettings['subclasses'];
@@ -81,8 +94,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
                                if (in_array($currentClassName, array('Tx_Extbase_DomainObject_AbstractEntity', 'Tx_Extbase_DomainObject_AbstractValueObject'))) {
                                        break;
                                }
-                               $currentTableName = strtolower($currentClassName);
-                               $currentClassSettings = $extbaseFrameworkConfiguration['persistence']['classes'][$currentClassName];
+                               $currentClassSettings = $frameworkConfiguration['persistence']['classes'][$currentClassName];
                                if ($currentClassSettings !== NULL) {
                                        if (isset($currentClassSettings['mapping']['columns']) && is_array($currentClassSettings['mapping']['columns'])) {
                                                $columnMapping = t3lib_div::array_merge_recursive_overrule($columnMapping, $currentClassSettings['mapping']['columns'], 0, FALSE); // FALSE means: do not include empty values form 2nd array
@@ -91,7 +103,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
                        }
                }
 
-               $dataMap = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMap', $className, $tableName, $recordType, $subclasses);
+               $dataMap = new Tx_Extbase_Persistence_Mapper_DataMap($className, $tableName, $recordType, $subclasses);
                $dataMap = $this->addMetaDataColumnNames($dataMap, $tableName);
 
                // $classPropertyNames = $this->reflectionService->getClassPropertyNames($className);
@@ -101,7 +113,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapFactory {
                        if (isset($columnDefinition['mapOnProperty'])) {
                                $propertyName = $columnDefinition['mapOnProperty'];
                        } else {
-                               $propertyName = Tx_Extbase_Utility_Extension::convertUnderscoredToLowerCamelCase($columnName);
+                               $propertyName = t3lib_div::underscoredToLowerCamelCase($columnName);
                        }
                        // if (in_array($propertyName, $classPropertyNames)) { // TODO Enable check for property existance
                                $columnMap = new Tx_Extbase_Persistence_Mapper_ColumnMap($columnName, $propertyName);
index 232e55e..0e5649c 100644 (file)
@@ -83,12 +83,9 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
        protected $referenceIndex;
 
        /**
-        * Constructs a new mapper
-        *
+        * @var Tx_Extbase_Object_ObjectManagerInterface
         */
-       public function __construct() {
-               $this->queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
-       }
+       protected $objectManager;
 
        /**
         * Injects the identity map
@@ -131,16 +128,33 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
        }
 
        /**
+        * Injects the Query Factory
+        *
+        * @param Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory
+        */
+       public function injectQueryFactory(Tx_Extbase_Persistence_QueryFactoryInterface $queryFactory) {
+               $this->queryFactory = $queryFactory;
+       }
+
+       /**
         * Sets the query object model factory
         *
         * @param Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory
         * @return void
         */
-       public function setQomFactory(Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory) {
+       public function injectQomFactory(Tx_Extbase_Persistence_QOM_QueryObjectModelFactory $qomFactory) {
                $this->qomFactory = $qomFactory;
        }
 
        /**
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
+        */
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+       }
+
+       /**
         * Maps the given rows on objects
         *
         * @param string $className The name of the class
@@ -304,12 +318,12 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                $propertyMetaData = $this->reflectionService->getClassSchema(get_class($parentObject))->getProperty($propertyName);
                if ($enableLazyLoading === TRUE && $propertyMetaData['lazy']) {
                        if ($propertyMetaData['type'] === 'Tx_Extbase_Persistence_ObjectStorage') {
-                               $result = t3lib_div::makeInstance('Tx_Extbase_Persistence_LazyObjectStorage', $parentObject, $propertyName, $fieldValue);
+                               $result = $this->objectManager->create('Tx_Extbase_Persistence_LazyObjectStorage', $parentObject, $propertyName, $fieldValue);
                        } else {
                                if (empty($fieldValue)) {
                                        $result = NULL;
                                } else {
-                                       $result = t3lib_div::makeInstance('Tx_Extbase_Persistence_LazyLoadingProxy', $parentObject, $propertyName, $fieldValue);
+                                       $result = $this->objectManager->create('Tx_Extbase_Persistence_LazyLoadingProxy', $parentObject, $propertyName, $fieldValue);
                                }
                        }
                } else {
@@ -344,8 +358,8 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
        protected function getPreparedQuery(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName, $fieldValue = '') {
                $columnMap = $this->getDataMap(get_class($parentObject))->getColumnMap($propertyName);
                $type = $this->getType(get_class($parentObject), $propertyName);
-               $queryFactory = t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory');
-               $query = $queryFactory->create($type);
+
+               $query = $this->queryFactory->create($type);
                $query->getQuerySettings()->setRespectStoragePage(FALSE);
                if ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) {
                        if ($columnMap->getChildSortByFieldName() !== NULL) {
@@ -448,7 +462,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                                }
                        } elseif (strpos($propertyMetaData['type'], '_') !== FALSE) {
                                if (is_array($result)) {
-                                       
+
                                        if (current($result) !== FALSE) {
                                                $propertyValue = current($result);
                                        } else {
@@ -471,7 +485,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
         */
        public function countRelated(Tx_Extbase_DomainObject_DomainObjectInterface $parentObject, $propertyName, $fieldValue = '') {
                $query = $this->getPreparedQuery($parentObject, $propertyName, $fieldValue);
-               return $query->count();
+               return $query->execute()->count();
        }
 
        /**
@@ -533,7 +547,7 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton {
                                }
                        }
                }
-               return Tx_Extbase_Utility_Extension::convertCamelCaseToLowerCaseUnderscored($propertyName);
+               return t3lib_div::camelCaseToLowerCaseUnderscored($propertyName);
        }
 
        /**
index b043bf8..f63e742 100644 (file)
  * @version $Id: QueryObjectModelFactory.php 1972 2010-03-08 16:59:20Z jocrau $
  * @scope prototype
  */
-class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_Persistence_QOM_QueryObjectModelFactoryInterface {
-// SK: Needs to be cleaned up (methods might need to be removed, and comments fixed)
-       /**
-        * @var Tx_Extbase_Persistence_Storage_BackendInterface
-        */
-       protected $storageBackend;
+class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements t3lib_Singleton {
 
        /**
-        * Constructs the Component Factory
-        *
-        * @param Tx_Extbase_Persistence_Storage_BackendInterfasce $storageBackend
-        * @param Tx_Extbase_Persistence_Mapper_DataMapper $dataMapper
+        * @var Tx_Extbase_Object_ObjectManagerInterface
         */
-       public function __construct(Tx_Extbase_Persistence_Storage_BackendInterface $storageBackend) {
-               $this->storageBackend = $storageBackend;
-       }
-
+       protected $objectManager;
+       
        /**
-        * Creates a query with one or more selectors.
-        * If source is a selector, that selector is the default selector of the
-        * query. Otherwise the query does not have a default selector.
-        *
-        * If the query is invalid, this method throws an InvalidQueryException.
-        * See the individual QOM factory methods for the validity criteria of each
-        * query element.
-        *
-        * @param mixed $source the Selector or the node-tuple Source; non-null
-        * @param Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint the constraint, or null if none
-        * @param array $orderings zero or more orderings; null is equivalent to a zero-length array
-        * @param array $columns the columns; null is equivalent to a zero-length array
-        * @return Tx_Extbase_Persistence_QOM_QueryObjectModelInterface the query; non-null
-        * @throws \F3\PHPCR\Query\InvalidQueryException if a particular validity test is possible on this method, the implemention chooses to perform that test and the parameters given fail that test. See the individual QOM factory methods for the validity criteria of each query element.
-        * @throws Tx_Extbase_Persistence_Exception_RepositoryException if another error occurs.
+        * @param Tx_Extbase_Object_ObjectManagerInterface $objectManager
+        * @return void
         */
-       public function createQuery(Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource, $constraint, array $orderings, array $columns) {
-               $query =  new Tx_Extbase_Persistence_QOM_QueryObjectModel($selectorOrSource, $constraint, $orderings, $columns);
-               $query->injectStorageBackend($this->storageBackend);
-               return $query;
+       public function injectObjectManager(Tx_Extbase_Object_ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
        }
 
        /**
@@ -85,7 +60,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
                if ($selectorName === '') {
                        $selectorName = $nodeTypeName;
                }
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Selector', $selectorName, $nodeTypeName);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_Selector', $selectorName, $nodeTypeName);
        }
 
        /**
@@ -97,7 +72,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @return Tx_Extbase_Persistence_QOM_StatementInterface
         */
        public function statement($statement, array $boundVariables = array(), $language = Tx_Extbase_Persistence_QOM_Statement::TYPO3_SQL_MYSQL) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Statement', $statement, $boundVariables, $language);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_Statement', $statement, $boundVariables, $language);
        }
 
        /**
@@ -111,7 +86,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function join(Tx_Extbase_Persistence_QOM_SourceInterface $left, Tx_Extbase_Persistence_QOM_SourceInterface $right, $joinType, Tx_Extbase_Persistence_QOM_JoinConditionInterface $joinCondition) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Join', $left, $right, $joinType, $joinCondition);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_Join', $left, $right, $joinType, $joinCondition);
        }
 
        /**
@@ -125,7 +100,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function equiJoinCondition($selector1Name, $property1Name, $selector2Name, $property2Name) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_EquiJoinCondition', $selector1Name, $property1Name, $selector2Name, $property2Name);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_EquiJoinCondition', $selector1Name, $property1Name, $selector2Name, $property2Name);
        }
 
        /**
@@ -137,7 +112,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function _and(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1, Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_LogicalAnd', $constraint1, $constraint2);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_LogicalAnd', $constraint1, $constraint2);
        }
 
        /**
@@ -149,7 +124,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function _or(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint1, Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint2) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_LogicalOr', $constraint1, $constraint2);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_LogicalOr', $constraint1, $constraint2);
        }
 
        /**
@@ -160,7 +135,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function not(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_LogicalNot', $constraint);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_LogicalNot', $constraint);
        }
 
        /**
@@ -173,7 +148,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function comparison(Tx_Extbase_Persistence_QOM_DynamicOperandInterface $operand1, $operator, $operand2) {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_Comparison', $operand1, $operator, $operand2);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_Comparison', $operand1, $operator, $operand2);
        }
 
        /**
@@ -185,7 +160,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P
         * @throws Tx_Extbase_Persistence_Exception_RepositoryException if the operation otherwise fails
         */
        public function propertyValue($propertyName, $selectorName = '') {
-               return t3lib_div::makeInstance('Tx_Extbase_Persistence_QOM_PropertyValue', $propertyName, $selectorName);
+               return $this->objectManager->create('Tx_Extbase_Persistence_QOM_PropertyValue', $propertyName, $selectorName);
        }
 
        /**
@@ -196,7 +171,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModelFactory implements Tx_Extbase_P