Ejemplo n.º 1
0
 /**
  * Updates the form with default data.
  *
  * @param array $modelData The data formatted as expected for the underlying object
  *
  * @return Form The current form
  */
 public function setData($modelData)
 {
     if ($this->bound) {
         throw new AlreadyBoundException('You cannot change the data of a bound form');
     }
     // Don't allow modifications of the configured data if the data is locked
     if ($this->config->getDataLocked() && $modelData !== $this->config->getData()) {
         return $this;
     }
     if (is_object($modelData) && !$this->config->getByReference()) {
         $modelData = clone $modelData;
     }
     // Hook to change content of the data
     $event = new FormEvent($this, $modelData);
     $this->config->getEventDispatcher()->dispatch(FormEvents::PRE_SET_DATA, $event);
     // BC until 2.3
     $this->config->getEventDispatcher()->dispatch(FormEvents::SET_DATA, $event);
     $modelData = $event->getData();
     // Treat data as strings unless a value transformer exists
     if (!$this->config->getViewTransformers() && !$this->config->getModelTransformers() && is_scalar($modelData)) {
         $modelData = (string) $modelData;
     }
     // Synchronize representations - must not change the content!
     $normData = $this->modelToNorm($modelData);
     $viewData = $this->normToView($normData);
     // Validate if view data matches data class (unless empty)
     if (!FormUtil::isEmpty($viewData)) {
         $dataClass = $this->config->getDataClass();
         $actualType = is_object($viewData) ? 'an instance of class ' . get_class($viewData) : ' a(n) ' . gettype($viewData);
         if (null === $dataClass && is_object($viewData) && !$viewData instanceof \ArrayAccess) {
             $expectedType = 'scalar, array or an instance of \\ArrayAccess';
             throw new FormException('The form\'s view data is expected to be of type ' . $expectedType . ', ' . 'but is ' . $actualType . '. You ' . 'can avoid this error by setting the "data_class" option to ' . '"' . get_class($viewData) . '" or by adding a view transformer ' . 'that transforms ' . $actualType . ' to ' . $expectedType . '.');
         }
         if (null !== $dataClass && !$viewData instanceof $dataClass) {
             throw new FormException('The form\'s view data is expected to be an instance of class ' . $dataClass . ', but is ' . $actualType . '. You can avoid this error ' . 'by setting the "data_class" option to null or by adding a view ' . 'transformer that transforms ' . $actualType . ' to an instance of ' . $dataClass . '.');
         }
     }
     $this->modelData = $modelData;
     $this->normData = $normData;
     $this->viewData = $viewData;
     $this->synchronized = true;
     if ($this->config->getCompound()) {
         // Update child forms from the data
         $this->config->getDataMapper()->mapDataToForms($viewData, $this->children);
     }
     $event = new FormEvent($this, $modelData);
     $this->config->getEventDispatcher()->dispatch(FormEvents::POST_SET_DATA, $event);
     return $this;
 }
Ejemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 public function setData($modelData)
 {
     // If the form is submitted while disabled, it is set to submitted, but the data is not
     // changed. In such cases (i.e. when the form is not initialized yet) don't
     // abort this method.
     if ($this->submitted && $this->defaultDataSet) {
         throw new AlreadySubmittedException('You cannot change the data of a submitted form.');
     }
     // If the form inherits its parent's data, disallow data setting to
     // prevent merge conflicts
     if ($this->config->getInheritData()) {
         throw new RuntimeException('You cannot change the data of a form inheriting its parent data.');
     }
     // Don't allow modifications of the configured data if the data is locked
     if ($this->config->getDataLocked() && $modelData !== $this->config->getData()) {
         return $this;
     }
     if (is_object($modelData) && !$this->config->getByReference()) {
         $modelData = clone $modelData;
     }
     if ($this->lockSetData) {
         throw new RuntimeException('A cycle was detected. Listeners to the PRE_SET_DATA event must not call setData(). You should call setData() on the FormEvent object instead.');
     }
     $this->lockSetData = true;
     $dispatcher = $this->config->getEventDispatcher();
     // Hook to change content of the data
     if ($dispatcher->hasListeners(FormEvents::PRE_SET_DATA)) {
         $event = new FormEvent($this, $modelData);
         $dispatcher->dispatch(FormEvents::PRE_SET_DATA, $event);
         $modelData = $event->getData();
     }
     // Treat data as strings unless a value transformer exists
     if (!$this->config->getViewTransformers() && !$this->config->getModelTransformers() && is_scalar($modelData)) {
         $modelData = (string) $modelData;
     }
     // Synchronize representations - must not change the content!
     $normData = $this->modelToNorm($modelData);
     $viewData = $this->normToView($normData);
     // Validate if view data matches data class (unless empty)
     if (!FormUtil::isEmpty($viewData)) {
         $dataClass = $this->config->getDataClass();
         if (null !== $dataClass && !$viewData instanceof $dataClass) {
             $actualType = is_object($viewData) ? 'an instance of class ' . get_class($viewData) : 'a(n) ' . gettype($viewData);
             throw new LogicException('The form\'s view data is expected to be an instance of class ' . $dataClass . ', but is ' . $actualType . '. You can avoid this error ' . 'by setting the "data_class" option to null or by adding a view ' . 'transformer that transforms ' . $actualType . ' to an instance of ' . $dataClass . '.');
         }
     }
     $this->modelData = $modelData;
     $this->normData = $normData;
     $this->viewData = $viewData;
     $this->defaultDataSet = true;
     $this->lockSetData = false;
     // It is not necessary to invoke this method if the form doesn't have children,
     // even if the form is compound.
     if (count($this->children) > 0) {
         // Update child forms from the data
         $iterator = new InheritDataAwareIterator($this->children);
         $iterator = new \RecursiveIteratorIterator($iterator);
         $this->config->getDataMapper()->mapDataToForms($viewData, $iterator);
     }
     if ($dispatcher->hasListeners(FormEvents::POST_SET_DATA)) {
         $event = new FormEvent($this, $modelData);
         $dispatcher->dispatch(FormEvents::POST_SET_DATA, $event);
     }
     return $this;
 }
Ejemplo n.º 3
0
 /**
  * {@inheritdoc}
  */
 public function setData($modelData)
 {
     // If the form is bound while disabled, it is set to bound, but the data is not
     // changed. In such cases (i.e. when the form is not initialized yet) don't
     // abort this method.
     if ($this->bound && $this->initialized) {
         throw new AlreadyBoundException('You cannot change the data of a bound form');
     }
     // Don't allow modifications of the configured data if the data is locked
     if ($this->config->getDataLocked() && $modelData !== $this->config->getData()) {
         return $this;
     }
     if (is_object($modelData) && !$this->config->getByReference()) {
         $modelData = clone $modelData;
     }
     if ($this->lockSetData) {
         throw new Exception('A cycle was detected. Listeners to the PRE_SET_DATA event must not call setData(). You should call setData() on the FormEvent object instead.');
     }
     $this->lockSetData = true;
     $dispatcher = $this->config->getEventDispatcher();
     // Hook to change content of the data
     if ($dispatcher->hasListeners(FormEvents::PRE_SET_DATA) || $dispatcher->hasListeners(FormEvents::SET_DATA)) {
         $event = new FormEvent($this, $modelData);
         $dispatcher->dispatch(FormEvents::PRE_SET_DATA, $event);
         // BC until 2.3
         if ($dispatcher->hasListeners(FormEvents::SET_DATA)) {
             trigger_error('The FormEvents::SET_DATA event is deprecated since 2.1 and will be removed in 2.3. Use the FormEvents::PRE_SET_DATA event instead.', E_USER_DEPRECATED);
         }
         $dispatcher->dispatch(FormEvents::SET_DATA, $event);
         $modelData = $event->getData();
     }
     // Treat data as strings unless a value transformer exists
     if (!$this->config->getViewTransformers() && !$this->config->getModelTransformers() && is_scalar($modelData)) {
         $modelData = (string) $modelData;
     }
     // Synchronize representations - must not change the content!
     $normData = $this->modelToNorm($modelData);
     $viewData = $this->normToView($normData);
     // Validate if view data matches data class (unless empty)
     if (!FormUtil::isEmpty($viewData)) {
         $dataClass = $this->config->getDataClass();
         $actualType = is_object($viewData) ? 'an instance of class ' . get_class($viewData) : ' a(n) ' . gettype($viewData);
         if (null === $dataClass && is_object($viewData) && !$viewData instanceof \ArrayAccess) {
             $expectedType = 'scalar, array or an instance of \\ArrayAccess';
             throw new Exception('The form\'s view data is expected to be of type ' . $expectedType . ', ' . 'but is ' . $actualType . '. You ' . 'can avoid this error by setting the "data_class" option to ' . '"' . get_class($viewData) . '" or by adding a view transformer ' . 'that transforms ' . $actualType . ' to ' . $expectedType . '.');
         }
         if (null !== $dataClass && !$viewData instanceof $dataClass) {
             throw new Exception('The form\'s view data is expected to be an instance of class ' . $dataClass . ', but is ' . $actualType . '. You can avoid this error ' . 'by setting the "data_class" option to null or by adding a view ' . 'transformer that transforms ' . $actualType . ' to an instance of ' . $dataClass . '.');
         }
     }
     $this->modelData = $modelData;
     $this->normData = $normData;
     $this->viewData = $viewData;
     $this->initialized = true;
     $this->lockSetData = false;
     // It is not necessary to invoke this method if the form doesn't have children,
     // even if the form is compound.
     if (count($this->children) > 0) {
         // Update child forms from the data
         $this->config->getDataMapper()->mapDataToForms($viewData, $this->children);
     }
     if ($dispatcher->hasListeners(FormEvents::POST_SET_DATA)) {
         $event = new FormEvent($this, $modelData);
         $dispatcher->dispatch(FormEvents::POST_SET_DATA, $event);
     }
     return $this;
 }
Ejemplo n.º 4
0
 /**
  * Creates an unmodifiable copy of a given configuration.
  *
  * @param  FormConfigInterface $config The configuration to copy.
  */
 public function __construct(FormConfigInterface $config)
 {
     $dispatcher = $config->getEventDispatcher();
     if (!$dispatcher instanceof UnmodifiableEventDispatcher) {
         $dispatcher = new UnmodifiableEventDispatcher($dispatcher);
     }
     $this->dispatcher = $dispatcher;
     $this->name = $config->getName();
     $this->propertyPath = $config->getPropertyPath();
     $this->mapped = $config->getMapped();
     $this->byReference = $config->getByReference();
     $this->virtual = $config->getVirtual();
     $this->compound = $config->getCompound();
     $this->type = $config->getType();
     $this->viewTransformers = $config->getViewTransformers();
     $this->modelTransformers = $config->getModelTransformers();
     $this->dataMapper = $config->getDataMapper();
     $this->validators = $config->getValidators();
     $this->required = $config->getRequired();
     $this->disabled = $config->getDisabled();
     $this->errorBubbling = $config->getErrorBubbling();
     $this->emptyData = $config->getEmptyData();
     $this->attributes = $config->getAttributes();
     $this->data = $config->getData();
     $this->dataClass = $config->getDataClass();
     $this->dataLocked = $config->getDataLocked();
     $this->options = $config->getOptions();
 }