/**
  * 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());
             }
         }
     }
 }