[BUGFIX] Exception in EXT:form due to invalid array lookup 95/50995/5
authorOliver Hader <oliver@typo3.org>
Sun, 18 Dec 2016 13:15:43 +0000 (14:15 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Mon, 19 Dec 2016 16:03:58 +0000 (17:03 +0100)
Due to the changes of ArrayUtility in issue #77732
EXT:form now has to deal with these problems:

+ core's ArrayUtility uses a slash "/" as delimiter,
  but Extbase's ArrayUtility used a dot "."
+ core's ArrayUtility throws an exception if value is
  not defined, Extbase's ArrayUtility returned null

Change-Id: I26b043a28e376c99d50a9a36703b5927b09ee934
Resolves: #79024
Releases: master
Reviewed-on: https://review.typo3.org/50995
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Ralf Zimmermann <ralf.zimmermann@tritum.de>
Tested-by: Ralf Zimmermann <ralf.zimmermann@tritum.de>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/form/Classes/Domain/Finishers/AbstractFinisher.php
typo3/sysext/form/Classes/Domain/Model/FormDefinition.php
typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php
typo3/sysext/form/Classes/Domain/Runtime/FormState.php
typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php
typo3/sysext/form/Classes/Mvc/Configuration/InheritancesResolverService.php
typo3/sysext/form/Classes/Service/TranslationService.php

index 8302cb4..1627162 100644 (file)
@@ -135,8 +135,16 @@ abstract class AbstractFinisher implements FinisherInterface
             return null;
         }
 
-        $optionValue = ArrayUtility::getValueByPath($this->options, $optionName);
-        $defaultValue = ArrayUtility::getValueByPath($this->defaultOptions, $optionName);
+        try {
+            $optionValue = ArrayUtility::getValueByPath($this->options, $optionName, '.');
+        } catch (\RuntimeException $exception) {
+            $optionValue = null;
+        }
+        try {
+            $defaultValue = ArrayUtility::getValueByPath($this->defaultOptions, $optionName, '.');
+        } catch (\RuntimeException $exception) {
+            $defaultValue = null;
+        }
 
         if ($optionValue === null && $defaultValue !== null) {
             $optionValue = $defaultValue;
index 11d6050..3168689 100644 (file)
@@ -575,7 +575,12 @@ class FormDefinition extends AbstractCompositeRenderable
      */
     public function addElementDefaultValue(string $elementIdentifier, $defaultValue)
     {
-        $this->elementDefaultValues = ArrayUtility::setValueByPath($this->elementDefaultValues, $elementIdentifier, $defaultValue);
+        $this->elementDefaultValues = ArrayUtility::setValueByPath(
+            $this->elementDefaultValues,
+            $elementIdentifier,
+            $defaultValue,
+            '.'
+        );
     }
 
     /**
index 295f5fb..70c162c 100644 (file)
@@ -23,7 +23,6 @@ use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
 use TYPO3\CMS\Extbase\Mvc\Web\Request;
 use TYPO3\CMS\Extbase\Mvc\Web\Response;
 use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
-use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Extbase\Property\Exception as PropertyException;
 use TYPO3\CMS\Extbase\Reflection\PropertyReflection;
 use TYPO3\CMS\Form\Domain\Exception\RenderingException;
@@ -404,7 +403,11 @@ class FormRuntime implements RootRenderableInterface, \ArrayAccess
             }
         };
         foreach ($page->getElementsRecursively() as $element) {
-            $value = ArrayUtility::getValueByPath($requestArguments, $element->getIdentifier());
+            try {
+                $value = ArrayUtility::getValueByPath($requestArguments, $element->getIdentifier(), '.');
+            } catch (\RuntimeException $exception) {
+                $value = null;
+            }
             $element->onSubmit($this, $value, $requestArguments);
 
             $this->formState->setFormValue($element->getIdentifier(), $value);
index e6acc5b..e064a9c 100644 (file)
@@ -86,7 +86,12 @@ class FormState
      */
     public function setFormValue(string $propertyPath, $value)
     {
-        $this->formValues = ArrayUtility::setValueByPath($this->formValues, $propertyPath, $value);
+        $this->formValues = ArrayUtility::setValueByPath(
+            $this->formValues,
+            $propertyPath,
+            $value,
+            '.'
+        );
     }
 
     /**
@@ -95,6 +100,10 @@ class FormState
      */
     public function getFormValue(string $propertyPath)
     {
-        return ArrayUtility::getValueByPath($this->formValues, $propertyPath);
+        try {
+            return ArrayUtility::getValueByPath($this->formValues, $propertyPath, '.');
+        } catch (\RuntimeException $exception) {
+            return null;
+        }
     }
 }
index 7d9c700..776e321 100644 (file)
@@ -168,8 +168,20 @@ class DataStructureIdentifierHook
             foreach ($finisherValue['options'] as $optionKey => $optionValue) {
                 if (is_array($optionValue)) {
                     $optionKey = $optionKey . '.' . $this->extractDottedPathToLastElement($finisherValue['options'][$optionKey]);
-                    $elementConfiguration = ArrayUtility::getValueByPath($finishersDefinition[$finisherIdentifier]['FormEngine']['elements'], $optionKey);
-                    $optionValue = ArrayUtility::getValueByPath($finisherValue['options'], $optionKey);
+                    try {
+                        $elementConfiguration = ArrayUtility::getValueByPath(
+                            $finishersDefinition[$finisherIdentifier]['FormEngine']['elements'],
+                            $optionKey,
+                            '.'
+                        );
+                    } catch (\RuntimeException $exception) {
+                        $elementConfiguration = null;
+                    }
+                    try {
+                        $optionValue = ArrayUtility::getValueByPath($finisherValue['options'], $optionKey, '.');
+                    } catch (\RuntimeException $exception) {
+                        $optionValue = null;
+                    }
                 } else {
                     $elementConfiguration = $finishersDefinition[$finisherIdentifier]['FormEngine']['elements'][$optionKey];
                 }
index ce86670..28262a5 100644 (file)
@@ -143,10 +143,15 @@ class InheritancesResolverService
 
             if (is_array($configuration[$key])) {
                 if (isset($configuration[$key][self::INHERITANCE_OPERATOR])) {
-                    $inheritances = static::getValueByPathHelper(
-                        $this->referenceConfiguration,
-                        $path . '.' . self::INHERITANCE_OPERATOR
-                    );
+                    try {
+                        $inheritances = ArrayUtility::getValueByPath(
+                            $this->referenceConfiguration,
+                            $path . '.' . self::INHERITANCE_OPERATOR,
+                            '.'
+                        );
+                    } catch (\RuntimeException $exception) {
+                        $inheritances = null;
+                    }
 
                     if (is_array($inheritances)) {
                         $inheritedConfigurations = $this->resolveInheritancesRecursive($inheritances);
@@ -187,10 +192,15 @@ class InheritancesResolverService
         $inheritedConfigurations = [];
         foreach ($inheritances as $inheritancePath) {
             $this->throwExceptionIfCycleInheritances($inheritancePath, $inheritancePath);
-            $inheritedConfiguration = static::getValueByPathHelper(
-                $this->referenceConfiguration,
-                $inheritancePath
-            );
+            try {
+                $inheritedConfiguration = ArrayUtility::getValueByPath(
+                    $this->referenceConfiguration,
+                    $inheritancePath,
+                    '.'
+                );
+            } catch (\RuntimeException $exception) {
+                $inheritedConfiguration = null;
+            }
 
             if (
                 isset($inheritedConfiguration[self::INHERITANCE_OPERATOR])
@@ -240,27 +250,50 @@ class InheritancesResolverService
      */
     protected function throwExceptionIfCycleInheritances(string $path, string $pathToCheck)
     {
-        $configuration = static::getValueByPathHelper(
-            $this->referenceConfiguration,
-            $path
-        );
-
-        if (isset($configuration[self::INHERITANCE_OPERATOR])) {
-            $inheritances = static::getValueByPathHelper(
+        try {
+            $configuration = ArrayUtility::getValueByPath(
                 $this->referenceConfiguration,
-                $path . '.' . self::INHERITANCE_OPERATOR
+                $path,
+                '.'
             );
+        } catch (\RuntimeException $exception) {
+            $configuration = null;
+        }
+
+        if (isset($configuration[self::INHERITANCE_OPERATOR])) {
+            try {
+                $inheritances = ArrayUtility::getValueByPath(
+                    $this->referenceConfiguration,
+                    $path . '.' . self::INHERITANCE_OPERATOR,
+                    '.'
+                );
+            } catch (\RuntimeException $exception) {
+                $inheritances = null;
+            }
+
             if (is_array($inheritances)) {
                 foreach ($inheritances as $inheritancePath) {
-                    $configuration = static::getValueByPathHelper(
-                        $this->referenceConfiguration,
-                        $inheritancePath
-                    );
-                    if (isset($configuration[self::INHERITANCE_OPERATOR])) {
-                        $_inheritances = static::getValueByPathHelper(
+                    try {
+                        $configuration = ArrayUtility::getValueByPath(
                             $this->referenceConfiguration,
-                            $inheritancePath . '.' . self::INHERITANCE_OPERATOR
+                            $inheritancePath,
+                            '.'
                         );
+                    } catch (\RuntimeException $exception) {
+                        $configuration = null;
+                    }
+
+                    if (isset($configuration[self::INHERITANCE_OPERATOR])) {
+                        try {
+                            $_inheritances = ArrayUtility::getValueByPath(
+                                $this->referenceConfiguration,
+                                $inheritancePath . '.' . self::INHERITANCE_OPERATOR,
+                                '.'
+                            );
+                        } catch (\RuntimeException $exception) {
+                            $_inheritances = null;
+                        }
+
                         foreach ($_inheritances as $_inheritancePath) {
                             if (strpos($pathToCheck, $_inheritancePath) === 0) {
                                 throw new CycleInheritancesException(
@@ -372,20 +405,4 @@ class InheritancesResolverService
         reset($firstArray);
         return $firstArray;
     }
-
-    /**
-     * Helper to return a specified path.
-     *
-     * @param array &$array The array to traverse as a reference
-     * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz'
-     * @return mixed The value found, NULL if the path didn't exist
-     */
-    protected static function getValueByPathHelper(array $array, $path)
-    {
-        try {
-            return ArrayUtility::getValueByPath($array, $path, '.');
-        } catch (\RuntimeException $e) {
-            return null;
-        }
-    }
 }
index 0156a7f..f1d68f3 100644 (file)
@@ -265,10 +265,18 @@ class TranslationService implements SingletonInterface
             $defaultValue = $element->getLabel();
         } else {
             if ($element instanceof FormElementInterface) {
-                $defaultValue = ArrayUtility::getValueByPath($element->getProperties(), $property);
+                try {
+                    $defaultValue = ArrayUtility::getValueByPath($element->getProperties(), $property, '.');
+                } catch (\RuntimeException $exception) {
+                    $defaultValue = null;
+                }
             } else {
                 $propertyType = 'renderingOptions';
-                $defaultValue = ArrayUtility::getValueByPath($renderingOptions, $property);
+                try {
+                    $defaultValue = ArrayUtility::getValueByPath($renderingOptions, $property, '.');
+                } catch (\RuntimeException $exception) {
+                    $defaultValue = null;
+                }
             }
         }