Skip to content

Commit

Permalink
Add withInitialQueryConstraint() and withQueryConstraint() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
staudenmeir committed Jan 17, 2024
1 parent 48d0b84 commit 04df119
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 124 deletions.
26 changes: 16 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Supports Laravel 5.5.29+.
- [Path](#path)
- [Custom Paths](#custom-paths)
- [Nested Results](#nested-results)
- [Recursive Query Constraints](#recursive-query-constraints)
- [Initial & Recursive Query Constraints](#initial--recursive-query-constraints)
- [Custom Relationships](#custom-relationships)
- [Concatenation](#concatenation)

Expand Down Expand Up @@ -363,19 +363,22 @@ This recursively sets `children` relationships:
]
```

#### Recursive Query Constraints
#### Initial & Recursive Query Constraints

You can add custom constraints to the CTE's recursive query. Consider a query where you want to traverse a tree while
skipping inactive users and their subtrees:
You can add custom constraints to the CTE's initial and recursive query. Consider a query where you want to traverse a
tree while skipping inactive users and their descendants:

```php
$tree = User::withRecursiveQueryConstraint(function (Builder $query) {
$tree = User::withQueryConstraint(function (Builder $query) {
$query->where('users.active', true);
}, function () {
return User::tree()->get();
});
```

You can also add a custom constraint to only the initial or recursive query using `withInitialQueryConstraint()`/
`withRecursiveQueryConstraint()`.

#### Custom Relationships

You can also define custom relationships to retrieve related models recursively.
Expand Down Expand Up @@ -663,7 +666,7 @@ Supports Laravel 9+.
- [Path](#graphs-path)
- [Custom Paths](#graphs-custom-paths)
- [Nested Results](#graphs-nested-results)
- [Recursive Query Constraints](#graphs-recursive-query-constraints)
- [Initial & Recursive Query Constraints](#graphs-initial--recursive-query-constraints)

#### <a name="graphs-getting-started">Getting Started</a>

Expand Down Expand Up @@ -1026,19 +1029,22 @@ This recursively sets `children` relationships:
]
```

#### <a name="graphs-recursive-query-constraints">Recursive Query Constraints</a>
#### <a name="graphs-initial--recursive-query-constraints">Initial & Recursive Query Constraints</a>

You can add custom constraints to the CTE's recursive query. Consider a query where you want to traverse a node's
descendants while skipping inactive nodes and their subgraphs:
You can add custom constraints to the CTE's initial and recursive query. Consider a query where you want to traverse a
node's descendants while skipping inactive nodes and their descendants:

```php
$descendants = Node::withRecursiveQueryConstraint(function (Builder $query) {
$descendants = Node::withQueryConstraint(function (Builder $query) {
$query->where('nodes.active', true);
}, function () {
return Node::find($id)->descendants;
});
```

You can also add a custom constraint to only the initial or recursive query using `withInitialQueryConstraint()`/
`withRecursiveQueryConstraint()`.

### Package Conflicts

- `staudenmeir/eloquent-eager-limit`: Replace both packages
Expand Down
49 changes: 1 addition & 48 deletions src/Eloquent/Traits/HasAdjacencyList.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,9 @@
trait HasAdjacencyList
{
use HasOfDescendantsRelationships;
use HasQueryConstraints;
use HasRecursiveRelationshipScopes;

/**
* The additional constraint for the recursive query.
*
* @var callable|null
*/
public static $recursiveQueryConstraint;

/**
* Get the name of the parent key column.
*
Expand Down Expand Up @@ -414,45 +408,4 @@ public function newCollection(array $models = [])
{
return new Collection($models);
}

/**
* Set an additional constraint for the recursive query.
*
* @param callable $constraint
* @return void
*/
public static function setRecursiveQueryConstraint(callable $constraint)
{
static::$recursiveQueryConstraint = $constraint;
}

/**
* Unset the additional constraint for the recursive query.
*
* @return void
*/
public static function unsetRecursiveQueryConstraint()
{
static::$recursiveQueryConstraint = null;
}

/**
* Execute a query with an additional constraint for the recursive query.
*
* @param callable $constraint
* @param callable $query
* @return mixed
*/
public static function withRecursiveQueryConstraint(callable $constraint, callable $query)
{
$previous = static::$recursiveQueryConstraint;

static::$recursiveQueryConstraint = $constraint;

$result = $query();

static::$recursiveQueryConstraint = $previous;

return $result;
}
}
49 changes: 1 addition & 48 deletions src/Eloquent/Traits/HasGraphAdjacencyList.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@
trait HasGraphAdjacencyList
{
use HasGraphRelationshipScopes;

/**
* The additional constraint for the recursive query.
*
* @var callable|null
*/
public static $recursiveQueryConstraint;
use HasQueryConstraints;

/**
* Get the name of the pivot table.
Expand Down Expand Up @@ -433,47 +427,6 @@ public function newCollection(array $models = [])
return new Collection($models);
}

/**
* Set an additional constraint for the recursive query.
*
* @param callable $constraint
* @return void
*/
public static function setRecursiveQueryConstraint(callable $constraint): void
{
static::$recursiveQueryConstraint = $constraint;
}

/**
* Unset the additional constraint for the recursive query.
*
* @return void
*/
public static function unsetRecursiveQueryConstraint(): void
{
static::$recursiveQueryConstraint = null;
}

/**
* Execute a query with an additional constraint for the recursive query.
*
* @param callable $constraint
* @param callable $query
* @return mixed
*/
public static function withRecursiveQueryConstraint(callable $constraint, callable $query): mixed
{
$previous = static::$recursiveQueryConstraint;

static::$recursiveQueryConstraint = $constraint;

$result = $query();

static::$recursiveQueryConstraint = $previous;

return $result;
}

/**
* Execute a query with a maximum depth constraint for the recursive query.
*
Expand Down
4 changes: 4 additions & 0 deletions src/Eloquent/Traits/HasGraphRelationshipScopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ protected function getInitialQuery(

$constraint($query);

if (static::$initialQueryConstraint) {
(static::$initialQueryConstraint)($query);
}

return $query;
}

Expand Down
106 changes: 106 additions & 0 deletions src/Eloquent/Traits/HasQueryConstraints.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace Staudenmeir\LaravelAdjacencyList\Eloquent\Traits;

trait HasQueryConstraints
{
/**
* The additional constraint for the initial query.
*
* @var callable|null
*/
public static $initialQueryConstraint;

/**
* The additional constraint for the recursive query.
*
* @var callable|null
*/
public static $recursiveQueryConstraint;

/**
* Execute a query with an additional constraint for the initial query.
*
* @param callable $constraint
* @param callable $query
* @return mixed
*/
public static function withInitialQueryConstraint(callable $constraint, callable $query): mixed
{
$previous = static::$initialQueryConstraint;

static::$initialQueryConstraint = $constraint;

$result = $query();

static::$initialQueryConstraint = $previous;

return $result;
}

/**
* Execute a query with an additional constraint for the recursive query.
*
* @param callable $constraint
* @param callable $query
* @return mixed
*/
public static function withRecursiveQueryConstraint(callable $constraint, callable $query): mixed
{
$previous = static::$recursiveQueryConstraint;

static::$recursiveQueryConstraint = $constraint;

$result = $query();

static::$recursiveQueryConstraint = $previous;

return $result;
}

/**
* Set an additional constraint for the recursive query.
*
* @param callable $constraint
* @return void
*/
public static function setRecursiveQueryConstraint(callable $constraint): void
{
static::$recursiveQueryConstraint = $constraint;
}

/**
* Unset the additional constraint for the recursive query.
*
* @return void
*/
public static function unsetRecursiveQueryConstraint(): void
{
static::$recursiveQueryConstraint = null;
}

/**
* Execute a query with an additional constraint for the initial and recursive query.
*
* @param callable $constraint
* @param callable $query
* @return mixed
*/
public static function withQueryConstraint(
callable $constraint,
callable $query
): mixed {
$previousInitialConstraint = static::$initialQueryConstraint;
$previousRecursiveConstraint = static::$recursiveQueryConstraint;

static::$initialQueryConstraint = $constraint;
static::$recursiveQueryConstraint = $constraint;

$result = $query();

static::$initialQueryConstraint = $previousInitialConstraint;
static::$recursiveQueryConstraint = $previousRecursiveConstraint;

return $result;
}
}
4 changes: 4 additions & 0 deletions src/Eloquent/Traits/HasRecursiveRelationshipScopes.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ protected function getInitialQuery(ExpressionGrammar $grammar, callable $constra

$constraint($query);

if (static::$initialQueryConstraint) {
(static::$initialQueryConstraint)($query);
}

return $query;
}

Expand Down
Loading

0 comments on commit 04df119

Please sign in to comment.