diff --git a/README.md b/README.md index 08d6e9b..526896c 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ Supports Laravel 5.5+. - [Custom Paths](#custom-paths) - [Nested Results](#nested-results) - [Initial & Recursive Query Constraints](#initial--recursive-query-constraints) +- [Additional Methods](#additional-methods) - [Custom Relationships](#custom-relationships) - [Deep Relationship Concatenation](#deep-relationship-concatenation) - [Known Issues](#known-issues) @@ -407,6 +408,24 @@ $tree = User::withQueryConstraint(function (Builder $query) { You can also add a custom constraint to only the initial or recursive query using `withInitialQueryConstraint()`/ `withRecursiveQueryConstraint()`. +#### Additional Methods + +The trait also provides methods to check relationships between models: + +- `isChildOf(Model $model)`: Checks if the current model is a child of the given model. +- `isParentOf(Model $model)`: Checks if the current model is a parent of the given model. +- `getDepthRelatedTo(Model $model)`: Returns the depth of the current model related to the given model. + +```php +$rootUser = User::create(['parent_id' => null]); +$firstLevelUser = User::create(['parent_id' => $rootUser->id]); +$secondLevelUser = User::create(['parent_id' => $firstLevelUser->id]); + +$isChildOf = $secondLevelUser->isChildOf($firstLevelUser); // Output: true +$isParentOf = $rootUser->isParentOf($firstLevelUser); // Output: true +$depthRelatedTo = $secondLevelUser->getDepthRelatedTo($rootUser); // Output: 2 +``` + #### Custom Relationships You can also define custom relationships to retrieve related models recursively. diff --git a/src/Eloquent/Traits/HasAdjacencyList.php b/src/Eloquent/Traits/HasAdjacencyList.php index 051dccc..4a57633 100644 --- a/src/Eloquent/Traits/HasAdjacencyList.php +++ b/src/Eloquent/Traits/HasAdjacencyList.php @@ -16,6 +16,7 @@ trait HasAdjacencyList { use HasOfDescendantsRelationships; use HasQueryConstraints; + use HasRecursiveRelationshipHelpers; use HasRecursiveRelationshipScopes; /** diff --git a/src/Eloquent/Traits/HasRecursiveRelationshipHelpers.php b/src/Eloquent/Traits/HasRecursiveRelationshipHelpers.php new file mode 100644 index 0000000..998e4f8 --- /dev/null +++ b/src/Eloquent/Traits/HasRecursiveRelationshipHelpers.php @@ -0,0 +1,50 @@ +parent ? $this->parent->is($model) : false; + } + + /** + * Determine if the model is the parent of the given model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return bool + */ + public function isParentOf(Model $model): bool + { + return $this->children->contains($model); + } + + /** + * Get the depth of the model related to the given model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return int|null + */ + public function getDepthRelatedTo(Model $model): ?int + { + $thisModel = $this->bloodline->find($this); + $relatedModel = $this->bloodline->find($model); + + if ($thisModel && $relatedModel) { + $depthName = $this->getDepthName(); + + return $thisModel->$depthName - $relatedModel->$depthName; + } + + return null; + } +} diff --git a/tests/Tree/EloquentTest.php b/tests/Tree/EloquentTest.php index 25c74bc..bc27743 100644 --- a/tests/Tree/EloquentTest.php +++ b/tests/Tree/EloquentTest.php @@ -191,6 +191,27 @@ public function testScopeDepthFirstWithStringKey() $this->assertEquals(['a', 'b', 'c', 'd'], $categories->pluck('id')->all()); } + public function testIsChildOf() + { + $this->assertTrue(User::find(5)->isChildOf(User::find(2))); + $this->assertFalse(User::find(5)->isChildOf(User::find(1))); + $this->assertFalse(User::find(1)->isChildOf(User::find(2))); + } + + public function testIsParentOf() + { + $this->assertTrue(User::find(2)->isParentOf(User::find(5))); + $this->assertFalse(User::find(1)->isParentOf(User::find(5))); + $this->assertFalse(User::find(2)->isParentOf(User::find(1))); + } + + public function testGetDepthRelatedTo() + { + $this->assertEquals(2, User::find(5)->getDepthRelatedTo(User::find(1))); + $this->assertEquals(-2, User::find(1)->getDepthRelatedTo(User::find(5))); + $this->assertNull(User::find(4)->getDepthRelatedTo(User::find(5))); + } + public function testWithInitialQueryConstraint() { $users = User::withInitialQueryConstraint(function (Builder $query) {