Search the parent of a model in parented mode.

@param ModelInterface $model The model to search the parent of.

@return ModelInterface|null

@throws DcGeneralInvalidArgumentException When the model does not originate from the child provider.
506890
private function searchParentOfInParentedMode(ModelInterface $model)
    {
        if ($this->defaultProviderName !== $model->getProviderName()) {
            throw new DcGeneralInvalidArgumentException(
                'Model originates from ' . $model->getProviderName() .
                ' but is expected to be from ' . $this->defaultProviderName .
                ' can not determine parent.'
            );
        }

        $condition = $this->relationships->getChildCondition($this->parentProviderName, $this->defaultProviderName);
        // This is pretty expensive, we fetch all models from the parent provider here.
        // This can be much faster by using the inverse condition if present.
        foreach ($this->parentProvider->fetchAll($this->parentProvider->getEmptyConfig()) as $candidate) {
            if ($condition->matches($candidate, $model)) {
                return $candidate;
            }
        }

        return null;
    }
483149
protected function _changeParent(Model $model, $id = null, $parentId = null) {
		$parentField = $this->_getBehaviorConfig($model, 'parent');
		if (empty($id) || ($parentField === null)) {
			return false;
		}

		$model->recursive = -1;
		$treeItem = $model->read(null, $id);
		if (empty($treeItem)) {
			return false;
		}

		$treeItem[$model->alias][$parentField] = $parentId;
		$result = (bool)$model->save($treeItem);

		return $result;
	}
1010789
public function searchParentOfIn(ModelInterface $model, CollectionInterface $models)
    {
        // @codingStandardsIgnoreStart
        @\trigger_error(
            'Use \ContaoCommunityAlliance\DcGeneral\Controller\ModelCollector::searchParentOfIn().',
            E_USER_DEPRECATED
        );
        // @codingStandardsIgnoreEnd

        return $this->modelCollector->searchParentOfIn($model, $models);
    }
1075635
public function addModel(ModelInterface $model): ModelCollectionInterface
    {
        $this->propertyReflection->setValue($model, $this->foreignId);

        $this->models[$model->getId()] = $model;

        return $this;
    }
997232
private function generateToggleUrl(ModelInterface $model)
    {
        $toggleUrlEvent = new AddToUrlEvent(
            'ptg=' . $model->getId() . '&amp;provider=' . $model->getProviderName()
        );
        $this->getEnvironment()->getEventDispatcher()->dispatch(ContaoEvents::BACKEND_ADD_TO_URL, $toggleUrlEvent);

        return System::getContainer()->get('router')->generate(
            'cca_dc_general_tree_toggle',
            $this->getQueryParameterFromUrl($toggleUrlEvent->getUrl()),
            UrlGenerator::ABSOLUTE_URL
        );
    }
751723
public function model(Model $model)
    {
        // Check if the model is searchable before setting the query builder model
        $traits = class_uses_recursive(get_class($model));

        if (!isset($traits[Searchable::class])) {
            throw new InvalidArgumentException(get_class($model).' does not use the searchable trait');
        }

        $this->type($model->getDocumentType());

        if ($index = $model->getDocumentIndex()) {
            $this->index($index);
        }

        $this->model = $model;

        return $this;
    }
331712
protected function parseClassNames(ContainerInterface $container)
    {
        if ($container->hasDefinition(ExtendedDca::NAME)) {
            $definition = $container->getDefinition(ExtendedDca::NAME);

            if (!($definition instanceof ExtendedDca)) {
                throw new DcGeneralInvalidArgumentException(
                    \sprintf(
                        'Definition with name %s must be an instance of ExtendedDca but instance of %s encountered.',
                        ExtendedDca::NAME,
                        \get_class($definition)
                    )
                );
            }
        } else {
            $definition = new ExtendedDca();
            $container->setDefinition(ExtendedDca::NAME, $definition);
        }

        if (null === $this->getFromDca('dca_config')) {
            return;
        }

        if (null !== ($class = $this->getFromDca('dca_config/controller'))) {
            $definition->setControllerClass($class);
        }

        if (null !== ($class = $this->getFromDca('dca_config/view'))) {
            $definition->setViewClass($class);
        }
    }
887057
public function create(ModelInterface $model)
    {
        $user = $this->container->make(UserSingularity::class);

        $user
            ->setModel($model)
            ->boot();

        return $user;
    }
924454
public function getFlatModelErrors(ModelInterface $model)
    {
        $modelErrors = $this->getModelError($model);
        if (!$modelErrors) {
            return $modelErrors;
        }

        $errors = [[]];
        foreach ($this->getModelError($model) as $modelError) {
            $errors[] = $modelError;
        }

        return \array_merge(...$errors);
    }
515409
public function setParent(ModelInterface $childModel, ModelInterface $parentModel)
    {
        $condition = $this->relationships->getChildCondition(
            $parentModel->getProviderName(),
            $childModel->getProviderName()
        );
        if (!$condition instanceof ParentChildConditionInterface) {
            throw new DcGeneralRuntimeException(
                'No condition defined from ' . $parentModel->getProviderName() . ' to ' . $childModel->getProviderName()
            );
        }

        $condition->applyTo($parentModel, $childModel);
    }
974880
protected function parseParentChildConditions(ContainerInterface $container)
    {
        if ($container->hasDefinition(ModelRelationshipDefinitionInterface::NAME)) {
            $definition = $container->getDefinition(ModelRelationshipDefinitionInterface::NAME);
        } else {
            $definition = new DefaultModelRelationshipDefinition();
        }

        // If mode is 5, we need to define tree view.
        if (5 === $this->getFromDca('list/sorting/mode')) {
            $rootProvider = $this->getRootProviderName($container);

            if (null === ($relationship = $definition->getRootCondition())) {
                $relationship = new RootCondition();
                $relationship
                    ->setSourceName($rootProvider);
                $definition->setRootCondition($relationship);

                $builder = FilterBuilder::fromArrayForRoot()->getFilter();
            } else {
                $builder = FilterBuilder::fromArrayForRoot($relationship->getFilterArray())->getFilter();
            }

            $relationship
                ->setSetters(
                    \array_merge_recursive(
                        [['property' => 'pid', 'value' => '0']]
                    ),
                    $relationship->getSetters()
                );

            $builder->andPropertyEquals('pid', '0');

            $relationship
                ->setFilterArray($builder->getAllAsArray());

            if (null === ($relationship = $definition->getChildCondition($rootProvider, $rootProvider))) {
                $relationship = new ParentChildCondition();
                $relationship
                    ->setSourceName($rootProvider)
                    ->setDestinationName($rootProvider);
                $definition->addChildCondition($relationship);

                $builder = FilterBuilder::fromArray()->getFilter();
            } else {
                $builder = FilterBuilder::fromArray($relationship->getFilterArray())->getFilter();
            }

            $relationship
                ->setSetters(
                    \array_merge_recursive(
                        [['to_field' => 'pid', 'from_field' => 'id']]
                    ),
                    $relationship->getSetters()
                );

            $builder->andRemotePropertyEquals('pid', 'id');
            $relationship
                ->setFilterArray($builder->getAllAsArray());

            $container->setDefinition(ModelRelationshipDefinitionInterface::NAME, $definition);
        }

        // If ptable defined and no root setter we need to add (Contao default id=>pid mapping).
        if (null !== $this->getFromDca('config/ptable')) {
            $rootProvider = $this->getRootProviderName($container);

            if (null === ($relationship = $definition->getRootCondition())) {
                $relationship = new RootCondition();
                $relationship
                    ->setSourceName($rootProvider);

                $definition->setRootCondition($relationship);
            }

            if (!$relationship->getSetters()) {
                $relationship
                    ->setSetters(
                        \array_merge_recursive(
                            [['property' => 'pid', 'value' => '0']]
                        ),
                        $relationship->getSetters()
                    );
            }

            $container->setDefinition(ModelRelationshipDefinitionInterface::NAME, $definition);
        }
    }
1042983
public function getContext(ModelContextInterface $context = null)
    {
        $context = new ModelContextDatabase(parent::getContext());
        $context->setQuery($this->getObject('lib:database.query.select'));
        return $context;
    }
798740
private function isRootModel(ModelInterface $model)
    {
        return (null !== $this->rootCondition) && $this->rootCondition->matches($model);
    }
1362982
public static function findRelatedElement(Model $model, $type=null)
	{
		if($model->bootstrap_parentId == '' && $model->getType() != $model::TYPE_START) {
			return null;
		}

		$options = array(
			'order' => 'sorting'
		);

		if($type === null) {
			$column   = 'bootstrap_parentId';
			$values[] = $model->id;
		}
		else {
			$column   = array('bootstrap_parentId=? ', 'type=?');
			$values[] = $model->id;
			$values[] = $model->getTypeName($type);

		}

		return \ContentModel::findOneBy($column, $values, $options);
	}
663574
public function createTable(ModelInterface $model)
    {
        $i = 0;

        $model->setConnection($this->connection);

        $schemaManager = $this->connection->getSchemaManager();
        $builder = $this->getQueryBuilder();
        $tableName = TableNameResolver::getTableName($model->tableName());

        $columns = [];
        $indexes = [];

        foreach ($model->getMeta()->getFields() as $name => $field) {
            $field->setModel($model);

            if ($field instanceof ManyToManyField) {
                $field->setConnection($this->connection);

                /* @var $field \Mindy\Orm\Fields\ManyToManyField */
                if (null === $field->through) {
                    $fieldTableName = TableNameResolver::getTableName($field->getTableName());
                    if (false === $this->hasTable($fieldTableName)) {
                        $fieldTable = new Table(
                            $fieldTableName,
                            $field->getColumns()
                        );
                        $schemaManager->createTable($fieldTable);
                        $i += 1;
                    }
                }
            } else {
                $column = $field->getColumn();
                if (empty($column)) {
                    continue;
                }

                $columns[] = $column;
                $indexes = array_merge($indexes, $field->getSqlIndexes());
            }
        }

        if (false === $this->hasTable($tableName)) {
            $table = new Table($tableName, $columns, []);
            $table->setPrimaryKey($model->getPrimaryKeyName(true), 'primary');
            $schemaManager->createTable($table);

            $i += 1;
        }

        return $i;
    }
74244
public function findRootParentRecursively(string $parentProperty, string $table, Model $instance, bool $returnInstanceIfNoParent = true)
    {
        if (!$instance || !$instance->{$parentProperty}
            || null === ($parentInstance = $this->findModelInstanceByPk($table, $instance->{$parentProperty}))) {
            return $returnInstanceIfNoParent ? $instance : null;
        }

        return $this->findRootParentRecursively($parentProperty, $table, $parentInstance);
    }
864220
protected static function convertModelToFormRepresentation(
        ContainerInterface $container,
        ModelInterface $model
    ): ?array {
        /** @var JsonSchemasInterface $schemas */
        $schemas = $container->get(JsonSchemasInterface::class);
        /** @var SchemaInterface $schema */
        $schema = $schemas->getSchema($model);
        assert($schema instanceof SchemaInterface);

        $mappings = $schema::getMappings();

        $formData = [];
        if (array_key_exists(SchemaInterface::SCHEMA_ATTRIBUTES, $mappings) === true) {
            foreach ($mappings[SchemaInterface::SCHEMA_ATTRIBUTES] as $jsonAttrName => $modelAttrName) {
                $formData[$jsonAttrName] = $model->{$modelAttrName} ?? null;
            }
        }
        if (array_key_exists(SchemaInterface::SCHEMA_RELATIONSHIPS, $mappings) === true) {
            /** @var ModelSchemaInfoInterface $modelSchemeInfo */
            $modelSchemeInfo = $container->get(ModelSchemaInfoInterface::class);
            $modelClass      = get_class($model);
            foreach ($mappings[SchemaInterface::SCHEMA_RELATIONSHIPS] as $jsonRelName => $modelRelName) {
                $relationshipType = $modelSchemeInfo->getRelationshipType($modelClass, $modelRelName);
                if ($relationshipType === RelationshipTypes::BELONGS_TO) {
                    $fkName                 = $modelSchemeInfo->getForeignKey($modelClass, $modelRelName);
                    $formData[$jsonRelName] = $model->{$fkName} ?? null;
                }
            }
        }

        return $formData;
    }