Resolve relations

@param object $entity

@return void
175943
public function resolve($entity)
    {
        $entityClass = get_class($entity);
        $meta        = $this->getMeta($entityClass);
        $this->resolveRelations($entity, $meta);
    }
891495
public function save($entity)
    {
        $query = new Query($entity, false);
        $structure = $this->getEntityStructure($entity);

        if ($entity->_saved) {
            // Update
            $result = $query->update()->set($this->getEntityDataArray($entity))->where(array($structure->primaryColumn->name => $entity->_id))->apply();

            // Update relations
            RelationManager::with($entity)->saveRelations();

            return $result;
        } else {
            // Insert
            $id = $query->insert()->into($structure->tableName)->values($this->getEntityDataArray($entity))->apply();

            if ($id === false) {
                return false; // @codeCoverageIgnore
            }

            // Update relations
            RelationManager::with($entity)->saveRelations();

            // Save ID and state
            $entity->{$structure->primaryColumn->propertyName} = $id;
            $entity->_id = $id;
            $entity->_saved = true;

            return true;
        }
    }
925840
public function add($entity)
    {
        $idAccessorRegistry = $this->unitOfWork->getEntityRegistry()->getIdAccessorRegistry();
        $entityId           = $idAccessorRegistry->getEntityId($entity);

        $mapClass = $this->mapRepository->getEntityClass();

        if (empty($entityId)) {
            $this->entityRepository->add($entity);
            $map         = new $mapClass;
            $varJoinName = $this->relation->varJoinName();
            $this->mapRepository->add($map);
            $this->unitOfWork->getEntityRegistry()->registerAggregateRootCallback(
                $entity,
                $map,
                function ($root, $child) use ($varJoinName, $idAccessorRegistry) {
                    $entityId              = $idAccessorRegistry->getEntityId($root);
                    $child->{$varJoinName} = $entityId;
                    $this->map[]           = $entityId;
                }
            )
            ;

            return;
        }

        if (in_array($entityId, $this->map)) {
            throw new OrmException("Entity with id $entityId already exists");
        }

        $map                 = new $mapClass;
        $varJoinName         = $this->relation->varJoinName();
        $map->{$varJoinName} = $entityId;
        $this->mapRepository->add($map);
        $this->map[] = $entityId;
    }
349765
protected function resolveNestedRelations($data, $request)
    {
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $data[$key] = $this->resolveNestedRelations($value, $request);
            }
            elseif ($value instanceof static) {
                $data[$key] = $value->resolve($request);
            }
        }

        return $this->filter($data);
    }
769047
private function getClass($entity)
    {
        if (is_object($entity)) {
            return get_class($entity);
        }

        if (class_exists($entity)) {
            return $entity;
        }

        $realClassName = $this->classnameResolver->resolveFullQualifiedClassname($entity);

        return $realClassName;
    }
1018276
protected function assignRelationships($entity, $attributes)
    {
        $modelAttributes = $this->model->getAttributes($entity);

        // We'll filter through all of the columns, and check
        // to see if there are any defined relationships. If there
        // are, then we'll need to create those records as well.

        foreach ($modelAttributes as $columnName => $value) {
            if ($relationship = $this->findRelation($value)) {
                $entity[$columnName] = $this->fetchRelationId($relationship, $columnName, $attributes);
            }
        }

        return $entity;
    }
1136374
protected function eagerLoadRelations(array $entities)
    {
        if (empty($entities)) {
            return;
        }

        if ($this->class === null) {
            throw new LogicException('A class must be specified for Eager Loading using the `asClass` method.');
        }

        foreach ($this->with as $method) {
            $relation = $this->getRelation($entities[0], $method);
            $relation->addEagerConstraints($entities);
            $relationEntities = $relation->getEager();
            /** @var Model $entity */
            foreach ($entities as $entity) {
                $id = $entity->getId();
                $entity->setRelationEntities($method, isset($relationEntities[$id]) ? $relationEntities[$id] : null);
            }
        }
    }
286435
public function saveRelations()
    {
        foreach ($this->structure->relationProperties as $virtualProperty) {
            // Check for existing of the relation property
            if (! in_array($virtualProperty, $this->structure->relationProperties) || ! isset($this->structure->relations[$virtualProperty])) {
                throw new RelationException("Relation not defined!"); // @codeCoverageIgnore
            }

            // Get relation and verify
            $relation = $this->structure->relations[$virtualProperty]; /** @var Relation $relation */
            if (! $relation instanceof Relation) {
                throw new RelationException("Relation indexing failed, something is really wrong, please report! Fetch proprty no instance of relation!"); // @codeCoverageIgnore
            }

            // Property existing check
            if (($relation->join instanceof Join && ! isset($this->entity->{$relation->join->column})) ||
                ($relation->join instanceof JoinTable && ! isset($this->entity->{$relation->join->column->entityColumn}))) {
                if ($relation->join->optional) {
                    // Ignore this, the join is optional.
                    continue;
                }

                if ($relation->join instanceof Join) { // @codeCoverageIgnore
                    throw new \Exception("Property with column '".$relation->join->column."' is not set at entity '".get_class($this->entity)."' when trying to solve relationship fetching."); // @codeCoverageIgnore
                } // @codeCoverageIgnore
                if ($relation->join instanceof JoinTable) { // @codeCoverageIgnore
                    throw new \Exception("Property with column '".$relation->join->column->entityColumn."' is not set at entity '".get_class($this->entity)."' when trying to solve relationship fetching."); // @codeCoverageIgnore
                } // @codeCoverageIgnore
            }

            // Is the content changed?
            $value = $this->fetch($virtualProperty, true);
            if ($value === null) {
                // Nothing is changed, lets continue loop
                continue;
            }
            if (! $value instanceof ArrayCollection && ! $value instanceof Entity) {
                throw new RelationException("The value of the relation '".$virtualProperty."' should be an ArrayCollection or Entity!"); // @codeCoverageIgnore
            }

            // Make solver
            $solverName = join('', array_slice(explode("\\", get_class($relation)), -1));
            $class = "\\SweetORM\\Database\\Solver\\" . $solverName;

            $query = new Query($relation->targetEntity, false);

            /** @var Solver $solver */
            $solver = new $class($relation, $this->structure, $query);

            // Lets call the solver to solve this save relation problem
            $solver->solveSave($this->entity, $value);
        }
    }
1297247
protected function _resetrelationships($entity)
    {
        $entities = clone $entity->getRepository()->getSpace()->getEntities();

        //reset all the entities that have a belongs to or one to one relationship
        //with the $entity. Because since $entity is not being saved
        //nor should any child that requires the parent $entity value 
        foreach ($entities as $child) {
            if ($child->eql($entity)) {
                continue;
            }

            $relationships = $child->getEntityDescription()->getRelationships();

            foreach ($relationships as $relationship) {
                //child has a one to one or belongs to relationship to the entity (parent) 
                if ($relationship->isOneToOne() || $relationship->isManyToOne()) {
                    $value = $child->get($relationship->getName());

                    if ($entity->eql($value)) {
                        $child->reset();
                    }
                }
            }
        }
    }
1101753
public function commit($entity = null)
    {
        if ($this->evm->hasListeners(Events::preFlush)) {
            $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->sm));
        }

        //TODO: single/array entity commit handling
        $this->commitRemoved();
        $this->commitPersisted();

        //Force refresh of updated indexes
        if ($entity === true) {
            $client = $this->sm->getClient();
            foreach (array_unique($this->updatedIndexes) as $index) {
                $client->refreshIndex($index);
            }
        }

        $this->clear();

        if ($this->evm->hasListeners(Events::postFlush)) {
            $this->evm->dispatchEvent(Events::postFlush, new Event\PostFlushEventArgs($this->sm));
        }
    }
830684
public function getEntityProperties($entity)
    {
        $metadata = $this->em->getClassMetadata(get_class($entity));
        return array_merge($metadata->getFieldNames(), $metadata->getAssociationNames());
    }
879340
public function stashEntity($entity)
    {
        $className = $this->getClassName($entity);
        $entityId  = $this->getEntityId($entity);

        if (!isset($this->stashedEntities[$className])) {
            $this->stashedEntities[$className] = [];
        }

        $this->stashedEntities[$className][$entityId] = $entity;
    }
122261
private function resolveAndAddType(ObjectTypeInterface $type): void
    {
        $parentType = $type->getParent();
        $typeExtensions = [];

        foreach ($this->extensions as $extension) {
            /** @var ObjectExtensionInterface $extension */
            $typeExtensions = array_merge(
                $typeExtensions,
                $extension->getTypeExtensions('default'),
                $extension->getTypeExtensions($type->getClass())
            );
        }

        $parent = $parentType ? $this->getType($parentType) : null;
        $rType = $this->resolvedTypeFactory->createResolvedType($type, $typeExtensions, $parent);

        $this->types[$type->getClass()] = $rType;
    }
68738
public function addRelation($relation)
    {
        $relations = $this->getRelations();
        array_push($relations, $relation);
        $this->setRelations($relations);
    }
31457
public function setEntitiesAttribute($entities): void
    {
        static::saved(function ($model) use ($entities) {
            $this->entities()->delete();
            ! $entities || $this->entities()->createMany(array_map(function ($entity) {
                return ['entity_type' => $entity];
            }, $entities));
        });
    }
928754
private void setRelationToEntity(Object entity, Object relationEntity, Relation relation)
    {
        if (relation.getTargetEntity().isAssignableFrom(getEntity(relationEntity).getClass()))
        {

            if (relation.isUnary())
            {
                PropertyAccessorHelper.set(entity, relation.getProperty(), getEntity(relationEntity));
            }
            else
            {
                Object associationObject = PropertyAccessorHelper.getObject(entity, relation.getProperty());
                if (associationObject == null || ProxyHelper.isProxyOrCollection(associationObject))
                {
                    associationObject = PropertyAccessorHelper.getCollectionInstance(relation.getProperty());
                    PropertyAccessorHelper.set(entity, relation.getProperty(), associationObject);
                }

                ((Collection) associationObject).add(getEntity(relationEntity));
            }
        }
    }
979329
public function getRelations(&$query, $table)
    {
        $relations = [];
        $columns = [];
        /** @var Module $module */
        $module = $this->module;
        if (isset($module->tables[$table]['relations'])) {
            $relations = $module->tables[$table]['relations'];
        }
        foreach ($relations as $relation => $relationParams) {
            $query->join(
                $relationParams['type'],
                $relationParams['table'] . ' ' . $relationParams['alias'],
                $relationParams['on']
            );
            $columns[] = $relationParams['alias'] . '.' . $relationParams['representive_columns'] . ' ' . $relation;
        }

        return $columns;
    }