/** * @param Page $page * @return Result * @throws PropertyMappingException */ protected function mapAndValidatePage(Page $page) : Result { $result = $this->objectManager->get(Result::class); $requestArguments = $this->request->getArguments(); $propertyPathsForWhichPropertyMappingShouldHappen = []; $registerPropertyPaths = function ($propertyPath) use(&$propertyPathsForWhichPropertyMappingShouldHappen) { $propertyPathParts = explode('.', $propertyPath); $accumulatedPropertyPathParts = []; foreach ($propertyPathParts as $propertyPathPart) { $accumulatedPropertyPathParts[] = $propertyPathPart; $temporaryPropertyPath = implode('.', $accumulatedPropertyPathParts); $propertyPathsForWhichPropertyMappingShouldHappen[$temporaryPropertyPath] = $temporaryPropertyPath; } }; foreach ($page->getElementsRecursively() as $element) { $value = ArrayUtility::getValueByPath($requestArguments, $element->getIdentifier()); $element->onSubmit($this, $value, $requestArguments); $this->formState->setFormValue($element->getIdentifier(), $value); $registerPropertyPaths($element->getIdentifier()); } // The more parts the path has, the more early it is processed usort($propertyPathsForWhichPropertyMappingShouldHappen, function ($a, $b) { return substr_count($b, '.') - substr_count($a, '.'); }); $processingRules = $this->formDefinition->getProcessingRules(); foreach ($propertyPathsForWhichPropertyMappingShouldHappen as $propertyPath) { if (isset($processingRules[$propertyPath])) { $processingRule = $processingRules[$propertyPath]; $value = $this->formState->getFormValue($propertyPath); try { $value = $processingRule->process($value); } catch (PropertyException $exception) { throw new PropertyMappingException('Failed to process FormValue at "' . $propertyPath . '" from "' . gettype($value) . '" to "' . $processingRule->getDataType() . '"', 1480024933, $exception); } $result->forProperty($propertyPath)->merge($processingRule->getProcessingMessages()); $this->formState->setFormValue($propertyPath, $value); } } return $result; }