/** * Set a value in an entity * @param $parent * @param ResourceTransformer $resourceTransformer * @param PropertyResolver $propertyResolver * @param PropertySetter $propertySetter * @param EntityFactory $factory * @param Context $context * @throws InvalidPropertyException */ public function toEntity($parent, ResourceTransformer $resourceTransformer, PropertyResolver $propertyResolver, PropertySetter $propertySetter, EntityFactory $factory, Context $context) { $children = $this->getChildrenToProcess(); $childrenToAdd = []; $childrenToEdit = []; /** * Keep a list of all identifies we've touched, so we can removed those we haven't * @var PropertyValues[] $identifiersToKeep */ $identifiersToKeep = []; /** @var RelationshipField $field */ $field = $this->getField(); foreach ($children as $child) { if (!$child) { continue; } /** @var RESTResource $child */ /** @var bool $isNew */ $isNew = $child->isNew(); $childIdentifiers = $child->getProperties()->getIdentifiers(); $childEntity = null; if (!$isNew) { $childEntity = $this->getChildByIdentifiers($resourceTransformer, $propertyResolver, $parent, $childIdentifiers, $context); if ($childEntity) { $identifiersToKeep[] = $childIdentifiers; } } // Do we just link the resource? In this case we can't edit it right now. if ($field->canLinkExistingEntities()) { $entity = $factory->resolveLinkedEntity($parent, $child->getResourceDefinition()->getEntityClassName(), $childIdentifiers->toMap(), $context); if ($entity) { $childrenToAdd[] = $entity; $identifiersToKeep[] = $childIdentifiers; continue; } } // Is this a new child? We might not be able to add it... if (!$childEntity && !$field->canCreateNewChildren()) { throw new InvalidPropertyException("Only existing items can be linked to " . get_class($parent) . "->" . $field->getName()); } $entity = $resourceTransformer->toEntity($child, $child->getResourceDefinition(), $factory, $context, $childEntity); if (!isset($childEntity)) { $childrenToAdd[] = $entity; } else { $childrenToEdit[] = $entity; } } if (count($childrenToAdd) > 0) { $this->addChildren($resourceTransformer, $propertySetter, $parent, $this->getField(), $childrenToAdd, $context); } if (count($childrenToEdit) > 0) { $this->editChildren($resourceTransformer, $propertySetter, $parent, $this->getField(), $childrenToEdit, $context); } // Notify the setter to remove all children that haven't been touched (in the range defined in the context) $this->removeAllChildrenExcept($resourceTransformer, $propertyResolver, $propertySetter, $parent, $this->getField(), $identifiersToKeep, $context); }
/** * @param ResourceDefinition $resourceDefinition * @param $content * @param EntityFactoryContract $factory * @param ContextContract $context * @return mixed */ private function fromIdentifier(ResourceDefinition $resourceDefinition, $content, EntityFactoryContract $factory, ContextContract $context) { $resourceDefinition = ResourceDefinitionLibrary::make($resourceDefinition); return $factory->resolveFromIdentifier($resourceDefinition->getEntityClassName(), $content, $context); }