Lemon\RestBundle\Object\Processor::processRelationships PHP Метод

processRelationships() публичный Метод

public processRelationships ( object $object, object | null $entity = null )
$object object
$entity object | null
    public function processRelationships($object, $entity = null)
    {
        $class = get_class($object);
        $em = $this->doctrine->getManagerForClass($class);
        $reflection = new \ReflectionClass($class);
        /** @var \Doctrine\Common\Persistence\Mapping\ClassMetadata $metadata */
        $metadata = $em->getMetadataFactory()->getMetadataFor($class);
        // Look for relationships, compare against preloaded entity
        foreach ($metadata->getAssociationNames() as $fieldName) {
            // This can happen for Doctrine's Mongo ODM because while it adheres to the interface it throws an exception :(
            try {
                $mappedBy = $metadata->getAssociationMappedByTargetField($fieldName);
            } catch (\BadMethodCallException $e) {
                $mappedBy = null;
                // Not defined by the interface, but both ORM & Mongo have it and we can use it to get what we want
                if (method_exists($metadata, 'getFieldMapping')) {
                    $mapping = $metadata->getFieldMapping($fieldName);
                    if (isset($mapping['association']) && !empty($mapping['mappedBy'])) {
                        $mappedBy = $mapping['mappedBy'];
                    }
                }
            }
            if (!$reflection->hasProperty($fieldName)) {
                continue;
            }
            $property = $reflection->getProperty($fieldName);
            $property->setAccessible(true);
            $value = $property->getValue($object);
            if (!$value) {
                continue;
            }
            if ($metadata->isCollectionValuedAssociation($fieldName)) {
                foreach ($value as $k => $v) {
                    // If the parent object is new, or if the relation has already been persisted
                    // set the mappedBy to the current object so that ids fill in properly
                    if ($this->isNew($object) && !empty($mappedBy)) {
                        $ref = new \ReflectionObject($v);
                        if ($ref->hasProperty($mappedBy)) {
                            $prop = $ref->getProperty($mappedBy);
                            $prop->setAccessible(true);
                            $prop->setValue($v, $object);
                            $this->processRelationships($v);
                        }
                    }
                    $vid = IdHelper::getId($v);
                    // If we have an object that already exists, merge it before we persist
                    if ($vid !== null && $this->isNew($object)) {
                        $value[$k] = $em->merge($v);
                    }
                }
                // Existing objects with collections may need to have missing values removed from them
                if (!$this->isNew($object) && $entity) {
                    $original = $property->getValue($entity);
                    foreach ($original as $v) {
                        $checkIfExists = function ($key, $element) use($v) {
                            return IdHelper::getId($v) == IdHelper::getId($element);
                        };
                        $exists = $value->exists($checkIfExists);
                        if ($value && $value != $object && !$exists) {
                            $em->remove($v);
                        }
                    }
                }
            } elseif ($metadata->isSingleValuedAssociation($fieldName)) {
                if ($this->isNew($object) && !$this->isNew($value)) {
                    $property->setValue($object, $em->merge($value));
                }
            }
        }
    }