[TASK] Extract displayCond functionality from FormEngine to new class 80/19080/11
authorSebastian Michaelsen <michaelsen@t3seo.de>
Wed, 20 Mar 2013 12:33:54 +0000 (13:33 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sun, 31 Mar 2013 11:34:17 +0000 (13:34 +0200)
In order to streamline \TYPO3\CMS\Backend\Form\FormEngine
(formerly t3lib_TCEforms) the functionality for 'displayCond' is extracted
into a new class: \TYPO3\CMS\Backend\Form\ElementConditionMatcher

* Refactor the code a bit without changing it's behaviour
* Deprecate FormEngine->isDisplayCondition() and remove its core usages
* Add a bit of documentation in the new class
* Add Unit tests

Releases: 6.1
Resolves: #46461
Change-Id: Ie199fe0600a70231f1e7b710a09164364cef8578
Reviewed-on: https://review.typo3.org/19080
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/backend/Classes/Form/ElementConditionMatcher.php [new file with mode: 0644]
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Tests/Unit/Form/ElementConditionMatcherTest.php [new file with mode: 0644]

diff --git a/typo3/sysext/backend/Classes/Form/ElementConditionMatcher.php b/typo3/sysext/backend/Classes/Form/ElementConditionMatcher.php
new file mode 100644 (file)
index 0000000..8a439aa
--- /dev/null
@@ -0,0 +1,265 @@
+<?php
+namespace TYPO3\CMS\Backend\Form;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Sebastian Michaelsen (michaelsen@t3seo.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.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *  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!
+ ***************************************************************/
+
+/**
+ * Class ElementConditionMatcher implements the TCA 'displayCond' option.
+ * The display condition is a colon separated string which describes
+ * the condition to decide whether a form field should be displayed.
+ */
+class ElementConditionMatcher {
+
+       /**
+        * @var string
+        */
+       protected $flexformValueKey = '';
+
+       /**
+        * @var array
+        */
+       protected $record = array();
+
+       /**
+        * Evaluates the provided condition and returns TRUE if the form
+        * element should be displayed.
+        *
+        * The condition string is separated by colons and the first part
+        * indicates what type of evaluation should be performed.
+        *
+        * @param string $displayCondition
+        * @param array $record
+        * @param string $flexformValueKey
+        * @return boolean
+        */
+       public function match($displayCondition, array $record = array(), $flexformValueKey = '') {
+               $this->record = $record;
+               $this->flexformValueKey = $flexformValueKey;
+               $result = FALSE;
+               list($matchType, $condition) = explode(':', $displayCondition, 2);
+               switch ($matchType) {
+                       case 'EXT':
+                               $result = $this->matchExtensionCondition($condition);
+                               break;
+                       case 'FIELD':
+                               $result = $this->matchFieldCondition($condition);
+                               break;
+                       case 'HIDE_FOR_NON_ADMINS':
+                               $result = $this->matchHideForNonAdminsCondition();
+                               break;
+                       case 'HIDE_L10N_SIBLINGS':
+                               $result = $this->matchHideL10nSiblingsCondition($condition);
+                               break;
+                       case 'REC':
+                               $result = $this->matchRecordCondition($condition);
+                               break;
+                       case 'VERSION':
+                               $result = $this->matchVersionCondition($condition);
+                               break;
+               }
+               return $result;
+       }
+
+       /**
+        * Evaluates conditions concerning extensions
+        *
+        * Example:
+        * "EXT:saltedpasswords:LOADED:TRUE" => TRUE, if extension saltedpasswords is loaded.
+        *
+        * @param string $condition
+        * @return boolean
+        */
+       protected function matchExtensionCondition($condition) {
+               $result = FALSE;
+               list($extensionKey, $operator, $operand) = explode(':', $condition, 3);
+               if ($operator === 'LOADED') {
+                       if (strtoupper($operand) === 'TRUE') {
+                               $result = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extensionKey);
+                       } elseif (strtoupper($operand) === 'FALSE') {
+                               $result = !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extensionKey);
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Evaluates conditions concerning a field of the current record.
+        * Requires a record set via ->setRecord()
+        *
+        * Example:
+        * "FIELD:sys_language_uid:>:0" => TRUE, if the field 'sys_language_uid' is greater than 0
+        *
+        * @param string $condition
+        * @return boolean
+        */
+       protected function matchFieldCondition($condition) {
+               list($fieldName, $operator, $operand) = explode(':', $condition, 3);
+               if ($this->flexformValueKey) {
+                       if (strpos($fieldName, 'parentRec.') !== FALSE) {
+                               $fieldNameParts = explode('.', $fieldName, 2);
+                               $fieldValue = $this->record['parentRec'][$fieldNameParts[1]];
+                       } else {
+                               $fieldValue = $this->record[$fieldName][$this->flexformValueKey];
+                       }
+               } else {
+                       $fieldValue = $this->record[$fieldName];
+               }
+
+               $result = FALSE;
+               switch ($operator) {
+                       case 'REQ':
+                               if (strtoupper($operand) === 'TRUE') {
+                                       $result = (bool) $fieldValue;
+                               } else {
+                                       $result = !$fieldValue;
+                               }
+                               break;
+                       case '>':
+                               $result = $fieldValue > $operand;
+                               break;
+                       case '<':
+                               $result = $fieldValue < $operand;
+                               break;
+                       case '>=':
+                               $result = $fieldValue >= $operand;
+                               break;
+                       case '<=':
+                               $result = $fieldValue <= $operand;
+                               break;
+                       case '-':
+                       case '!-':
+                               list($minimum, $maximum) = explode('-', $operand);
+                               $result = $fieldValue >= $minimum && $fieldValue <= $maximum;
+                               if ($operator{0} === '!') {
+                                       $result = !$result;
+                               }
+                               break;
+                       case 'IN':
+                       case '!IN':
+                       case '=':
+                       case '!=':
+                               $result = \TYPO3\CMS\Core\Utility\GeneralUtility::inList($operand, $fieldValue);
+                               if ($operator{0} === '!') {
+                                       $result = !$result;
+                               }
+                               break;
+               }
+               return $result;
+       }
+
+       /**
+        * Evaluates TRUE if current backend user is an admin.
+        *
+        * @return boolean
+        */
+       protected function matchHideForNonAdminsCondition() {
+               return (bool) $this->getBackendUser()->isAdmin();
+       }
+
+       /**
+        * Evaluates whether the field is a value for the default language.
+        * Works only for <langChildren>=1, otherwise it has no effect.
+        *
+        * @param string $condition
+        * @return boolean
+        */
+       protected function matchHideL10nSiblingsCondition($condition) {
+               $result = FALSE;
+               if ($this->flexformValueKey === 'vDEF') {
+                       $result = TRUE;
+               } elseif ($condition === 'except_admin' && $this->getBackendUser()->isAdmin()) {
+                       $result = TRUE;
+               }
+               return $result;
+       }
+
+       /**
+        * Evaluates conditions concerning the status of the current record.
+        * Requires a record set via ->setRecord()
+        *
+        * Example:
+        * "REC:NEW:FALSE" => TRUE, if the record is already persisted (has a uid > 0)
+        *
+        * @param string $condition
+        * @return boolean
+        */
+       protected function matchRecordCondition($condition) {
+               $result = FALSE;
+               list($operator, $operand) = explode(':', $condition, 2);
+               if ($operator === 'NEW') {
+                       if (strtoupper($operand) === 'TRUE') {
+                               $result = !(intval($this->record['uid']) > 0);
+                       } elseif (strtoupper($operand) === 'FALSE') {
+                               $result = (intval($this->record['uid']) > 0);
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Evaluates whether the current record is versioned.
+        * Requires a record set via ->setRecord()
+        *
+        * @param string $condition
+        * @return boolean
+        */
+       protected function matchVersionCondition($condition) {
+               $result = FALSE;
+               list($operator, $operand) = explode(':', $condition, 2);
+               if ($operator === 'IS') {
+                       $isNewRecord = !(intval($this->record['uid']) > 0);
+                       // Detection of version can be done be detecting the workspace of the user
+                       $isUserInWorkspace = $this->getBackendUser()->workspace > 0;
+                       if (intval($this->record['pid']) == -1 || intval($this->record['_ORIG_pid']) == -1) {
+                               $isRecordDetectedAsVersion = TRUE;
+                       } else {
+                               $isRecordDetectedAsVersion = FALSE;
+                       }
+                       // New records in a workspace are not handled as a version record
+                       // if it's no new version, we detect versions like this:
+                       // -- if user is in workspace: always TRUE
+                       // -- if editor is in live ws: only TRUE if pid == -1
+                       $isVersion = ($isUserInWorkspace || $isRecordDetectedAsVersion) && !$isNewRecord;
+                       if (strtoupper($operand) === 'TRUE') {
+                               $result = $isVersion;
+                       } elseif (strtoupper($operand) === 'FALSE') {
+                               $result = !$isVersion;
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Get current backend user
+        *
+        * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
+        */
+       protected function getBackendUser() {
+               return $GLOBALS['BE_USER'];
+       }
+}
+
+?>
\ No newline at end of file
index ebd6c34..5dc5b2f 100644 (file)
@@ -26,14 +26,7 @@ namespace TYPO3\CMS\Backend\Form;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-/**
- * Contains TYPO3 Core Form generator - AKA "TCEforms"
- *
- * Revised for TYPO3 3.6 August/2003 by Kasper Skårhøj
- * XHTML compliant
- *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- */
+
 /**
  * 'TCEforms' - Class for creating the backend editing forms.
  *
@@ -1008,8 +1001,26 @@ class FormEngine {
                $PA['fieldConf']['config']['form_type'] = $PA['fieldConf']['config']['form_type'] ? $PA['fieldConf']['config']['form_type'] : $PA['fieldConf']['config']['type'];
                // Using "form_type" locally in this script
                $skipThisField = $this->inline->skipField($table, $field, $row, $PA['fieldConf']['config']);
-               // Now, check if this field is configured and editable (according to excludefields + other configuration)
-               if (is_array($PA['fieldConf']) && !$skipThisField && (!$PA['fieldConf']['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $table . ':' . $field)) && $PA['fieldConf']['config']['form_type'] != 'passthrough' && ($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE']) && (!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'], $row)) && (!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || $PA['fieldConf']['l10n_display'] || strcmp($PA['fieldConf']['l10n_mode'], 'exclude') || $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] <= 0) && (!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode === $PA['fieldConf']['l10n_cat'])) {
+
+               // Evaluate display condition
+               $displayConditionResult = TRUE;
+               if (is_array($PA['fieldConf']) && $PA['fieldConf']['displayCond'] && is_array($row)) {
+                       /** @var $elementConditionMatcher \TYPO3\CMS\Backend\Form\ElementConditionMatcher */
+                       $elementConditionMatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\ElementConditionMatcher');
+                       $displayConditionResult = $elementConditionMatcher->match($PA['fieldConf']['displayCond'], $row);
+               }
+
+               // Check if this field is configured and editable (according to excludefields + other configuration)
+               if (
+                       is_array($PA['fieldConf'])
+                       && !$skipThisField
+                       && (!$PA['fieldConf']['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $table . ':' . $field))
+                       && $PA['fieldConf']['config']['form_type'] != 'passthrough'
+                       && ($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE'])
+                       && $displayConditionResult
+                       && (!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || $PA['fieldConf']['l10n_display'] || strcmp($PA['fieldConf']['l10n_mode'], 'exclude') || $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] <= 0)
+                       && (!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || !$this->localizationMode || $this->localizationMode === $PA['fieldConf']['l10n_cat'])
+               ) {
                        // Fetching the TSconfig for the current table/field. This includes the $row which means that
                        $PA['fieldTSConfig'] = $this->setTSconfig($table, $row, $field);
                        // If the field is NOT disabled from TSconfig (which it could have been) then render it
@@ -2613,6 +2624,10 @@ function ' . $evalData . '(value) {
                        } else {
                                $tabsToTraverse = array($sheet);
                        }
+
+                       /** @var $elementConditionMatcher \TYPO3\CMS\Backend\Form\ElementConditionMatcher */
+                       $elementConditionMatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\ElementConditionMatcher');
+
                        foreach ($rotateLang as $lKey) {
                                if (!$langChildren && !$langDisabled) {
                                        $item .= '<strong>' . $this->getLanguageIcon($table, $row, ('v' . $lKey)) . $lKey . ':</strong>';
@@ -2650,8 +2665,12 @@ function ' . $evalData . '(value) {
                                                        $skipCondition = TRUE;
                                                        break;
                                                }
+                                               $displayConditionResult = TRUE;
+                                               if ($dataStruct['ROOT']['TCEforms']['displayCond']) {
+                                                       $displayConditionResult = $elementConditionMatcher->match($dataStruct['ROOT']['TCEforms']['displayCond'], $fakeRow, 'vDef');
+                                               }
                                                // If sheets displayCond leads to false
-                                               if (!$skipCondition && !$this->isDisplayCondition($dataStruct['ROOT']['TCEforms']['displayCond'], $fakeRow, 'vDEF')) {
+                                               if (!$skipCondition && !$displayConditionResult) {
                                                        // Don't create this sheet
                                                        continue;
                                                }
@@ -2912,9 +2931,17 @@ function ' . $evalData . '(value) {
                                                // Add current $row to data processed by isDisplayCondition()
                                                $conditionData['parentRec'] = $row;
                                                $tRows = array();
+
+                                               /** @var $elementConditionMatcher \TYPO3\CMS\Backend\Form\ElementConditionMatcher */
+                                               $elementConditionMatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\ElementConditionMatcher');
+
                                                foreach ($rotateLang as $vDEFkey) {
                                                        $vDEFkey = 'v' . $vDEFkey;
-                                                       if (!$value['TCEforms']['displayCond'] || $this->isDisplayCondition($value['TCEforms']['displayCond'], $conditionData, $vDEFkey)) {
+                                                       $displayConditionResult = TRUE;
+                                                       if ($value['TCEforms']['displayCond']) {
+                                                               $displayConditionResult = $elementConditionMatcher->match($value['TCEforms']['displayCond'], $conditionData, $vDEFkey);
+                                                       }
+                                                       if ($displayConditionResult) {
                                                                $fakePA = array();
                                                                $fakePA['fieldConf'] = array(
                                                                        'label' => $this->sL(trim($value['TCEforms']['label'])),
@@ -5918,130 +5945,15 @@ function ' . $evalData . '(value) {
         * @param string $ffValueKey FlexForm value key, eg. vDEF
         * @return boolean
         * @todo Define visibility
+        * @deprecated since TYPO3 6.1, will be removed 2 versions later - Use \TYPO3\CMS\Backend\Form\ElementConditionMatcher instead
         */
        public function isDisplayCondition($displayCond, $row, $ffValueKey = '') {
-               $output = FALSE;
-               $parts = explode(':', $displayCond);
-               // Type of condition:
-               switch ((string) $parts[0]) {
-               case 'FIELD':
-                       if ($ffValueKey) {
-                               if (strpos($parts[1], 'parentRec.') !== FALSE) {
-                                       $fParts = explode('.', $parts[1]);
-                                       $theFieldValue = $row['parentRec'][$fParts[1]];
-                               } else {
-                                       $theFieldValue = $row[$parts[1]][$ffValueKey];
-                               }
-                       } else {
-                               $theFieldValue = $row[$parts[1]];
-                       }
-                       switch ((string) $parts[2]) {
-                       case 'REQ':
-                               if (strtolower($parts[3]) == 'true') {
-                                       $output = $theFieldValue ? TRUE : FALSE;
-                               } elseif (strtolower($parts[3]) == 'false') {
-                                       $output = !$theFieldValue ? TRUE : FALSE;
-                               }
-                               break;
-                       case '>':
-                               $output = $theFieldValue > $parts[3];
-                               break;
-                       case '<':
-                               $output = $theFieldValue < $parts[3];
-                               break;
-                       case '>=':
-                               $output = $theFieldValue >= $parts[3];
-                               break;
-                       case '<=':
-                               $output = $theFieldValue <= $parts[3];
-                               break;
-                       case '-':
-
-                       case '!-':
-                               $cmpParts = explode('-', $parts[3]);
-                               $output = $theFieldValue >= $cmpParts[0] && $theFieldValue <= $cmpParts[1];
-                               if ($parts[2][0] == '!') {
-                                       $output = !$output;
-                               }
-                               break;
-                       case 'IN':
-
-                       case '!IN':
-                               $output = \TYPO3\CMS\Core\Utility\GeneralUtility::inList($parts[3], $theFieldValue);
-                               if ($parts[2][0] == '!') {
-                                       $output = !$output;
-                               }
-                               break;
-                       case '=':
-
-                       case '!=':
-                               $output = \TYPO3\CMS\Core\Utility\GeneralUtility::inList($parts[3], $theFieldValue);
-                               if ($parts[2][0] == '!') {
-                                       $output = !$output;
-                               }
-                               break;
-                       }
-                       break;
-               case 'EXT':
-                       switch ((string) $parts[2]) {
-                       case 'LOADED':
-                               if (strtolower($parts[3]) == 'true') {
-                                       $output = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($parts[1]) ? TRUE : FALSE;
-                               } elseif (strtolower($parts[3]) == 'false') {
-                                       $output = !\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($parts[1]) ? TRUE : FALSE;
-                               }
-                               break;
-                       }
-                       break;
-               case 'REC':
-                       switch ((string) $parts[1]) {
-                       case 'NEW':
-                               if (strtolower($parts[2]) == 'true') {
-                                       $output = !(intval($row['uid']) > 0) ? TRUE : FALSE;
-                               } elseif (strtolower($parts[2]) == 'false') {
-                                       $output = intval($row['uid']) > 0 ? TRUE : FALSE;
-                               }
-                               break;
-                       }
-                       break;
-               case 'HIDE_L10N_SIBLINGS':
-                       if ($ffValueKey === 'vDEF') {
-                               $output = TRUE;
-                       } elseif ($parts[1] === 'except_admin' && $GLOBALS['BE_USER']->isAdmin()) {
-                               $output = TRUE;
-                       }
-                       break;
-               case 'HIDE_FOR_NON_ADMINS':
-                       $output = $GLOBALS['BE_USER']->isAdmin() ? TRUE : FALSE;
-                       break;
-               case 'VERSION':
-                       switch ((string) $parts[1]) {
-                       case 'IS':
-                               $isNewRecord = intval($row['uid']) > 0 ? FALSE : TRUE;
-                               // Detection of version can be done be detecting the workspace of the user
-                               $isUserInWorkspace = $GLOBALS['BE_USER']->workspace > 0 ? TRUE : FALSE;
-                               if (intval($row['pid']) == -1 || intval($row['_ORIG_pid']) == -1) {
-                                       $isRecordDetectedAsVersion = TRUE;
-                               } else {
-                                       $isRecordDetectedAsVersion = FALSE;
-                               }
-                               // New records in a workspace are not handled as a version record
-                               // if it's no new version, we detect versions like this:
-                               // -- if user is in workspace: always TRUE
-                               // -- if editor is in live ws: only TRUE if pid == -1
-                               $isVersion = ($isUserInWorkspace || $isRecordDetectedAsVersion) && !$isNewRecord;
-                               if (strtolower($parts[2]) == 'true') {
-                                       $output = $isVersion;
-                               } else {
-                                       if (strtolower($parts[2]) == 'false') {
-                                               $output = !$isVersion;
-                                       }
-                               }
-                               break;
-                       }
-                       break;
-               }
-               return $output;
+               \TYPO3\CMS\Core\Utility\GeneralUtility::logDeprecatedFunction();
+               /** @var $elementConditionMatcher \TYPO3\CMS\Backend\Form\ElementConditionMatcher */
+               $elementConditionMatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Form\\ElementConditionMatcher');
+               $elementConditionMatcher->setRecord($row);
+               $elementConditionMatcher->setFlexformValueKey($ffValueKey);
+               return $elementConditionMatcher->match($displayCond);
        }
 
        /**
diff --git a/typo3/sysext/backend/Tests/Unit/Form/ElementConditionMatcherTest.php b/typo3/sysext/backend/Tests/Unit/Form/ElementConditionMatcherTest.php
new file mode 100644 (file)
index 0000000..9b6d9d5
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+namespace TYPO3\CMS\Backend\Tests\Unit\Form\Element;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Sebastian Michaelsen <michaelsen@t3seo.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!
+ ***************************************************************/
+
+/**
+ * Test case
+ */
+class ElementConditionMatcherTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
+
+       /**
+        * @var \TYPO3\CMS\Backend\Form\ElementConditionMatcher
+        */
+       protected $fixture;
+
+       /**
+        * Sets up this test case.
+        */
+       protected function setUp() {
+               $this->fixture = new \TYPO3\CMS\Backend\Form\ElementConditionMatcher();
+       }
+
+       /**
+        * Tears down this test case.
+        */
+       protected function tearDown() {
+               unset($this->fixture);
+       }
+
+       /**
+        * Returns data sets for the test matchConditionStrings
+        * Each dataset is an array with the following elements:
+        * - the condition string
+        * - the current record
+        * - the current flexform value key
+        * - the expected result
+        *
+        * @return array
+        */
+       public function conditionStringDataProvider() {
+               return array(
+                       'Invalid condition string' => array(
+                               'xINVALIDx:', array(), NULL, FALSE,
+                       ),
+                       'EXT (#1)' => array (
+                               'EXT:neverloadedext:LOADED:TRUE', array(), NULL, FALSE
+                       ),
+                       'EXT (#2)' => array (
+                               'EXT:neverloadedext:LOADED:FALSE', array(), NULL, TRUE
+                       ),
+                       'EXT (#3)' => array (
+                               'EXT:backend:LOADED:TRUE', array(), NULL, TRUE
+                       ),
+                       'EXT (#4)' => array (
+                               'EXT:backend:LOADED:FALSE', array(), NULL, FALSE
+                       ),
+                       'FIELD (#1)' => array(
+                               'FIELD:uid:>:0', array(), NULL, FALSE
+                       ),
+                       'FIELD (#2)' => array(
+                               'FIELD:uid:=:0', array(), NULL, FALSE
+                       ),
+                       'FIELD (#3)' => array(
+                               'FIELD:foo:=:bar', array('foo' => 'bar'), NULL, TRUE
+                       ),
+                       'FIELD (#4)' => array(
+                               'FIELD:foo:REQ:FALSE', array('foo' => 'bar'), NULL, FALSE
+                       ),
+                       'FIELD (#5)' => array(
+                               'FIELD:foo:!=:baz', array('foo' => 'bar'), NULL, TRUE
+                       ),
+                       'FIELD (#6)' => array(
+                               'FIELD:uid:-:3-42', array('uid' => '23'), NULL, TRUE
+                       ),
+                       'FIELD (#7)' => array(
+                               'FIELD:uid:>=:42', array('uid' => '23'), NULL, FALSE
+                       ),
+                       'FIELD (#8)' => array(
+                               'FIELD:foo:=:bar', array('foo' => array('vDEF' => 'bar')), 'vDEF', TRUE
+                       ),
+                       'FIELD (#9)' => array(
+                               'FIELD:parentRec.foo:=:bar', array('parentRec' => array('foo' => 'bar')), 'vDEF', TRUE
+                       ),
+                       'HIDE_L10N_SIBLINGS (#1)' => array(
+                               'HIDE_L10N_SIBLINGS', array(), NULL, FALSE
+                       ),
+                       'HIDE_L10N_SIBLINGS (#2)' => array(
+                               'HIDE_L10N_SIBLINGS', array(), 'vDEF', TRUE
+                       ),
+                       'HIDE_L10N_SIBLINGS (#3)' => array(
+                               'HIDE_L10N_SIBLINGS', array(), 'vEN', FALSE
+                       ),
+                       'REC (#1)' => array(
+                               'REC:NEW:TRUE', array('uid' => NULL), NULL, TRUE
+                       ),
+                       'REC (#2)' => array(
+                               'REC:NEW:FALSE', array('uid' => NULL), NULL, FALSE
+                       ),
+                       'REC (#3)' => array(
+                               'REC:NEW:TRUE', array('uid' => 42), NULL, FALSE
+                       ),
+                       'REC (#4)' => array(
+                               'REC:NEW:FALSE', array('uid' => 42), NULL, TRUE
+                       ),
+                       'VERSION (#1)' => array(
+                               'VERSION:IS:TRUE', array('uid' => 42, 'pid' => -1), NULL, TRUE
+                       ),
+                       'VERSION (#2)' => array(
+                               'VERSION:IS:FALSE', array('uid' => 42, 'pid' => 1), NULL, TRUE
+                       ),
+                       'VERSION (#3)' => array(
+                               'VERSION:IS:TRUE', array('uid' => NULL, 'pid' => NULL), NULL, FALSE
+                       ),
+               );
+       }
+
+       /**
+        * @param string $condition
+        * @param array $record
+        * @param string $flexformValueKey
+        * @param string $expectedResult
+        * @dataProvider conditionStringDataProvider
+        * @test
+        */
+       public function matchConditionStrings($condition, array $record, $flexformValueKey, $expectedResult) {
+               $this->assertEquals($expectedResult, $this->fixture->match($condition, $record, $flexformValueKey));
+       }
+
+       /**
+        * @test
+        */
+       public function matchHideForNonAdminsReturnsTrueIfBackendUserIsAdmin() {
+               /** @var $backendUserMock \TYPO3\CMS\Core\Authentication\BackendUserAuthentication|\PHPUnit_Framework_MockObject_MockObject */
+               $backendUserMock = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
+               $backendUserMock
+                       ->expects($this->once())
+                       ->method('isAdmin')
+                       ->will($this->returnValue(TRUE));
+               $GLOBALS['BE_USER'] = $backendUserMock;
+               $this->assertTrue($this->fixture->match('HIDE_FOR_NON_ADMINS'));
+       }
+
+       /**
+        * @test
+        */
+       public function matchHideForNonAdminsReturnsFalseIfBackendUserIsNotAdmin() {
+               /** @var $backendUserMock \TYPO3\CMS\Core\Authentication\BackendUserAuthentication|\PHPUnit_Framework_MockObject_MockObject */
+               $backendUserMock = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
+               $backendUserMock
+                       ->expects($this->once())
+                       ->method('isAdmin')
+                       ->will($this->returnValue(FALSE));
+               $GLOBALS['BE_USER'] = $backendUserMock;
+               $this->assertFalse($this->fixture->match('HIDE_FOR_NON_ADMINS'));
+       }
+
+       /**
+        * @test
+        */
+       public function matchHideL10NSiblingsExceptAdminReturnsTrueIfBackendUserIsAdmin() {
+               /** @var $backendUserMock \TYPO3\CMS\Core\Authentication\BackendUserAuthentication|\PHPUnit_Framework_MockObject_MockObject */
+               $backendUserMock = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
+               $backendUserMock
+                       ->expects($this->once())
+                       ->method('isAdmin')
+                       ->will($this->returnValue(TRUE));
+               $GLOBALS['BE_USER'] = $backendUserMock;
+               $this->assertTrue($this->fixture->match('HIDE_L10N_SIBLINGS:except_admin'), array(), 'vEN');
+       }
+
+       /**
+        * @test
+        */
+       public function matchHideL10NSiblingsExceptAdminReturnsFalseIfBackendUserIsNotAdmin() {
+               /** @var $backendUserMock \TYPO3\CMS\Core\Authentication\BackendUserAuthentication|\PHPUnit_Framework_MockObject_MockObject */
+               $backendUserMock = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
+               $backendUserMock
+                       ->expects($this->once())
+                       ->method('isAdmin')
+                       ->will($this->returnValue(FALSE));
+               $GLOBALS['BE_USER'] = $backendUserMock;
+               $this->assertFalse($this->fixture->match('HIDE_L10N_SIBLINGS:except_admin'), array(), 'vEN');
+       }
+}
+?>
\ No newline at end of file