Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
staudenmeir committed Dec 4, 2021
1 parent aa1f265 commit 3776bcf
Show file tree
Hide file tree
Showing 4 changed files with 384 additions and 338 deletions.
329 changes: 329 additions & 0 deletions src/Eloquent/HasOfDescendantsRelationships.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
<?php

namespace Staudenmeir\LaravelAdjacencyList\Eloquent;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\BelongsToManyOfDescendants;
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\HasManyOfDescendants;
use Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\MorphToManyOfDescendants;

trait HasOfDescendantsRelationships
{
/**
* Define a one-to-many relationship of the model's descendants.
*
* @param string $related
* @param string|null $foreignKey
* @param string|null $localKey
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\HasManyOfDescendants
*/
public function hasManyOfDescendants($related, $foreignKey = null, $localKey = null)
{
$instance = $this->newRelatedInstance($related);

$foreignKey = $foreignKey ?: $this->getForeignKey();

$localKey = $localKey ?: $this->getKeyName();

return $this->newHasManyOfDescendants(
$instance->newQuery(),
$this,
$instance->qualifyColumn($foreignKey),
$localKey,
false
);
}

/**
* Define a one-to-many relationship of the model's descendants and itself.
*
* @param string $related
* @param string|null $foreignKey
* @param string|null $localKey
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\HasManyOfDescendants
*/
public function hasManyOfDescendantsAndSelf($related, $foreignKey = null, $localKey = null)
{
$instance = $this->newRelatedInstance($related);

$foreignKey = $foreignKey ?: $this->getForeignKey();

$localKey = $localKey ?: $this->getKeyName();

return $this->newHasManyOfDescendants(
$instance->newQuery(),
$this,
$instance->qualifyColumn($foreignKey),
$localKey,
true
);
}

/**
* Instantiate a new HasManyOfDescendants relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $foreignKey
* @param string $localKey
* @param bool $andSelf
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\HasManyOfDescendants
*/
protected function newHasManyOfDescendants(Builder $query, Model $parent, $foreignKey, $localKey, $andSelf)
{
return new HasManyOfDescendants($query, $parent, $foreignKey, $localKey, $andSelf);
}

/**
* Define a many-to-many relationship of the model's descendants.
*
* @param string $related
* @param string|null $table
* @param string|null $foreignPivotKey
* @param string|null $relatedPivotKey
* @param string|null $parentKey
* @param string|null $relatedKey
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\BelongsToManyOfDescendants
*/
public function belongsToManyOfDescendants(
$related,
$table = null,
$foreignPivotKey = null,
$relatedPivotKey = null,
$parentKey = null,
$relatedKey = null
) {
$instance = $this->newRelatedInstance($related);

$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();

$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();

if (is_null($table)) {
$table = $this->joiningTable($related, $instance);
}

return $this->newBelongsToManyOfDescendants(
$instance->newQuery(),
$this,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(),
false
);
}

/**
* Define a many-to-many relationship of the model's descendants and itself.
*
* @param string $related
* @param string|null $table
* @param string|null $foreignPivotKey
* @param string|null $relatedPivotKey
* @param string|null $parentKey
* @param string|null $relatedKey
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\BelongsToManyOfDescendants
*/
public function belongsToManyOfDescendantsAndSelf(
$related,
$table = null,
$foreignPivotKey = null,
$relatedPivotKey = null,
$parentKey = null,
$relatedKey = null
) {
$instance = $this->newRelatedInstance($related);

$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();

$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();

if (is_null($table)) {
$table = $this->joiningTable($related, $instance);
}

return $this->newBelongsToManyOfDescendants(
$instance->newQuery(),
$this,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(),
true
);
}

/**
* Instantiate a new BelongsToManyOfDescendants relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $table
* @param string $foreignPivotKey
* @param string $relatedPivotKey
* @param string $parentKey
* @param string $relatedKey
* @param bool $andSelf
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\BelongsToManyOfDescendants
*/
protected function newBelongsToManyOfDescendants(
Builder $query,
Model $parent,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey,
$relatedKey,
$andSelf
) {
return new BelongsToManyOfDescendants(
$query,
$parent,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey,
$relatedKey,
$andSelf
);
}

/**
* Define a polymorphic many-to-many relationship of the model's descendants.
*
* @param string $related
* @param string $name
* @param string|null $table
* @param string|null $foreignPivotKey
* @param string|null $relatedPivotKey
* @param string|null $parentKey
* @param string|null $relatedKey
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\MorphToManyOfDescendants
*/
public function morphToManyOfDescendants(
$related,
$name,
$table = null,
$foreignPivotKey = null,
$relatedPivotKey = null,
$parentKey = null,
$relatedKey = null
) {
$instance = $this->newRelatedInstance($related);

$foreignPivotKey = $foreignPivotKey ?: $name.'_id';

$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();

if (! $table) {
$words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE);

$lastWord = array_pop($words);

$table = implode('', $words).Str::plural($lastWord);
}

return $this->newMorphToManyOfDescendants(
$instance->newQuery(),
$this,
$name,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(),
false
);
}

/**
* Define a polymorphic many-to-many relationship of the model's descendants and itself.
*
* @param string $related
* @param string $name
* @param string|null $table
* @param string|null $foreignPivotKey
* @param string|null $relatedPivotKey
* @param string|null $parentKey
* @param string|null $relatedKey
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\MorphToManyOfDescendants
*/
public function morphToManyOfDescendantsAndSelf(
$related,
$name,
$table = null,
$foreignPivotKey = null,
$relatedPivotKey = null,
$parentKey = null,
$relatedKey = null
) {
$instance = $this->newRelatedInstance($related);

$foreignPivotKey = $foreignPivotKey ?: $name.'_id';

$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();

if (! $table) {
$words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE);

$lastWord = array_pop($words);

$table = implode('', $words).Str::plural($lastWord);
}

return $this->newMorphToManyOfDescendants(
$instance->newQuery(),
$this,
$name,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey ?: $this->getKeyName(),
$relatedKey ?: $instance->getKeyName(),
true
);
}

/**
* Instantiate a new MorphToManyOfDescendants relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent
* @param string $name
* @param string $table
* @param string $foreignPivotKey
* @param string $relatedPivotKey
* @param string $parentKey
* @param string $relatedKey
* @param bool $andSelf
* @return \Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\MorphToManyOfDescendants
*/
protected function newMorphToManyOfDescendants(
Builder $query,
Model $parent,
$name,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey,
$relatedKey,
$andSelf
) {
return new MorphToManyOfDescendants(
$query,
$parent,
$name,
$table,
$foreignPivotKey,
$relatedPivotKey,
$parentKey,
$relatedKey,
$andSelf
);
}
}
26 changes: 20 additions & 6 deletions src/Eloquent/HasRecursiveRelationshipScopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,26 @@ protected function getRecursiveQuery(ExpressionGrammar $grammar, $direction, $fr
);
}

$this->addRecursiveQueryJoinsAndConstraints($query, $direction, $name, $joinColumns);

if (!is_null($maxDepth)) {
$query->where($this->getDepthName(), '<', $maxDepth);
}

return $query;
}

/**
* Add join and where clauses to the recursive query for a relationship expression.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $direction
* @param string $name
* @param array $joinColumns
* @return void
*/
protected function addRecursiveQueryJoinsAndConstraints(Builder $query, $direction, $name, array $joinColumns)
{
if ($direction === 'both') {
$query->join($name, function (JoinClause $join) use ($joinColumns) {
$join->on($joinColumns['asc'][0], '=', $joinColumns['asc'][1])
Expand All @@ -269,11 +289,5 @@ protected function getRecursiveQuery(ExpressionGrammar $grammar, $direction, $fr
} else {
$query->join($name, $joinColumns[$direction][0], '=', $joinColumns[$direction][1]);
}

if (!is_null($maxDepth)) {
$query->where($this->getDepthName(), '<', $maxDepth);
}

return $query;
}
}
Loading

0 comments on commit 3776bcf

Please sign in to comment.