master

laravel/framework

Last updated at: 29/12/2023 09:22

MorphOneOrMany.php

TLDR

The provided file is MorphOneOrMany.php and it is a part of the Illuminate\Database\Eloquent\Relations namespace in the Demo Projects project. It defines the MorphOneOrMany class, which is an abstract class extending the HasOneOrMany class. The class provides methods for creating morph one or many relationships in the Laravel Eloquent ORM.

Methods

__construct(Builder $query, Model $parent, $type, $id, $localKey)

This method is the constructor of the MorphOneOrMany class. It initializes the properties $morphType and $morphClass, and calls the parent constructor from HasOneOrMany class.

addConstraints()

This method sets the base constraints on the relation query. If the static::$constraints property is true, it adds a WHERE clause to the relation query to filter the results based on the $morphType and $morphClass.

addEagerConstraints(array $models)

This method sets the constraints for an eager load of the relation. It calls the parent's addEagerConstraints method and adds a WHERE clause to the relation query to filter the results based on the $morphType and $morphClass.

forceCreate(array $attributes = [])

This method creates a new instance of the related model with mass-assignment. It sets the foreign key and morph type attributes based on the parent key and morph class, and then calls the forceCreate method on the related model.

setForeignAttributesForCreate(Model $model)

This method sets the foreign key and morph type attributes on a related model for creating a new instance. It sets the $morphType and $morphClass properties of the model.

getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])

This method returns the relationship query for checking the existence of a related model. It calls the parent's getRelationExistenceQuery method and adds a WHERE clause to the query to filter the results based on the relationship's $morphType and $morphClass.

getQualifiedMorphType()

This method returns the qualified foreign key "type" name.

getMorphType()

This method returns the plain morph type name without the table.

getMorphClass()

This method returns the class name of the parent model.

<?php

namespace Illuminate\Database\Eloquent\Relations;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

abstract class MorphOneOrMany extends HasOneOrMany
{
    /**
     * The foreign key type for the relationship.
     *
     * @var string
     */
    protected $morphType;

    /**
     * The class name of the parent model.
     *
     * @var string
     */
    protected $morphClass;

    /**
     * Create a new morph one or many relationship instance.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  \Illuminate\Database\Eloquent\Model  $parent
     * @param  string  $type
     * @param  string  $id
     * @param  string  $localKey
     * @return void
     */
    public function __construct(Builder $query, Model $parent, $type, $id, $localKey)
    {
        $this->morphType = $type;

        $this->morphClass = $parent->getMorphClass();

        parent::__construct($query, $parent, $id, $localKey);
    }

    /**
     * Set the base constraints on the relation query.
     *
     * @return void
     */
    public function addConstraints()
    {
        if (static::$constraints) {
            $this->getRelationQuery()->where($this->morphType, $this->morphClass);

            parent::addConstraints();
        }
    }

    /**
     * Set the constraints for an eager load of the relation.
     *
     * @param  array  $models
     * @return void
     */
    public function addEagerConstraints(array $models)
    {
        parent::addEagerConstraints($models);

        $this->getRelationQuery()->where($this->morphType, $this->morphClass);
    }

    /**
     * Create a new instance of the related model. Allow mass-assignment.
     *
     * @param  array  $attributes
     * @return \Illuminate\Database\Eloquent\Model
     */
    public function forceCreate(array $attributes = [])
    {
        $attributes[$this->getForeignKeyName()] = $this->getParentKey();
        $attributes[$this->getMorphType()] = $this->morphClass;

        return $this->related->forceCreate($attributes);
    }

    /**
     * Set the foreign ID and type for creating a related model.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    protected function setForeignAttributesForCreate(Model $model)
    {
        $model->{$this->getForeignKeyName()} = $this->getParentKey();

        $model->{$this->getMorphType()} = $this->morphClass;
    }

    /**
     * Get the relationship query.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @param  \Illuminate\Database\Eloquent\Builder  $parentQuery
     * @param  array|mixed  $columns
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
    {
        return parent::getRelationExistenceQuery($query, $parentQuery, $columns)->where(
            $query->qualifyColumn($this->getMorphType()), $this->morphClass
        );
    }

    /**
     * Get the foreign key "type" name.
     *
     * @return string
     */
    public function getQualifiedMorphType()
    {
        return $this->morphType;
    }

    /**
     * Get the plain morph type name without the table.
     *
     * @return string
     */
    public function getMorphType()
    {
        return last(explode('.', $this->morphType));
    }

    /**
     * Get the class name of the parent model.
     *
     * @return string
     */
    public function getMorphClass()
    {
        return $this->morphClass;
    }
}