/**
  * {@inheritdoc}
  */
 public function mapFormsToData($forms, &$data)
 {
     $formsOtherThanQuantity = [];
     foreach ($forms as $key => $form) {
         if ('quantity' === $form->getName()) {
             $targetQuantity = $form->getData();
             $this->orderItemQuantityModifier->modify($data, $targetQuantity);
             continue;
         }
         $formsOtherThanQuantity[] = $form;
     }
     if (!empty($formsOtherThanQuantity)) {
         $this->propertyPathDataMapper->mapFormsToData($formsOtherThanQuantity, $data);
     }
 }
예제 #2
0
 /**
  * Binds data to the field, transforms and validates it.
  *
  * @param string|array $clientData The data
  *
  * @return Form The current form
  *
  * @throws UnexpectedTypeException
  */
 public function bind($clientData)
 {
     if ($this->readOnly) {
         $this->bound = true;
         return $this;
     }
     if (is_scalar($clientData) || null === $clientData) {
         $clientData = (string) $clientData;
     }
     // Initialize errors in the very beginning so that we don't lose any
     // errors added during listeners
     $this->errors = array();
     $event = new DataEvent($this, $clientData);
     $this->dispatcher->dispatch(FormEvents::PRE_BIND, $event);
     $appData = null;
     $normData = null;
     $extraData = array();
     $synchronized = false;
     // Hook to change content of the data bound by the browser
     $event = new FilterDataEvent($this, $clientData);
     $this->dispatcher->dispatch(FormEvents::BIND_CLIENT_DATA, $event);
     $clientData = $event->getData();
     if (count($this->children) > 0) {
         if (null === $clientData || '' === $clientData) {
             $clientData = array();
         }
         if (!is_array($clientData)) {
             throw new UnexpectedTypeException($clientData, 'array');
         }
         foreach ($this->children as $name => $child) {
             if (!isset($clientData[$name])) {
                 $clientData[$name] = null;
             }
         }
         foreach ($clientData as $name => $value) {
             if ($this->has($name)) {
                 $this->children[$name]->bind($value);
             } else {
                 $extraData[$name] = $value;
             }
         }
         // If we have a data mapper, use old client data and merge
         // data from the children into it later
         if ($this->dataMapper) {
             $clientData = $this->getClientData();
         }
     }
     if (null === $clientData || '' === $clientData) {
         $clientData = $this->emptyData;
         if ($clientData instanceof \Closure) {
             $clientData = $clientData($this);
         }
     }
     // Merge form data from children into existing client data
     if (count($this->children) > 0 && $this->dataMapper) {
         $this->dataMapper->mapFormsToData($this->children, $clientData);
     }
     try {
         // Normalize data to unified representation
         $normData = $this->clientToNorm($clientData);
         $synchronized = true;
     } catch (TransformationFailedException $e) {
     }
     if ($synchronized) {
         // Hook to change content of the data in the normalized
         // representation
         $event = new FilterDataEvent($this, $normData);
         $this->dispatcher->dispatch(FormEvents::BIND_NORM_DATA, $event);
         $normData = $event->getData();
         // Synchronize representations - must not change the content!
         $appData = $this->normToApp($normData);
         $clientData = $this->normToClient($normData);
     }
     $this->bound = true;
     $this->appData = $appData;
     $this->normData = $normData;
     $this->clientData = $clientData;
     $this->extraData = $extraData;
     $this->synchronized = $synchronized;
     $event = new DataEvent($this, $clientData);
     $this->dispatcher->dispatch(FormEvents::POST_BIND, $event);
     foreach ($this->validators as $validator) {
         $validator->validate($this);
     }
     return $this;
 }