+2010-09-22 Sebastian Kurfuerst <sebastian@typo3.org>
+
+ * Raised Extbase and Fluid version numbers to 1.3.0alpha2. See the ChangeLog in Extbase and Fluid for details.
+
2010-09-21 Steffen Kamper <steffen@typo3.org>
* Added feature #15699: Provide a wizard for media to process the video url (Thanks to Aishwara M.B.)
ChangeLog for Fluid
===================
+Changes for 1.3.0 Alpha 2
+=========================
+included in TYPO3 4.5.0 Alpha 2.
+
+Since the last version, one (possible BREAKING) change happened:
+
+ * Fixed Extbase Caching Bug.
+ Non-cacheable actions were cached due to the fact that TYPO3s
+ TypoScript condition "GP" does not merge GET & POST vars.
+ Additionally "switchableControllerActions" that were overridden
+ in the plugin flexform were not taken into account.
+
+!!! This is a breaking change if you set up your TS configuration
+ of the plugin manually.
+
+Full Changes:
+-------------
+
+[!!!][+BUGFIX] Extbase: Fix Extbase Caching Bug (thanks to Bastian Waidelich)
+
+[-TASK] Extbase (MVC): removed fallback to current page in AbstractController::redirect() as that's already done within the UriBuilder if $targetPageUid is NULL
+
Changes for 1.3.0 Alpha 1
=========================
+included in TYPO3 4.5.0 Alpha 1.
Since the last version, the following notable things happened:
}
if (count($newSwitchableControllerActionsFromFlexform)) {
- $frameworkConfiguration['switchableControllerActions'] = array();
+ $overriddenSwitchableControllerActions = array();
foreach ($newSwitchableControllerActionsFromFlexform as $controller => $actions) {
- $frameworkConfiguration['switchableControllerActions'][] = array(
+ $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']);
return $frameworkConfiguration;
}
}
-?>
\ No newline at end of file
+?>
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);
- $request->setIsCached($this->cObj->getUserObjectType() == tslib_cObj::OBJECTTYPE_USER);
+ 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');
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.
*
if ($i == 1) {
$actions .= ',extObj';
}
- $extbaseConfiguration['switchableControllerActions.'][$i++ . '.'] = array(
+ $extbaseConfiguration['switchableControllerActions.'][$controller . '.'] = array(
'controller' => $controller,
'actions' => $actions,
);
+ $i++;
}
// BACK_PATH is the path from the typo3/ directory from within the
if ($controllerName === NULL) {
$controllerName = $this->request->getControllerName();
}
- if ($pageUid === NULL && isset($GLOBALS['TSFE'])) {
- $pageUid = $GLOBALS['TSFE']->id;
- }
$uri = $this->uriBuilder
->reset()
} else {
$controllerName = $this->defaultControllerName;
$actionName = $this->defaultActionName;
- }
-
+ }
+
$request = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Request');
$request->setPluginName($this->pluginName);
$request->setControllerExtensionName($this->extensionName);
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);
}
* @param string $extensionName The extension name (in UpperCamelCase) or the extension key (in lower_underscore)
* @param string $pluginName must be a unique id for your plugin in UpperCamelCase (the string length of the extension key added to the length of the plugin name should be less than 32!)
* @param string $controllerActions is an array of allowed combinations of controller and action stored in an array (controller name as key and a comma separated list of action names as value, the first controller and its first action is chosen as default)
- * @param string $nonCachableControllerActions is an optional array of controller name and action names which should not be cached (array as defined in $controllerActions)
+ * @param string $nonCacheableControllerActions is an optional array of controller name and action names which should not be cached (array as defined in $controllerActions)
* @param string $defaultControllerAction is an optional array controller name (as array key) and action name (as array value) that should be called as default
* @return void
*/
- public static function configurePlugin($extensionName, $pluginName, array $controllerActions, array $nonCachableControllerActions = array()) {
+ public static function configurePlugin($extensionName, $pluginName, array $controllerActions, array $nonCacheableControllerActions = array()) {
if (empty($pluginName)) {
throw new InvalidArgumentException('The plugin name must not be empty', 1239891987);
}
$extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName)));
$pluginSignature = strtolower($extensionName) . '_' . strtolower($pluginName);
- $controllerCounter = 1;
- $hasMultipleActionsCounter = 0;
$controllers = '';
foreach ($controllerActions as $controller => $actionsList) {
$controllers .= '
- ' . $controllerCounter . '.controller = ' . $controller . '
- ' . $controllerCounter . '.actions = ' . $actionsList;
- $controllerCounter++;
- if (strpos($actionsList, ',') !== FALSE) {
- $hasMultipleActionsCounter++;
+ ' . $controller . '.actions = ' . $actionsList;
+ if (!empty($nonCacheableControllerActions[$controller])) {
+ $controllers .= '
+ ' . $controller . '.nonCacheableActions = ' . $nonCacheableControllerActions[$controller];
}
}
- $switchableControllerActions = '';
- if ($controllerCounter > 1 || $hasMultipleActionsCounter > 0) {
- $switchableControllerActions = '
+ $switchableControllerActions = '
switchableControllerActions {' . $controllers . '
}';
- }
reset($controllerActions);
$defaultController = key($controllerActions);
$action = '
action = ' . $defaultAction;
- $nonCachableActions = array();
- if (!empty($nonCachableControllerActions[$defaultController])) {
- $nonCachableActions = t3lib_div::trimExplode(',', $nonCachableControllerActions[$defaultController]);
- }
- $cachableActions = array_diff(t3lib_div::trimExplode(',', $controllerActions[$defaultController]), $nonCachableActions);
-
- $contentObjectType = in_array($defaultAction, $nonCachableActions) ? 'USER_INT' : 'USER';
-
- $conditions = '';
- foreach ($controllerActions as $controllerName => $actionsList) {
- if (!empty($nonCachableControllerActions[$controllerName])) {
- $nonCachableActions = t3lib_div::trimExplode(',', $nonCachableControllerActions[$controllerName]);
- $cachableActions = array_diff(t3lib_div::trimExplode(',', $controllerActions[$controllerName]), $nonCachableActions);
- if (($contentObjectType == 'USER' && count($nonCachableActions) > 0)
- || ($contentObjectType == 'USER_INT' && count($cachableActions) > 0)) {
-
- $conditions .= '
-[globalString = GP:tx_' . $pluginSignature . '|controller = ' . $controllerName . '] && [globalString = GP:tx_' . $pluginSignature . '|action = /' . implode('|', $contentObjectType === 'USER' ? $nonCachableActions : $cachableActions) . '/]
-tt_content.list.20.' . $pluginSignature . ' = ' . ($contentObjectType === 'USER' ? 'USER_INT' : 'USER') . '
-[global]
-';
- }
- }
- }
-
$pluginTemplate = 'plugin.tx_' . strtolower($extensionName) . ' {
settings {
}
' . $pluginTemplate);
$pluginContent = trim('
-tt_content.list.20.' . $pluginSignature . ' = ' . $contentObjectType . '
+tt_content.list.20.' . $pluginSignature . ' = USER
tt_content.list.20.' . $pluginSignature . ' {
userFunc = tx_extbase_dispatcher->dispatch
pluginName = ' . $pluginName . '
persistence =< plugin.tx_' . strtolower($extensionName) . '.persistence
view =< plugin.tx_' . strtolower($extensionName) . '.view
_LOCAL_LANG =< plugin.tx_' . strtolower($extensionName) . '._LOCAL_LANG
-}
-' . $conditions);
+}');
t3lib_extMgm::addTypoScript($extensionName, 'setup', '
# Setting ' . $extensionName . ' plugin TypoScript
return t3lib_div::underscoredToUpperCamelCase($camelCasedString);
}
- /**
+ /**
* Build the autoload registry for a given extension and place it ext_autoload.php.
*
* @param string $extensionKey Key of the extension
$this->assertEquals(array('foo' => 'bar'), $this->frontendConfigurationManager->loadTypoScriptSetup());
}
+ /**
+ * @test
+ */
+ public function overrideSwitchableControllerActionsFromFlexformMergesNonCacheableActions() {
+ $frameworkConfiguration = array(
+ 'userFunc' => 'tx_extbase_dispatcher->dispatch',
+ 'pluginName' => 'Pi1',
+ 'extensionName' => 'SomeExtension',
+ 'switchableControllerActions' => array(
+ 'Controller1' => array(
+ 'controller' => 'Controller1',
+ 'actions' => 'action1 , action2'
+ ),
+ 'Controller2' => array(
+ 'controller' => 'Controller2',
+ 'actions' => 'action2 , action1,action3',
+ 'nonCacheableActions' => 'action2, action3'
+ )
+ )
+ );
+ $flexformConfiguration = array(
+ 'switchableControllerActions' => 'Controller1->action2;Controller2->action3;Controller2->action1'
+ );
+ $expectedResult = array(
+ 'userFunc' => 'tx_extbase_dispatcher->dispatch',
+ 'pluginName' => 'Pi1',
+ 'extensionName' => 'SomeExtension',
+ 'switchableControllerActions' => array(
+ 'Controller1' => array(
+ 'controller' => 'Controller1',
+ 'actions' => 'action2'
+ ),
+ 'Controller2' => array(
+ 'controller' => 'Controller2',
+ 'actions' => 'action3,action1',
+ 'nonCacheableActions' => 'action3'
+ )
+ )
+ );
+ $actualResult = $this->frontendConfigurationManager->_callRef('overrideSwitchableControllerActionsFromFlexform', $frameworkConfiguration, $flexformConfiguration);
+ $this->assertEquals($expectedResult, $actualResult);
+ }
}
?>
\ No newline at end of file
public function setUp() {
$this->configuration = array(
'userFunc' => 'Tx_Extbase_Dispatcher->dispatch',
- 'pluginName' => 'pi1',
+ 'pluginName' => 'Pi1',
'extensionName' => 'MyExtension',
'controller' => 'TheFirstController',
'action' => 'show',
- 'switchableControllerActions.' => array(
- '1.' => array(
+ 'switchableControllerActions' => array(
+ 'TheFirstController' => array(
'controller' => 'TheFirstController',
'actions' => 'show,index, ,new,create,delete,edit,update,setup,test'
- ),
- '2.' => array(
+ ),
+ 'TheSecondController' => array(
'controller' => 'TheSecondController',
'actions' => 'show, index'
- ),
- '3.' => array(
+ ),
+ 'TheThirdController' => array(
'controller' => 'TheThirdController',
'actions' => 'delete,create'
- )
)
- );
- $this->builder = new Tx_Extbase_MVC_Web_RequestBuilder;
+ )
+ );
+ $this->builder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_RequestBuilder'), array('dummy'));
$this->getBackup = $_GET;
$this->postBackup = $_POST;
}
$this->builder->initialize($this->configuration);
$request = $this->builder->build();
$this->assertEquals('Tx_Extbase_MVC_Web_Request', get_class($request));
- $this->assertEquals('pi1', $request->getPluginName());
+ $this->assertEquals('Pi1', $request->getPluginName());
$this->assertEquals('MyExtension', $request->getControllerExtensionName());
$this->assertEquals('TheFirstController', $request->getControllerName());
$this->assertEquals('show', $request->getControllerActionName());
$configuration = $this->configuration;
unset($configuration['controller']);
unset($configuration['action']);
- unset($configuration['switchableControllerActions.']);
+ unset($configuration['switchableControllerActions']);
$this->builder->initialize($configuration);
$request = $this->builder->build();
- $this->assertEquals('pi1', $request->getPluginName());
+ $this->assertEquals('Pi1', $request->getPluginName());
$this->assertEquals('MyExtension', $request->getControllerExtensionName());
$this->assertEquals('Standard', $request->getControllerName());
$this->assertEquals('index', $request->getControllerActionName());
public function buildWithMissingActionsReturnsAWebRequestObjectWithDefaultControllerSettings() {
$configuration = $this->configuration;
unset($configuration['action']);
+ unset($configuration['switchableControllerActions']);
$this->builder->initialize($configuration);
$request = $this->builder->build();
- $this->assertEquals('pi1', $request->getPluginName());
+ $this->assertEquals('Pi1', $request->getPluginName());
$this->assertEquals('MyExtension', $request->getControllerExtensionName());
$this->assertEquals('TheFirstController', $request->getControllerName());
$this->assertEquals('index', $request->getControllerActionName());
* @test
*/
public function buildSetsParametersFromGetAndPostVariables() {
- $builder = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Web_RequestBuilder'), array('dummy'));
- $builder->_set('extensionName', 'someExtensionName');
- $builder->_set('pluginName', 'somePluginName');
+ $this->builder->_set('extensionName', 'someExtensionName');
+ $this->builder->_set('pluginName', 'somePluginName');
$_GET = array(
'tx_someotherextensionname_somepluginname' => array(
)
);
- $request = $builder->build();
+ $request = $this->builder->build();
$expectedResult = array(
'parameter1' => 'value1',
'parameter2' => array(
$this->assertEquals($expectedResult, $actualResult);
}
+ /**
+ * @test
+ */
+ public function initializeCorrectlySetsAllowedControllerActions() {
+ $this->builder->initialize($this->configuration);
+ $expectedResult = array(
+ 'TheFirstController' => array(
+ 'show', 'index', 'new', 'create', 'delete', 'edit', 'update', 'setup', 'test'
+ ),
+ 'TheSecondController' => array(
+ 'show', 'index'
+ ),
+ 'TheThirdController' => array(
+ 'delete', 'create'
+ )
+ );
+ $actualResult = $this->builder->_get('allowedControllerActions');
+ $this->assertEquals($expectedResult, $actualResult);
+ }
}
?>
\ No newline at end of file
*/
protected $typo3ConfVars = array();
+ /**
+ * @var t3lib_DB
+ */
+ protected $typo3DbBackup;
+
+ /**
+ * @var t3lib_fe contains a backup of the current $GLOBALS['TSFE']
+ */
+ protected $tsfeBackup;
+
public function setUp() {
global $TYPO3_CONF_VARS;
$this->typo3ConfVars = $TYPO3_CONF_VARS;
+ $this->typo3DbBackup = $GLOBALS['TYPO3_DB'];
+ $GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_DB', array('fullQuoteStr', 'exec_SELECTgetRows'));
+ $this->tsfeBackup = $GLOBALS['TSFE'];
+ if (!isset($GLOBALS['TSFE']->tmpl)) {
+ $GLOBALS['TSFE']->tmpl = new stdClass();
+ }
+ if (!isset($GLOBALS['TSFE']->tmpl->setup)) {
+ $GLOBALS['TSFE']->tmpl->setup = array();
+ }
}
public function tearDown() {
global $TYPO3_CONF_VARS;
$TYPO3_CONF_VARS = $this->typo3ConfVars;
+ $GLOBALS['TSFE'] = $this->tsfeBackup;
}
/**
* @test
* @see Tx_Extbase_Utility_Extension::registerPlugin
*/
- public function configurePluginRespectsDefaultActionAsANonCachableAction() {
+ public function configurePluginRespectsDefaultActionAsANonCacheableAction() {
global $TYPO3_CONF_VARS;
$TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
Tx_Extbase_Utility_Extension::configurePlugin(
)
);
$staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
-
$this->assertContains('
-tt_content.list.20.myextension_pi1 = USER_INT
+tt_content.list.20.myextension_pi1 = USER
tt_content.list.20.myextension_pi1 {', $staticTypoScript);
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = FirstController] && [globalString = GP:tx_myextension_pi1|action = /new|create|delete|edit|update/]
-tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+ $this->assertContains('FirstController.nonCacheableActions = index,show
+', $staticTypoScript);
}
/**
* @test
* @see Tx_Extbase_Utility_Extension::registerPlugin
*/
- public function configurePluginRespectsNonDefaultActionAsANonCachableAction() {
+ public function configurePluginRespectsNonDefaultActionAsANonCacheableAction() {
global $TYPO3_CONF_VARS;
$TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
Tx_Extbase_Utility_Extension::configurePlugin(
$this->assertContains('
tt_content.list.20.myextension_pi1 = USER
tt_content.list.20.myextension_pi1 {', $staticTypoScript);
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = FirstController] && [globalString = GP:tx_myextension_pi1|action = /show|new/]
-tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+ $this->assertContains('FirstController.nonCacheableActions = show,new
+', $staticTypoScript);
}
/**
* @test
* @see Tx_Extbase_Utility_Extension::registerPlugin
*/
- public function configurePluginWorksForMultipleControllerActionsWithCachableActionAsDefault() {
+ public function configurePluginWorksForMultipleControllerActionsWithCacheableActionAsDefault() {
global $TYPO3_CONF_VARS;
$TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
Tx_Extbase_Utility_Extension::configurePlugin(
'FirstController' => 'new,create,edit,update',
'SecondController' => 'delete',
'ThirdController' => 'create'
- ),
- array('SecondController' => 'show')
+ )
);
$staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
tt_content.list.20.myextension_pi1 = USER
tt_content.list.20.myextension_pi1 {', $staticTypoScript);
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = FirstController] && [globalString = GP:tx_myextension_pi1|action = /new|create|edit|update/]
-tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+ $this->assertContains('FirstController.nonCacheableActions = new,create,edit,update
+', $staticTypoScript);
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = SecondController] && [globalString = GP:tx_myextension_pi1|action = /delete/]
-tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+ $this->assertContains('SecondController.nonCacheableActions = delete
+', $staticTypoScript);
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = ThirdController] && [globalString = GP:tx_myextension_pi1|action = /create/]
-tt_content.list.20.myextension_pi1 = USER_INT', $staticTypoScript);
+ $this->assertContains('ThirdController.nonCacheableActions = create
+', $staticTypoScript);
}
* @test
* @see Tx_Extbase_Utility_Extension::registerPlugin
*/
- public function configurePluginWorksForMultipleControllerActionsWithNonCachableActionAsDefault() {
+ public function configurePluginWorksForMultipleControllerActionsWithNonCacheableActionAsDefault() {
global $TYPO3_CONF_VARS;
$TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
Tx_Extbase_Utility_Extension::configurePlugin(
$staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
$this->assertContains('
-tt_content.list.20.myextension_pi1 = USER_INT
+tt_content.list.20.myextension_pi1 = USER
tt_content.list.20.myextension_pi1 {', $staticTypoScript);
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = FirstController] && [globalString = GP:tx_myextension_pi1|action = /show|delete/]
-tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
-
- $this->assertContains('
-[globalString = GP:tx_myextension_pi1|controller = SecondController] && [globalString = GP:tx_myextension_pi1|action = /index|show/]
-tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
-
- $this->assertNotContains('[globalString = GP:tx_myextension_pi1|controller = ThirdController]', $staticTypoScript);
- }
-
- /**
- * @test
- * @see Tx_Extbase_Utility_Extension::registerPlugin
- */
- public function configurePluginWorksForMultipleControllerActionsWithNonCachableActionAsDefaultAndOnlyNonCachableActions() {
- global $TYPO3_CONF_VARS;
- $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
- Tx_Extbase_Utility_Extension::configurePlugin(
- 'MyExtension',
- 'Pi1',
- array(
- 'FirstController' => 'index,show,new,create,delete,edit,update',
- 'SecondController' => 'index,show,delete',
- 'ThirdController' => 'create'
- ),
- array(
- 'FirstController' => 'index,show,new,create,delete,edit,update',
- 'SecondController' => 'index,show,delete',
- 'ThirdController' => 'create'
- )
- );
- $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+ $this->assertContains('FirstController.nonCacheableActions = index,new,create,edit,update
+', $staticTypoScript);
- $this->assertContains('
-tt_content.list.20.myextension_pi1 = USER_INT
-tt_content.list.20.myextension_pi1 {', $staticTypoScript);
+ $this->assertContains('SecondController.nonCacheableActions = delete
+', $staticTypoScript);
- $this->assertNotContains('GP', $staticTypoScript);
+ $this->assertContains('ThirdController.nonCacheableActions = create
+', $staticTypoScript);
}
- // TODO switchableControllerActionsIsSupressedIfOnlyOneControllerActionIsGiven()
- // TODO switchableControllerDingsIsGeneratedWithMultipleControllersEachHavingOnlyOneAction
-
}
?>
\ No newline at end of file
'clearCacheOnLoad' => 1,
'lockType' => '',
'author_company' => '',
- 'version' => '1.3.0alpha1',
+ 'version' => '1.3.0alpha2',
'constraints' => array(
'depends' => array(
'php' => '5.2.0-0.0.0',
-https://svn.typo3.org/TYPO3v4/CoreProjects/MVC/extbase/tags/1.3.0alpha1/
+https://svn.typo3.org/TYPO3v4/CoreProjects/MVC/extbase/tags/1.3.0alpha2/
ChangeLog for Fluid
===================
+Changes for 1.3.0 Alpha 2
+=========================
+included in TYPO3 4.5.0 Alpha 2.
+
+In this release, mostly small bugfixes have been made in Fluid. Highlights are:
+
+ * {settings} is now automatically in partials. (#6289)
+
+ * You can now use <f:security.ifAuthenticated> and <f:security.ifHasRole role="foo"> (#9143)
+ in your Fluid templates to check whether an FE user is currently logged in / belongs to the
+ specified usergroup.
+ Note: if "role" is a numeric value the uid of the usergroup is compared, otherwise the title
+ of the usergroup.
+ To deal with BE users you can use the respective be.security.* view helpers
+
+ * Boolean expressions can now contain negative numbers. Resolves #9434.
+
+Full Changes:
+-------------
+
+[+FEATURE] Fluid (Core): {settings} is available in Partials
+Now, the {settings} are automatically available in partials and sections.
+Before, they had to be passed explicitely, i.e. by calling
+<f:render section="..." arguments="{settings: settings}" />.
+If somebody defined his own "settings"-argument, this still takes precedence:
+<f:render section="..." arguments="{settings: some.different.settings}" />
+This means that this change is completely backwards compatible.
+NOTE: The settings are NOT merged together, like it has been suggested in #6289,
+as this will lead to un-obvious behavior for the user.
+
+[-API] Fluid (Core): Remove getTemplateParser() method.
+This method has accidentally gotten an @api annotation,
+and was only needed for the Viewhelpertest package.
+Now, this package is cleaned up, and this method can be
+completely thrown away.
+
+[+BUGFIX] Fluid (ViewHelpers): Fix bug in Form ViewHelper
+Since #6521 you can use the "objectName" argument to specify the name of a bound object rather then using the "name" attribute.
+But if you do so, the rendered hidden identity field is not correct anymore. This behavior is fixed with this commit.
+Resolves: #9515
+
+* Documentation Cleanup
+
+[+FEATURE] Fluid (ViewHelpers): Backported ifAuthenticated & ifHasRole security ViewHelpers
+you can now use <f:security.ifAuthenticated> and <f:security.ifHasRole role="foo">
+in your Fluid templates to check whether an FE user is currently logged in / belongs to the
+specified usergroup.
+Note: if role is a numeric value the uid of the usergroup is compared, otherwise the title
+of the usergroup.
+to deal with BE users you can use the respective be.security.* view helpers
+Resolves #9143
+
+[TASK] Fluid (Core): Regular Expression performance improvements
+In rare cases, on some systems (like mine), the
+PCRE parser reproducably crashes if one passes very
+long argument strings into it, or very complex ones.
+With this patch, the parser is slightly modified
+to decrease the use of backtracking; which then avoids
+the crashes mostly.
+
+[TASK] Fluid (Core): Formatted Regular Expressions more nicely
+There were some undocumented regular expressions
+in the parser, which needed to be formatted nicely.
+
+[+BUGFIX] Fluid (Core): Boolean expressions can now contain negative numbers. Resolves #9434.
+Boolean expressions with negative numbers did not work so far.
+Now, they work as expected. Example from Viewhelpertest which displayed
+a wrong result before, and now displays the correct result:
+<f:if condition="{testVariables.number.minusOne} < -1.1">
+ <f:then>Then part!</f:then>
+ <f:else>Else part!</f:else>
+</f:if>
+Issue: #9434
+
+
Changes for 1.3.0 Alpha 1
=========================
+included in TYPO3 4.5.0 Alpha 1.
In this release, numerous bugs have been fixed, making Fluid more stable than ever. Below are some nice features which have been introduced:
(?: # start repeat
COMPARATORS # We allow all comparators
|\s* # Arbitary spaces
- |[0-9] # Numbers
- |\\. # And the dot.
+ |-? # Numbers, possibly with the "minus" symbol in front.
+ [0-9]+ # some digits
+ (?: # and optionally a dot, followed by some more digits
+ \\.
+ [0-9]+
+ )?
)*
$/x';
(?: # Begin tag arguments
\s*[a-zA-Z0-9:]+ # Argument Keys
= # =
- (?: # either...
+ (?> # either... If we have found an argument, we will not back-track (That does the Atomic Bracket)
"(?:\\\"|[^"])*" # a double-quoted string
|\'(?:\\\\\'|[^\'])*\' # or a single quoted string
)\s* #
*
* @author Sebastian Kurfürst <sebastian@typo3.org>
*/
- public static $SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG = '/^<(?P<NamespaceIdentifier>NAMESPACE):(?P<MethodIdentifier>[a-zA-Z0-9\\.]+)(?P<Attributes>(?:\s*[a-zA-Z0-9:]+=(?:"(?:\\\"|[^"])*"|\'(?:\\\\\'|[^\'])*\')\s*)*)\s*(?P<Selfclosing>\/?)>$/';
+ public static $SCAN_PATTERN_TEMPLATE_VIEWHELPERTAG = '/
+ ^< # A Tag begins with <
+ (?P<NamespaceIdentifier>NAMESPACE): # Then comes the Namespace prefix followed by a :
+ (?P<MethodIdentifier> # Now comes the Name of the ViewHelper
+ [a-zA-Z0-9\\.]+
+ )
+ (?P<Attributes> # Begin Tag Attributes
+ (?: # A tag might have multiple attributes
+ \s*
+ [a-zA-Z0-9:]+ # The attribute name
+ = # =
+ (?> # either... # If we have found an argument, we will not back-track (That does the Atomic Bracket)
+ "(?:\\\"|[^"])*" # a double-quoted string
+ |\'(?:\\\\\'|[^\'])*\' # or a single quoted string
+ ) #
+ \s*
+ )* # A tag might have multiple attributes
+ ) # End Tag Attributes
+ \s*
+ (?P<Selfclosing>\/?) # A tag might be selfclosing
+ >$/x';
/**
* This regular expression scans if the input string is a closing ViewHelper
*
* @author Sebastian Kurfürst <sebastian@typo3.org>
*/
- public static $SPLIT_PATTERN_TAGARGUMENTS = '/(?:\s*(?P<Argument>[a-zA-Z0-9:]+)=(?:(?P<ValueQuoted>(?:"(?:\\\"|[^"])*")|(?:\'(?:\\\\\'|[^\'])*\')))\s*)/';
+ public static $SPLIT_PATTERN_TAGARGUMENTS = '/
+ (?: #
+ \s* #
+ (?P<Argument> # The attribute name
+ [a-zA-Z0-9:]+ #
+ ) #
+ = # =
+ (?> # If we have found an argument, we will not back-track (That does the Atomic Bracket)
+ (?P<ValueQuoted> # either...
+ (?:"(?:\\\"|[^"])*") # a double-quoted string
+ |(?:\'(?:\\\\\'|[^\'])*\') # or a single quoted string
+ )
+ )\s*
+ )
+ /xs';
/**
* This pattern detects CDATA sections and outputs the text between opening
$this->controllerContext = $controllerContext;
}
- /**
- * Returns the template parser that is used to parse this views template
- *
- * @return Tx_Fluid_Core_Parser_TemplateParser
- * @author Bastian Waidelich <bastian@typo3.org>
- * @api
- */
- public function getTemplateParser() {
- return $this->templateParser;
- }
-
public function initializeView() {
}
// Here, the backporter can insert the initializeView method, which is needed for Fluid v4.
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+/**
+ * This view helper implements an ifAuthenticated/else condition for BE users/groups.
+ *
+ * = Examples =
+ *
+ * <code title="Basic usage">
+ * <f:be.security.ifAuthenticated>
+ * This is being shown whenever a BE user is logged in
+ * </f:be.security.ifAuthenticated>
+ * </code>
+ * <output>
+ * Everything inside the <f:be.ifAuthenticated> tag is being displayed if you are authenticated with any BE user account.
+ * </output>
+ *
+ * <code title="IfAuthenticated / then / else">
+ * <f:be.security.ifAuthenticated>
+ * <f:then>
+ * This is being shown in case you have access.
+ * </f:then>
+ * <f:else>
+ * This is being displayed in case you do not have access.
+ * </f:else>
+ * </f:be.security.ifAuthenticated>
+ * </code>
+ * <output>
+ * Everything inside the "then" tag is displayed if you have access.
+ * Otherwise, everything inside the "else"-tag is displayed.
+ * </output>
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @api
+ */
+class Tx_Fluid_ViewHelpers_Be_Security_IfAuthenticatedViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractConditionViewHelper {
+
+ /**
+ * Renders <f:then> child if any BE user is currently authenticated, otherwise renders <f:else> child.
+ *
+ * @return string the rendered string
+ * @api
+ */
+ public function render() {
+ if (isset($GLOBALS['BE_USER']) && $GLOBALS['BE_USER']->user['uid'] > 0) {
+ return $this->renderThenChild();
+ }
+ return $this->renderElseChild();
+ }
+}
+?>
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+/**
+ * This view helper implements an ifHasRole/else condition for BE users/groups.
+ *
+ * = Examples =
+ *
+ * <code title="Basic usage">
+ * <f:be.security.ifHasRole role="Administrator">
+ * This is being shown in case the current BE user belongs to a BE usergroup (aka role) titled "Administrator" (case sensitive)
+ * </f:be.security.ifHasRole>
+ * </code>
+ * <output>
+ * Everything inside the <f:ifHasRole> tag is being displayed if the logged in BE user belongs to the specified role.
+ * </output>
+ *
+ * <code title="Using the usergroup uid as role identifier">
+ * <f:be.security.ifHasRole role="1">
+ * This is being shown in case the current BE user belongs to a BE usergroup (aka role) with the uid "1"
+ * </f:be.security.ifHasRole>
+ * </code>
+ * <output>
+ * Everything inside the <f:ifHasRole> tag is being displayed if the logged in BE user belongs to the specified role.
+ * </output>
+ *
+ * <code title="IfRole / then / else">
+ * <f:be.security.ifHasRole role="Administrator">
+ * <f:then>
+ * This is being shown in case you have the role.
+ * </f:then>
+ * <f:else>
+ * This is being displayed in case you do not have the role.
+ * </f:else>
+ * </f:be.security.ifHasRole>
+ * </code>
+ * <output>
+ * Everything inside the "then" tag is displayed if the logged in BE user belongs to the specified role.
+ * Otherwise, everything inside the "else"-tag is displayed.
+ * </output>
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @api
+ */
+class Tx_Fluid_ViewHelpers_Be_Security_IfHasRoleViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractConditionViewHelper {
+
+ /**
+ * renders <f:then> child if the current logged in BE user belongs to the specified role (aka usergroup)
+ * otherwise renders <f:else> child.
+ *
+ * @param string $role The usergroup (either the usergroup uid or its title)
+ * @return string the rendered string
+ * @api
+ */
+ public function render($role) {
+ if ($this->backendUserHasRole($role)) {
+ return $this->renderThenChild();
+ } else {
+ return $this->renderElseChild();
+ }
+ }
+
+ /**
+ * Determines whether the currently logged in BE user belongs to the specified usergroup
+ *
+ * @param string $role The usergroup (either the usergroup uid or its title)
+ * @return boolean TRUE if the currently logged in BE user belongs to $role
+ */
+ protected function backendUserHasRole($role) {
+ if (!is_array($GLOBALS['BE_USER']->userGroups)) {
+ return FALSE;
+ }
+ if (is_numeric($role)) {
+ foreach($GLOBALS['BE_USER']->userGroups as $userGroup) {
+ if ((integer)$userGroup['uid'] === (integer)$role) {
+ return TRUE;
+ }
+ }
+ } else {
+ foreach($GLOBALS['BE_USER']->userGroups as $userGroup) {
+ if ($userGroup['title'] === $role) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+ }
+}
+?>
$formObjectName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
if (!empty($formObjectName)) {
$propertySegments = explode('.', $this->arguments['property']);
- $properties = '';
+ $propertyPath = '';
foreach ($propertySegments as $segment) {
- $properties .= '[' . $segment . ']';
+ $propertyPath .= '[' . $segment . ']';
}
- $name = $formObjectName . $properties;
+ $name = $formObjectName . $propertyPath;
} else {
$name = $this->arguments['property'];
}
protected function addAdditionalIdentityPropertiesIfNeeded() {
$propertySegments = explode('.', $this->arguments['property']);
if (count($propertySegments) >= 2) {
- // hierarchical property. If there is no "." inside (thus $propertySegments == 1), we do not need to do anything
+ // hierarchical property. If there is no "." inside (thus $propertySegments == 1), we do not need to do anything
$formObject = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject');
$objectName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
- // If Count == 2 -> we need to go through the for-loop exactly once
+ // If Count == 2 -> we need to go through the for-loop exactly once
for ($i=1; $i < count($propertySegments); $i++) {
$object = Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($formObject, implode('.', array_slice($propertySegments, 0, $i)));
$objectName .= '[' . $propertySegments[$i-1] . ']';
$hiddenIdentityField = $this->renderHiddenIdentityField($object, $objectName);
- // Add the hidden identity field to the ViewHelperVariableContainer
+ // Add the hidden identity field to the ViewHelperVariableContainer
$additionalIdentityProperties = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties');
$additionalIdentityProperties[$objectName] = $hiddenIdentityField;
$this->viewHelperVariableContainer->addOrUpdate('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties', $additionalIdentityProperties);
$content = '';
- // register field name for token generation.
- // in case it is a multi-select, we need to register the field name
- // as often as there are elements in the box
+ // register field name for token generation.
+ // in case it is a multi-select, we need to register the field name
+ // as often as there are elements in the box
if ($this->arguments->hasArgument('multiple') && $this->arguments['multiple'] !== '') {
$content .= $this->renderHiddenFieldForEmptyValue();
for ($i=0; $i<count($options); $i++) {
$formContent = $this->renderChildren();
$content = chr(10) . '<div style="display: none">';
- $content .= $this->renderHiddenIdentityField($this->arguments['object'], $this->arguments['name']);
+ $content .= $this->renderHiddenIdentityField($this->arguments['object'], $this->getFormObjectName());
$content .= $this->renderAdditionalIdentityFields();
$content .= $this->renderHiddenReferrerFields();
$content .= $this->renderRequestHashField(); // Render hmac after everything else has been rendered
* @api
*/
public function render($section = NULL, $partial = NULL, $arguments = array()) {
+ $arguments = $this->loadSettingsIntoArguments($arguments);
+
if ($partial !== NULL) {
return $this->viewHelperVariableContainer->getView()->renderPartial($partial, $section, $arguments);
} elseif ($section !== NULL) {
return '';
}
-
+ /**
+ * If $arguments['settings'] is not set, it is loaded from the TemplateVariableContainer (if it is available there).
+ *
+ * @param array $arguments
+ * @return array
+ */
+ protected function loadSettingsIntoArguments($arguments) {
+ if (!isset($arguments['settings']) && $this->templateVariableContainer->exists('settings')) {
+ $arguments['settings'] = $this->templateVariableContainer->get('settings');
+ }
+ return $arguments;
+ }
}
-
?>
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+/**
+ * This view helper implements an ifAuthenticated/else condition for FE users/groups.
+ *
+ * = Examples =
+ *
+ * <code title="Basic usage">
+ * <f:security.ifAuthenticated>
+ * This is being shown whenever a FE user is logged in
+ * </f:security.ifAuthenticated>
+ * </code>
+ * <output>
+ * Everything inside the <f:ifAuthenticated> tag is being displayed if you are authenticated with any FE user account.
+ * </output>
+ *
+ * <code title="IfAuthenticated / then / else">
+ * <f:security.ifAuthenticated>
+ * <f:then>
+ * This is being shown in case you have access.
+ * </f:then>
+ * <f:else>
+ * This is being displayed in case you do not have access.
+ * </f:else>
+ * </f:security.ifAuthenticated>
+ * </code>
+ * <output>
+ * Everything inside the "then" tag is displayed if you have access.
+ * Otherwise, everything inside the "else"-tag is displayed.
+ * </output>
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @api
+ */
+class Tx_Fluid_ViewHelpers_Security_IfAuthenticatedViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractConditionViewHelper {
+
+ /**
+ * Renders <f:then> child if any FE user is currently authenticated, otherwise renders <f:else> child.
+ *
+ * @return string the rendered string
+ * @api
+ */
+ public function render() {
+ if (isset($GLOBALS['TSFE']) && $GLOBALS['TSFE']->loginUser) {
+ return $this->renderThenChild();
+ }
+ return $this->renderElseChild();
+ }
+}
+?>
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+/**
+ * This view helper implements an ifHasRole/else condition for FE users/groups.
+ *
+ * = Examples =
+ *
+ * <code title="Basic usage">
+ * <f:security.ifHasRole role="Administrator">
+ * This is being shown in case the current FE user belongs to a FE usergroup (aka role) titled "Administrator" (case sensitive)
+ * </f:security.ifHasRole>
+ * </code>
+ * <output>
+ * Everything inside the <f:ifHasRole> tag is being displayed if the logged in FE user belongs to the specified role.
+ * </output>
+ *
+ * <code title="Using the usergroup uid as role identifier">
+ * <f:security.ifHasRole role="1">
+ * This is being shown in case the current FE user belongs to a FE usergroup (aka role) with the uid "1"
+ * </f:security.ifHasRole>
+ * </code>
+ * <output>
+ * Everything inside the <f:ifHasRole> tag is being displayed if the logged in FE user belongs to the specified role.
+ * </output>
+ *
+ * <code title="IfRole / then / else">
+ * <f:security.ifHasRole role="Administrator">
+ * <f:then>
+ * This is being shown in case you have the role.
+ * </f:then>
+ * <f:else>
+ * This is being displayed in case you do not have the role.
+ * </f:else>
+ * </f:security.ifHasRole>
+ * </code>
+ * <output>
+ * Everything inside the "then" tag is displayed if the logged in FE user belongs to the specified role.
+ * Otherwise, everything inside the "else"-tag is displayed.
+ * </output>
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @api
+ */
+class Tx_Fluid_ViewHelpers_Security_IfHasRoleViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractConditionViewHelper {
+
+ /**
+ * renders <f:then> child if the current logged in FE user belongs to the specified role (aka usergroup)
+ * otherwise renders <f:else> child.
+ *
+ * @param string $role The usergroup (either the usergroup uid or its title)
+ * @return string the rendered string
+ * @api
+ */
+ public function render($role) {
+ if ($this->frontendUserHasRole($role)) {
+ return $this->renderThenChild();
+ } else {
+ return $this->renderElseChild();
+ }
+ }
+
+ /**
+ * Determines whether the currently logged in FE user belongs to the specified usergroup
+ *
+ * @param string $role The usergroup (either the usergroup uid or its title)
+ * @return boolean TRUE if the currently logged in FE user belongs to $role
+ */
+ protected function frontendUserHasRole($role) {
+ if (!isset($GLOBALS['TSFE']) || !$GLOBALS['TSFE']->loginUser) {
+ return FALSE;
+ }
+ if (is_numeric($role)) {
+ return (is_array($GLOBALS['TSFE']->fe_user->groupData['uid']) && in_array($role, $GLOBALS['TSFE']->fe_user->groupData['uid']));
+ } else {
+ return (is_array($GLOBALS['TSFE']->fe_user->groupData['title']) && in_array($role, $GLOBALS['TSFE']->fe_user->groupData['title']));
+ }
+ }
+}
+?>
$this->assertFalse($this->viewHelperNode->_call('evaluateBooleanExpression', $rootNode, $this->renderingContext));
}
+ /**
+ * @test
+ * @author Sebastian Kurfürst <sebastian@typo3.org>
+ */
+ public function lessOrEqualsReturnFalseIfComparingWithANegativeNumber() {
+ $rootNode = new Tx_Fluid_Core_Parser_SyntaxTree_RootNode();
+ $rootNode->addChildNode(new Tx_Fluid_Core_Parser_SyntaxTree_TextNode('11 <= -2.1'));
+
+ $this->assertFalse($this->viewHelperNode->_call('evaluateBooleanExpression', $rootNode, $this->renderingContext));
+ }
}
?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+require_once(dirname(__FILE__) . '/../ViewHelperBaseTestcase.php');
+
+/**
+ * Testcase for be.security.ifAuthenticated view helper
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Fluid_ViewHelpers_Be_Security_IfAuthenticatedViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
+
+ /**
+ * var Tx_Fluid_ViewHelpers_Be_Security_IfAuthenticatedViewHelper
+ */
+ protected $viewHelper;
+
+ /**
+ * @var t3lib_tsfeBeUserAuth
+ */
+ protected $beUserBackup;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->beUserBackup = isset($GLOBALS['BE_USER']) ? $GLOBALS['BE_USER'] : NULL;
+ $GLOBALS['BE_USER'] = new stdClass();
+ $this->viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_Be_Security_IfAuthenticatedViewHelper', array('renderThenChild', 'renderElseChild'));
+ $this->viewHelper->expects($this->any())->method('renderThenChild')->will($this->returnValue('then child'));
+ $this->viewHelper->expects($this->any())->method('renderElseChild')->will($this->returnValue("else child"));
+ $this->injectDependenciesIntoViewHelper($this->viewHelper);
+ $this->viewHelper->initializeArguments();
+ }
+
+ public function tearDown() {
+ $GLOBALS['BE_USER'] = $this->beUserBackup;
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersThenChildIfBeUserIsLoggedIn() {
+ $GLOBALS['BE_USER']->user = array('uid' => 1);
+
+ $actualResult = $this->viewHelper->render();
+ $this->assertEquals('then child', $actualResult);
+ }
+
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersElseChildIfBeUserIsNotLoggedIn() {
+ $actualResult = $this->viewHelper->render();
+ $this->assertEquals('else child', $actualResult);
+ }
+}
+
+?>
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+require_once(dirname(__FILE__) . '/../ViewHelperBaseTestcase.php');
+
+/**
+ * Testcase for be.security.ifHasRole view helper
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Fluid_ViewHelpers_Be_Security_IfHasRoleViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
+
+ /**
+ * var Tx_Fluid_ViewHelpers_Be_Security_IfAuthenticatedViewHelper
+ */
+ protected $viewHelper;
+
+ /**
+ * @var t3lib_tsfeBeUserAuth
+ */
+ protected $beUserBackup;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->beUserBackup = isset($GLOBALS['BE_USER']) ? $GLOBALS['BE_USER'] : NULL;
+ $GLOBALS['BE_USER'] = new stdClass();
+ $GLOBALS['BE_USER']->userGroups = array(
+ array(
+ 'uid' => 1,
+ 'title' => 'Editor',
+ ),
+ array(
+ 'uid' => 2,
+ 'title' => 'OtherRole',
+ ),
+ );
+ $this->viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_Be_Security_IfHasRoleViewHelper', array('renderThenChild', 'renderElseChild'));
+ $this->viewHelper->expects($this->any())->method('renderThenChild')->will($this->returnValue('then child'));
+ $this->viewHelper->expects($this->any())->method('renderElseChild')->will($this->returnValue("else child"));
+ $this->injectDependenciesIntoViewHelper($this->viewHelper);
+ $this->viewHelper->initializeArguments();
+ }
+
+ public function tearDown() {
+ $GLOBALS['BE_USER'] = $this->beUserBackup;
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersThenChildIfBeUserWithSpecifiedRoleIsLoggedIn() {
+ $actualResult = $this->viewHelper->render('Editor');
+ $this->assertEquals('then child', $actualResult);
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersThenChildIfBeUserWithSpecifiedRoleIdIsLoggedIn() {
+ $actualResult = $this->viewHelper->render(1);
+ $this->assertEquals('then child', $actualResult);
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersElseChildIfBeUserWithSpecifiedRoleIsNotLoggedIn() {
+ $actualResult = $this->viewHelper->render('editor');
+ $this->assertEquals('else child', $actualResult);
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersElseChildIfBeUserWithSpecifiedRoleIdIsNotLoggedIn() {
+ $actualResult = $this->viewHelper->render(123);
+ $this->assertEquals('else child', $actualResult);
+ }
+}
+
+?>
require_once(dirname(__FILE__) . '/../ViewHelperBaseTestcase.php');
/**
- * @version $Id:$
*/
class Tx_Fluid_ViewHelpers_Form_ErrorsViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
/**
require_once(dirname(__FILE__) . '/ViewHelperBaseTestcase.php');
/**
- * @version $Id:$
*/
class Tx_Fluid_ViewHelpers_FormViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
/**
/**
* @test
* @author Sebastian Kurfürst <sebastian@typo3.org>
+ * @author Bastian Waidelich <bastian@typo3.org>
*/
public function renderCallsRenderHiddenIdentityField() {
$object = new stdClass();
- $viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_FormViewHelper', array('renderChildren', 'renderRequestHashField', 'renderHiddenIdentityField'), array(), '', FALSE);
+ $viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_FormViewHelper', array('renderChildren', 'renderRequestHashField', 'renderHiddenIdentityField', 'getFormObjectName'), array(), '', FALSE);
$this->injectDependenciesIntoViewHelper($viewHelper);
- $viewHelper->setArguments(new Tx_Fluid_Core_ViewHelper_Arguments(array('object' => $object, 'name' => 'MyName')));
+ $viewHelper->setArguments(new Tx_Fluid_Core_ViewHelper_Arguments(array('object' => $object)));
+ $viewHelper->expects($this->atLeastOnce())->method('getFormObjectName')->will($this->returnValue('MyName'));
$viewHelper->expects($this->once())->method('renderHiddenIdentityField')->with($object, 'MyName');
$viewHelper->render();
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+require_once(dirname(__FILE__) . '/ViewHelperBaseTestcase.php');
+
+/**
+ * Testcase for RenderViewHelper
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Fluid_ViewHelpers_RenderViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
+
+ /**
+ * var Tx_Fluid_ViewHelpers_RenderViewHelper
+ */
+ protected $viewHelper;
+
+ /**
+ * var Tx_Fluid_Core_ViewHelper_Arguments
+ */
+ protected $mockArguments;
+
+ public function setUp() {
+ parent::setUp();
+ $this->templateVariableContainer = new Tx_Fluid_Core_ViewHelper_TemplateVariableContainer();
+ $this->viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_RenderViewHelper', array('dummy'));
+ $this->injectDependenciesIntoViewHelper($this->viewHelper);
+ }
+
+ /**
+ * @test
+ * @author Sebastian Kurfürst <sebastian@typo3.org>
+ */
+ public function loadSettingsIntoArgumentsSetsSettingsIfNoSettingsAreSpecified() {
+ $arguments = array(
+ 'someArgument' => 'someValue'
+ );
+ $expected = array(
+ 'someArgument' => 'someValue',
+ 'settings' => 'theSettings'
+ );
+ $this->templateVariableContainer->add('settings', 'theSettings');
+
+ $actual = $this->viewHelper->_call('loadSettingsIntoArguments', $arguments);
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * @test
+ * @author Sebastian Kurfürst <sebastian@typo3.org>
+ */
+ public function loadSettingsIntoArgumentsDoesNotOverrideGivenSettings() {
+ $arguments = array(
+ 'someArgument' => 'someValue',
+ 'settings' => 'specifiedSettings'
+ );
+ $expected = array(
+ 'someArgument' => 'someValue',
+ 'settings' => 'specifiedSettings'
+ );
+ $this->templateVariableContainer->add('settings', 'theSettings');
+
+ $actual = $this->viewHelper->_call('loadSettingsIntoArguments', $arguments);
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * @test
+ * @author Sebastian Kurfürst <sebastian@typo3.org>
+ */
+ public function loadSettingsIntoArgumentsDoesNotThrowExceptionIfSettingsAreNotInTemplateVariableContainer() {
+ $arguments = array(
+ 'someArgument' => 'someValue'
+ );
+ $expected = array(
+ 'someArgument' => 'someValue'
+ );
+
+ $actual = $this->viewHelper->_call('loadSettingsIntoArguments', $arguments);
+ $this->assertEquals($expected, $actual);
+ }
+
+
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+require_once(dirname(__FILE__) . '/../ViewHelperBaseTestcase.php');
+
+/**
+ * Testcase for security.ifAuthenticated view helper
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Fluid_ViewHelpers_Security_IfAuthenticatedViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
+
+ /**
+ * var Tx_Fluid_ViewHelpers_Security_IfAuthenticatedViewHelper
+ */
+ protected $viewHelper;
+
+ /**
+ * @var tslib_fe
+ */
+ protected $tsfeBackup;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
+ $GLOBALS['TSFE'] = new stdClass();
+ $this->viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_Security_IfAuthenticatedViewHelper', array('renderThenChild', 'renderElseChild'));
+ $this->viewHelper->expects($this->any())->method('renderThenChild')->will($this->returnValue('then child'));
+ $this->viewHelper->expects($this->any())->method('renderElseChild')->will($this->returnValue("else child"));
+ $this->injectDependenciesIntoViewHelper($this->viewHelper);
+ $this->viewHelper->initializeArguments();
+ }
+
+ public function tearDown() {
+ $GLOBALS['TSFE'] = $this->tsfeBackup;
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersThenChildIfFeUserIsLoggedIn() {
+ $GLOBALS['TSFE']->loginUser = 1;
+
+ $actualResult = $this->viewHelper->render();
+ $this->assertEquals('then child', $actualResult);
+ }
+
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersElseChildIfFeUserIsNotLoggedIn() {
+ $GLOBALS['TSFE']->loginUser = 0;
+
+ $actualResult = $this->viewHelper->render();
+ $this->assertEquals('else child', $actualResult);
+ }
+}
+
+?>
--- /dev/null
+<?php
+
+/* *
+ * This script belongs to the FLOW3 package "Fluid". *
+ * *
+ * It is free software; you can redistribute it and/or modify it under *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version. *
+ * *
+ * This script is distributed in the hope that it will be useful, but *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with the script. *
+ * If not, see http://www.gnu.org/licenses/lgpl.html *
+ * *
+ * The TYPO3 project - inspiring people to share! *
+ * */
+
+require_once(dirname(__FILE__) . '/../ViewHelperBaseTestcase.php');
+
+/**
+ * Testcase for security.ifHasRole view helper
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ */
+class Tx_Fluid_ViewHelpers_Security_IfHasRoleViewHelperTest extends Tx_Fluid_ViewHelpers_ViewHelperBaseTestcase {
+
+ /**
+ * var Tx_Fluid_ViewHelpers_Security_IfHasRoleViewHelper
+ */
+ protected $viewHelper;
+
+ /**
+ * @var tslib_fe
+ */
+ protected $tsfeBackup;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->tsfeBackup = isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
+ $GLOBALS['TSFE'] = new stdClass();
+ $GLOBALS['TSFE']->loginUser = 1;
+ $GLOBALS['TSFE']->fe_user->groupData = array(
+ 'uid' => array(1,2),
+ 'title' => array('Editor', 'OtherRole')
+ );
+ $this->viewHelper = $this->getAccessibleMock('Tx_Fluid_ViewHelpers_Security_IfHasRoleViewHelper', array('renderThenChild', 'renderElseChild'));
+ $this->viewHelper->expects($this->any())->method('renderThenChild')->will($this->returnValue('then child'));
+ $this->viewHelper->expects($this->any())->method('renderElseChild')->will($this->returnValue("else child"));
+ $this->injectDependenciesIntoViewHelper($this->viewHelper);
+ $this->viewHelper->initializeArguments();
+ }
+
+ public function tearDown() {
+ $GLOBALS['TSFE'] = $this->tsfeBackup;
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersThenChildIfFeUserWithSpecifiedRoleIsLoggedIn() {
+ $actualResult = $this->viewHelper->render('Editor');
+ $this->assertEquals('then child', $actualResult);
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersThenChildIfFeUserWithSpecifiedRoleIdIsLoggedIn() {
+ $actualResult = $this->viewHelper->render(1);
+ $this->assertEquals('then child', $actualResult);
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersElseChildIfFeUserWithSpecifiedRoleIsNotLoggedIn() {
+ $actualResult = $this->viewHelper->render('NonExistingRole');
+ $this->assertEquals('else child', $actualResult);
+ }
+
+ /**
+ * @test
+ */
+ public function viewHelperRendersElseChildIfFeUserWithSpecifiedRoleIdIsNotLoggedIn() {
+ $actualResult = $this->viewHelper->render(123);
+ $this->assertEquals('else child', $actualResult);
+ }
+}
+
+?>
'clearCacheOnLoad' => 0,
'lockType' => '',
'author_company' => '',
- 'version' => '1.3.0alpha1',
+ 'version' => '1.3.0alpha2',
'constraints' => array(
'depends' => array(
- 'extbase' => '1.3.0alpha1',
+ 'extbase' => '1.3.0alpha2',
),
'conflicts' => array(
),
-https://svn.typo3.org/TYPO3v4/CoreProjects/MVC/fluid/tags/1.3.0alpha1/
+https://svn.typo3.org/TYPO3v4/CoreProjects/MVC/fluid/tags/1.3.0alpha2/