/** * Retrieve the instance of a widget for the given property. * * @param string $property Name of the property for which the widget shall be retrieved. * * @param PropertyValueBag $valueBag The input values to use (optional). * * @return \Widget * * @throws DcGeneralRuntimeException When No widget could be build. * @throws DcGeneralInvalidArgumentException When property is not defined in the property definitions. */ public function getWidget($property, PropertyValueBag $valueBag = null) { $environment = $this->getEnvironment(); $dispatcher = $environment->getEventDispatcher(); $propertyDefinitions = $environment->getDataDefinition()->getPropertiesDefinition(); if (!$propertyDefinitions->hasProperty($property)) { throw new DcGeneralInvalidArgumentException('Property ' . $property . ' is not defined in propertyDefinitions.'); } $model = clone $this->model; $model->setId($this->model->getId()); if ($valueBag) { $values = new PropertyValueBag($valueBag->getArrayCopy()); $this->environment->getController()->updateModelFromPropertyBag($model, $values); } $propertyDefinition = $propertyDefinitions->getProperty($property); $event = new BuildWidgetEvent($environment, $model, $propertyDefinition); $dispatcher->dispatch(DcGeneralFrontendEvents::BUILD_WIDGET, $event); if (!$event->getWidget()) { throw new DcGeneralRuntimeException(sprintf('Widget was not build for property %s::%s.', $this->model->getProviderName(), $property)); } return $event->getWidget(); }
/** * {@inheritDoc} * * @SuppressWarnings(PHPMD.Superglobals) * @SuppressWarnings(PHPMD.CamelCaseVariableName) */ public function processInput(PropertyValueBag $propertyValues) { // @codingStandardsIgnoreStart - Remember current POST data and clear it. $post = $_POST; $_POST = array(); // @codingStandardsIgnoreEnd \Input::resetCache(); // Set all POST data, these get used within the Widget::validate() method. foreach ($propertyValues as $property => $propertyValue) { $_POST[$property] = $propertyValue; } // Now get and validate the widgets. foreach (array_keys($propertyValues->getArrayCopy()) as $property) { // NOTE: the passed input values are RAW DATA from the input provider - aka widget known values and not // native data as in the model. // Therefore we do not need to decode them but MUST encode them. $widget = $this->getWidget($property, $propertyValues); $widget->validate(); if ($widget->hasErrors()) { foreach ($widget->getErrors() as $error) { $propertyValues->markPropertyValueAsInvalid($property, $error); } } elseif ($widget->submitInput()) { try { $propertyValues->setPropertyValue($property, $this->encodeValue($property, $widget->value, $propertyValues)); } catch (\Exception $e) { $widget->addError($e->getMessage()); foreach ($widget->getErrors() as $error) { $propertyValues->markPropertyValueAsInvalid($property, $error); } } } } // FIXME: Add new event "CheckUpdatedPropertyValueBagEvent". $_POST = $post; \Input::resetCache(); }
/** * {@inheritDoc} */ public function processInput(PropertyValueBag $propertyValues) { foreach (array_keys($propertyValues->getArrayCopy()) as $property) { $widget = $this->getWidget($property, $propertyValues); // NOTE: the passed input values are RAW DATA from the input provider - aka widget known values and not // native data as in the model. // Therefore we do not need to decode them but MUST encode them. $widget->value = $propertyValues->getPropertyValue($property); // TODO: we need to either override the POST data so \Widget::validate() get's it or call the (protected) // \Widget::validator($value) on our own. $widget->validate(); if ($widget->hasErrors()) { foreach ($widget->getErrors() as $error) { $propertyValues->markPropertyValueAsInvalid($property, $error); } } else { try { $propertyValues->setPropertyValue($property, $this->encodeValue($property, $widget->value)); } catch (\Exception $e) { $widget->addError($e->getMessage()); $propertyValues->markPropertyValueAsInvalid($property, $e->getMessage()); } } } }