/** * @param object $object * @param string $fieldName * @param BaseControl $control * @param IClassMetadata $classMetadata * @throws \NForms\Exceptions\UnexpectedTypeException * @return bool */ public function save($object, $fieldName, BaseControl $control, IClassMetadata $classMetadata) { if ($control->isOmitted() || $control->isDisabled()) { return TRUE; } $value = $control->getValue(); if ($classMetadata->hasAssociation($fieldName) && $value !== NULL) { if ($classMetadata->isSingleValuedAssociation($fieldName)) { $value = $this->objectManager->find($classMetadata->getAssociationTargetClass($fieldName), $value); } else { if (!is_array($value) && (!$value instanceof \ArrayAccess || !$value instanceof \Iterator)) { throw new UnexpectedTypeException("In mapping association {$classMetadata->getClass()}::\${$fieldName} - expected array or ArrayAccess and Iterator instance, given " . get_class($value) . "."); } $collection = array(); foreach ($value as $id) { $collection[] = $this->objectManager->find($classMetadata->getAssociationTargetClass($fieldName), $id); } $value = $collection; } } if ($classMetadata->hasAssociation($fieldName)) { $classMetadata->setAssociationValue($object, $fieldName, $value); } else { if ($control instanceof Nette\Forms\Controls\TextBase && $value === '') { $value = NULL; } $classMetadata->setFieldValue($object, $fieldName, $value); } return TRUE; }
/** * @param object $object * @param ToManyContainer $container * @param IClassMetadata $metadata * @throws \NForms\Exceptions\InvalidStateException */ protected function saveToManyContainer($object, ToManyContainer $container, IClassMetadata $metadata) { $fieldName = $container->getOption(IObjectMapper::FIELD_NAME, $container->getName()); if (!$metadata->hasAssociation($fieldName)) { throw new InvalidStateException("Association '{$metadata->getClass()}#{$fieldName}' belonging to '{$container->getName()}' container not found."); } if ($metadata->isSingleValuedAssociation($fieldName)) { throw new InvalidStateException("It is not possible to save toMany container '{$container->getName()}' to toOne association '{$metadata->getClass()}#{$fieldName}''"); } $relatedMetadata = $metadata->getRelatedMetadata($fieldName); $collection = $metadata->getAssociationValue($object, $fieldName); // Collection objects id map $ids = array(); foreach ($collection as $key => $subObject) { $id = $relatedMetadata->hasId() ? $relatedMetadata->getId($subObject) : $key; if ($id !== NULL) { $ids[$id] = $subObject; } } // Create collection of new values $newCollection = array(); foreach ($container->getContainers() as $subContainer) { /** @var ToOneContainer $subContainer */ if (($id = $subContainer->getId()) === NULL) { if (($callback = $container->getOption(self::NEW_INSTANCE_FACTORY)) !== NULL) { $subObject = call_user_func($callback, $subContainer); } else { $subObject = $relatedMetadata->newInstance(); } } elseif (isset($ids[$id])) { $subObject = $ids[$id]; } else { throw new InvalidStateException("Object with id '{$id}' not found in collection in '{$metadata->getClass()}#{$fieldName}'."); } $this->save($subObject, $subContainer); $newCollection[] = $subObject; } $metadata->setAssociationValue($object, $fieldName, $newCollection); }