Check if the given object has a changed parent recursively

@param SluggableAdapter $ea
@param object           $object
@param string           $getter

@return bool
326245
private function hasChangedParent(SluggableAdapter $ea, $object, $getter)
    {
        $relation = $object->$getter();

        if (!$relation) {
            return false;
        }

        $changeSet = $ea->getObjectChangeSet($this->om->getUnitOfWork(), $relation);
        if (isset($changeSet[$this->usedOptions['relationField']])) {
            return true;
        }

        return $this->hasChangedParent($ea, $relation, $getter);
    }
667215
public static function validate($object, ExecutionContextInterface $context)
    {
        if (!method_exists($object, 'getParent')) {
            return;
        }

        $tempObject = $object->getParent();

        while ($tempObject !== null) {
            if ($tempObject === $object) {
                $context->buildViolation(
                    'Circular reference error. '
                    . 'An object can not reference with a parent to itself nor to an ancestor of itself'
                )
                    ->atPath('parent')
                    ->addViolation();

                break;
            }

            $tempObject = $tempObject->getParent();
        }
    }
759095
private function hasRelationGetter($getter, $onlyCheck = true)
    {
        if (strncmp('get', $getter, 3) === 0) {
            $name = substr($getter, 3);
            if ($this->hasRelation($name)) {
                if ($onlyCheck) {
                    return true;
                }

                return $this->getRelation($name)->get();
            }
        }

        return false;
    }
724393
def _parent_changed(self, parent):
        
        from .index_operations import ParameterIndexOperationsView
        #if getattr(self, "_in_init_"):
            #import ipdb;ipdb.set_trace()
            #self.constraints.update(param.constraints, start)
            #self.priors.update(param.priors, start)
        offset = parent._offset_for(self)
        for name, iop in list(self._index_operations.items()):
            self.remove_index_operation(name)
            self.add_index_operation(name, ParameterIndexOperationsView(parent._index_operations[name], offset, self.size))
        self._fixes_ = None
        for p in self.parameters:
            p._parent_changed(parent)
941342
public function isHasOneRelation(DataObject $object, $name)
    {
        return (
            $this->getSchema()->hasOneComponent($object, $name) ||
            $this->getSchema()->hasOneComponent($object, $this->trimID($name))
        );
    }
627416
public function getEntitiesWithCustomFields(
        $object,
        $args,
        $resultsCallback = null
    ) {
        // Run core method if we are not dealing with a lead.
        if ('lead' !== $object) {
            return parent::getEntitiesWithCustomFields($object, $args, $resultsCallback);
        }

        list($fields, $fixedFields) = $this->getCustomFieldList($object);

        //Fix arguments if necessary
        $args = $this->convertOrmProperties($this->getClassName(), $args);

        //DBAL
        /** @var QueryBuilder $dq */
        $dq = isset($args['qb']) ? $args['qb'] : $this->getEntitiesDbalQueryBuilder();

        // Generate where clause first to know if we need to use distinct on primary ID or not
        $this->useDistinctCount = false;

        // Alteration to core start.
        // Check to see if $args has any extendedFields.
        $extendedFieldList = [];
        foreach ($fields as $k => $field) {
            if (in_array($field['object'], ['extendedField', 'extendedFieldSecure'])) {
                $extendedFieldList[$k] = $field;
            }
        }
        $extendedFieldFilters = !empty($this->ExtendedFieldFilters) ? $this->ExtendedFieldFilters : $this->getExtendedFieldFilters(
            $args,
            $extendedFieldList
        );
        if (!empty($extendedFieldFilters)) {
            $this->ExtendedBuildWhereClause($dq, $args, $extendedFieldFilters);
        } else {
            $this->buildWhereClause($dq, $args);
        }
        // Alteration to core end.

        // Distinct is required here to get the correct count when group by is used due to applied filters
        $countSelect = ($this->useDistinctCount) ? 'COUNT(DISTINCT('.$this->getTableAlias(
            ).'.id))' : 'COUNT('.$this->getTableAlias().'.id)';
        $dq->select($countSelect.' as count');

        // Advanced search filters may have set a group by and if so, let's remove it for the count.
        if ($groupBy = $dq->getQueryPart('groupBy')) {
            $dq->resetQueryPart('groupBy');
        }

        $total   = 0;
        $results = [];
        if (isset($args['withTotalCount']) && $args['withTotalCount']) {
            //get a total count
            $result = $dq->execute()->fetchAll();
            $total  = ($result) ? $result[0]['count'] : $total;
            if (!$total) {
                return [
                    'count'   => $total,
                    'results' => $results,
                ];
            }
        }

        if ($total || !(isset($args['withTotalCount']) && $args['withTotalCount'])) {
            if ($groupBy) {
                $dq->groupBy($groupBy);
            }
            //now get the actual paginated results

            $this->buildOrderByClause($dq, $args);
            $this->buildLimiterClauses($dq, $args);

            $dq->resetQueryPart('select');
            $this->buildSelectClause($dq, $args);

            $results = $dq->execute()->fetchAll();

            //loop over results to put fields in something that can be assigned to the entities
            $fieldValues = [];
            $groups      = $this->getFieldGroups();

            // Alteration to core start.
            $lead_ids            = array_map('reset', $results);
            $extendedFieldValues = $this->getExtendedFieldValuesMultiple(
                $extendedFieldList,
                $lead_ids
            );
            // Alteration to core end.

            foreach ($results as $result) {
                $id = $result['id'];
                //unset all the columns that are not fields
                $this->removeNonFieldColumns($result, $fixedFields);

                foreach ($result as $k => $r) {
                    if (isset($fields[$k])) {
                        $fieldValues[$id][$fields[$k]['group']][$fields[$k]['alias']]          = $fields[$k];
                        $fieldValues[$id][$fields[$k]['group']][$fields[$k]['alias']]['value'] = $r;
                    }
                }

                // Alteration to core start.
                // Add the extended field to result if the current lead has that field value
                foreach ($extendedFieldList as $fieldToAdd => $e_config) {
                    $e_value                                                                                 = isset($extendedFieldValues[$id][$fieldToAdd]) ? $extendedFieldValues[$id][$fieldToAdd] : null;
                    $fieldValues[$id][$fields[$fieldToAdd]['group']][$fields[$fieldToAdd]['alias']]          = $fields[$fieldToAdd];
                    $fieldValues[$id][$fields[$fieldToAdd]['group']][$fields[$fieldToAdd]['alias']]['value'] = $e_value;
                }
                // Alteration to core end.

                //make sure each group key is present
                foreach ($groups as $g) {
                    if (!isset($fieldValues[$id][$g])) {
                        $fieldValues[$id][$g] = [];
                    }
                }
            }

            unset($results, $fields);

            //get an array of IDs for ORM query
            $ids = array_keys($fieldValues);

            if (count($ids)) {
                //ORM

                //build the order by id since the order was applied above
                //unfortunately, doctrine does not have a way to natively support this and can't use MySQL's FIELD function
                //since we have to be cross-platform; it's way ugly

                //We should probably totally ditch orm for leads
                $order = '(CASE';
                foreach ($ids as $count => $id) {
                    $order .= ' WHEN '.$this->getTableAlias().'.id = '.$id.' THEN '.$count;
                    ++$count;
                }
                $order .= ' ELSE '.$count.' END) AS HIDDEN ORD';

                //ORM - generates lead entities
                /** @var \Doctrine\ORM\QueryBuilder $q */
                $q = $this->getEntitiesOrmQueryBuilder($order);
                $this->buildSelectClause($dq, $args);

                //only pull the leads as filtered via DBAL
                $q->where(
                    $q->expr()->in($this->getTableAlias().'.id', ':entityIds')
                )->setParameter('entityIds', $ids);

                $q->orderBy('ORD', 'ASC');

                $results = $q->getQuery()
                    ->getResult();

                //assign fields
                /** @var Lead $r */
                foreach ($results as $r) {
                    $id = $r->getId();
                    $r->setFields($fieldValues[$id]);

                    if (is_callable($resultsCallback)) {
                        $resultsCallback($r);
                    }
                }
            } else {
                $results = [];
            }
        }

        return (isset($args['withTotalCount']) && $args['withTotalCount']) ?
            [
                'count'   => $total,
                'results' => $results,
            ] : $results;
    }
163157
protected function persistChangedSlug(IHierarchicObject $object, $newSlug)
    {

        $affectedDriver = $this
            ->getMetadata()
            ->getCollectionDataSource()
            ->getMasterServer()
            ->getConnection();

        $this
            ->getObjectPersister()
            ->executeTransaction(
                function () use ($object, $newSlug) {

                    $this->checkIfChangeSlugPossible($object, $this, $newSlug);
                    $this
                        ->buildUpdateUrlQuery($object, $this, $newSlug)
                        ->execute();

                },
                [$affectedDriver]
            );
    }
1340509
public function popAncestor($ancestor)
    {
        $this->ancestor = $this->ancestor->reject(function ($item) use ($ancestor) {
            if (is_object($item) && is_string($ancestor)) {
                return get_class($item) === $ancestor;
            }

            if (is_string($item) && is_object($ancestor)) {
                return $item === get_class($ancestor);
            }

            return get_class($item) === get_class($ancestor);
        });

        return $this;
    }
414581
private static function builderMatchesChange(Change $change, Builder $builder)
    {
        $class = $change->model;
        $route_key_name = (new $class)->getRouteKeyName();
        return collect($builder->getQuery()->wheres)
            ->contains(function($where) use ($change, $route_key_name) {

                // If the builder is keyed to a simple "id" in the route, return
                // whether the Change matches it.
                if ($route_key_name == 'id') {
                    return $where['column'] == $route_key_name
                        && $where['operator'] == '='
                        && $where['value'] == $change->key;

                // Otherwise compare against model logged by the change. The
                // scope needs to be removed to prevent recursion.
                } else {
                    $value = $change->changedModel()
                        ->withoutGlobalScope(static::$LOGGABLE_SCOPE)
                        ->first()
                        ->$route_key_name;
                    return $where['column'] == $route_key_name
                        && $where['operator'] == '='
                        && $where['value'] == $value;
                }
        });
    }
1135818
public static void removeDeepPropertyChangeListener(
        Object object, PropertyChangeListener propertyChangeListener)
    {
        Objects.requireNonNull(object, "The object may not be null");
        Objects.requireNonNull(propertyChangeListener, 
            "The propertyChangeListener may not be null");
        removeRecursive(object, propertyChangeListener);
    }
1077907
public function hasRelationshipInput(
        ResourceTransformer $transformer,
        &$input,
        RelationshipField $field,
        Context $context
    ) : bool {
        return $this->hasPropertyInput($transformer, $input, $field, $context);
    }
1210965
public function prepareUpdateChangeSet($object, ChangeSet $changeSet) : array
    {
        if (! $object instanceof PersistableInterface) {
            throw new InvalidArgumentException(sprintf('%s must implement PersistableInterface.', get_class($object)));
        }

        return $object->prepareUpdateChangeSet($changeSet);
    }
1256547
public function getObjectChangeSet($uow, $object)
    {
        $changeSet = parent::getObjectChangeSet($uow, $object);
        $meta = $this->getObjectManager()->getClassMetadata(get_class($object));
        $refl = $meta->getReflectionClass();
        $updates = $uow->getScheduledCollectionUpdates();
        $delitions = $uow->getScheduledCollectionDeletions();
        foreach ($meta->getAssociationNames() as $name) {
            if ($meta->isSingleValuedAssociation($name)) {
                continue;
            }

            $property = $refl->getProperty($name);
            $property->setAccessible(true);
            $assoc = $property->getValue($object);
            if (in_array($assoc, $updates, true) || in_array($assoc, $delitions, true)) {
                $changeSet[$name] = [$assoc, $assoc];
            }
        }

        return $changeSet;
    }
632612
protected function checkPermissions(TreeInterface $object)
    {
        if (!$this->permissionsIgnored) {
            $home = $object->getSiteTreeObject()->getSiteHomePageObject();
            if ($home) {
                $cp = new Checker($home);

                return $cp->canViewPageInSitemap();
            }
        }

        return true;
    }
259051
private function saveFieldsRecursive(\stdClass $params, ApiInterface $entity, $isCreating, TransactionInterface $transaction) {
        if(!$isCreating) {
            $this->getAcl()->canWrite($entity);
        }

        $isChanged = false;
        $entity->setTransaction($transaction);
        $parents = $this->filterParents($params, $entity);
        $fields = $this->filterFields($params, $entity, $isCreating);


        $this->writeFields($fields, $entity, false);
        $this->writeCustomParents($fields, $entity);
        //Then Update the parents
        /** @var ApiInterface[] $parentEntities */
        $parentEntities = array();
        foreach($parents as $relationship => $subParams) {
            /** @var ApiInterface $parentEntity */
            $parentEntity = $entity->getRelated($relationship);
            if($parentEntity === false) {
                $relation = $entity->getRelationship($relationship);
                $referencedModel = $relation->getReferencedModel();
                $parentEntity = new $referencedModel();
                $subIsCreating = true;
            } else {
                $subIsCreating = false;
            }
            $parentEntities[$relationship] = $parentEntity;
            $parentIsChanged = $this->saveFieldsRecursive($subParams, $parentEntity, $subIsCreating, $transaction);
            if($parentIsChanged) {
                $isChanged = true;
            }
        }
        //Then Check if we want to load from defaults (if creating the specific object)
        if($isCreating) {
            $requiredRelationships = $entity->getDefaultRelationships();
            foreach($requiredRelationships as $alias) {
                //If the entity isn't currently set, set it from the parents
                if($entity->getRelated($alias) === false) {
                    if(!array_key_exists($alias, $parentEntities)) {
                        $message = 'The Required Parent of \'' . $alias . '\' was not found.';
                        $relationship = $entity->getRelationship($alias);
                        $message .= ' Please either create a new \'' . $alias . '\' or set the field \'' . $relationship->getFields() . '\'';
                        throw new Exception($message, 400);
                    }
                    $entity->setRelated($alias, $parentEntities[$alias]);
                }
            }
            $entity->loadDefaults();
        }
        //Then, if loaded from defaults update the fields and other related parents again, to make sure the defaults didn't overwrite them
        foreach($parentEntities as $relationship => $parent) {
            $entity->setRelated($relationship, $parent);
        }
        if($this->writeFields($fields, $entity, true)) {
            $isChanged = true;
        }

        if($isCreating) {
            $entity->fireEventCancel(UploadBase::EVENT_UPLOAD_FILE_CREATE);
            $entity->fireEvent(self::EVENT_DATA_PROPAGATION_CREATE);
        } else {
            $entity->fireEventCancel(UploadBase::EVENT_UPLOAD_FILE_UPDATE);
            $entity->fireEvent(self::EVENT_DATA_PROPAGATION_UPDATE);
        }
        if($isCreating || sizeOf($entity->getChangedFields()) > 0) {
            $isChanged = true;
            $entity->save();
        }
        if($isCreating) {
            //Add the acl in after the save so that the validation can be performed, in case you are looking at a parent, and the parent value is set incorrectly.  This will rollback the transaction anyways
            $this->getAcl()->canWrite($entity);
        }
        $entity->fireEvent(self::EVENT_DATA_FINAL_CLEANUP);
        return $isChanged;
    }
350881
protected function insertParents($entity, array $path, array $parents)
    {
        $propertyName = reset($path);
        $propertyValue = Core::get()->getObjectService()->getObjectProperty($entity, $propertyName);

        if (1 === count($path)) {
            if (is_object($propertyValue)
                && Core::get()->getParentsUtility()->classUsesParentsTrait($propertyValue)
            ) {
                /** @var ParentsTrait $propertyValue */
                $propertyValue->attachParents($this->filterParents($parents));
            }
        } else {
            if (is_object($propertyValue)) {
                $parents[] = $propertyValue;
            }

            array_shift($path);
            $this->insertParents($propertyValue, $path, $parents);
        }
    }
143281
public function isTracked(EntityManagerInterface $em, $entity)
    {
        $class       = get_class($entity);
        $annotations = $this->reader->getClassAnnotations($em->getClassMetadata($class)->getReflectionClass());

        foreach ($annotations as $annotation) {
            if ($annotation instanceof Tracked) {
                return true;
            }
        }

        return false;
    }