diff --git a/src/Collections/ConnectiveCollection.php b/src/Collections/ConnectiveCollection.php index 3499b1a..92f9d2c 100644 --- a/src/Collections/ConnectiveCollection.php +++ b/src/Collections/ConnectiveCollection.php @@ -11,7 +11,7 @@ class ConnectiveCollection extends Collection /** * @return ?ConnectiveCollection */ - public function connectives(string|array $connectionTypes = null, string|array $modelTypes = null): ?ConnectiveCollection + public function connectives(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?ConnectiveCollection { /** * @var ConnectiveCollection $collection; diff --git a/src/Contracts/ConnectiveContract.php b/src/Contracts/ConnectiveContract.php index 3951684..0c98ac6 100644 --- a/src/Contracts/ConnectiveContract.php +++ b/src/Contracts/ConnectiveContract.php @@ -32,7 +32,7 @@ public function connectTo(ConnectiveContract&Model $model, string $connectionTyp * @param string|array $modelTypes * @return Collection|null */ - public function connections(string|array $connectionTypes = null, string|array $modelTypes = null): ?Collection; + public function connections(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?Collection; /** * returns connected model instances (connective models) as a collection @@ -41,4 +41,20 @@ public function connections(string|array $connectionTypes = null, string|array $ * @return ConnectiveCollection|null */ public function connectives(string|array $connectionTypes, string|array $modelTypes): ?ConnectiveCollection; + + /** + * returns connection model instances as a collection + * + * @param string|array $modelTypes + * @return Collection|null + */ + public function inverseConnections(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?Collection; + + /** + * returns connected model instances (connective models) as a collection + * + * @param string|array $modelTypes + * @return ConnectiveCollection|null + */ + public function inverseConnectives(string|array $connectionTypes, string|array $modelTypes): ?ConnectiveCollection; } diff --git a/src/Models/Connection.php b/src/Models/Connection.php index 0c64346..3623fd6 100644 --- a/src/Models/Connection.php +++ b/src/Models/Connection.php @@ -6,10 +6,10 @@ use Illuminate\Database\Eloquent\Model; /** - * @property class-string $to_model_type - * @property int $to_model_id - * @property class-string $from_model_type - * @property int $from_model_id + * @property class-string $to_model_type + * @property int $to_model_id + * @property class-string $from_model_type + * @property int $from_model_id */ class Connection extends Model { diff --git a/src/Traits/Connective.php b/src/Traits/Connective.php index 901627e..a7f17b7 100644 --- a/src/Traits/Connective.php +++ b/src/Traits/Connective.php @@ -54,7 +54,7 @@ public function connectTo(ConnectiveContract&Model $model, string $connectionTyp * @param string|array $modelTypes * @return Collection|null */ - public function connections(string|array $connectionTypes = null, string|array $modelTypes = null): ?Collection + public function connections(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?Collection { $query = Connection::query(); @@ -77,7 +77,7 @@ public function connections(string|array $connectionTypes = null, string|array $ /** * @return ConnectiveCollection|null */ - public function connectives(string|array $connectionTypes = null, string|array $modelTypes = null): ?ConnectiveCollection + public function connectives(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?ConnectiveCollection { $connections = $this->connections($connectionTypes, $modelTypes); $collection = ConnectiveCollection::make(); @@ -92,4 +92,49 @@ public function connectives(string|array $connectionTypes = null, string|array $ return $collection; } + + /** + * returns connection model instances as a collection + * + * @param string|array $modelTypes + * @return Collection|null + */ + public function inverseConnections(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?Collection + { + $query = Connection::query(); + + if ($connectionTypes !== null) { + $connectionTypes = is_array($connectionTypes) ? $connectionTypes : [$connectionTypes]; + $query->whereIn('connection_type', $connectionTypes); + } + + if ($modelTypes !== null) { + $modelTypes = is_array($modelTypes) ? $modelTypes : [$modelTypes]; + $query->whereIn('from_model_type', $modelTypes); + } + + $query->where('to_model_type', get_class($this)) + ->where('to_model_id', $this->id); + + return $query->get(); + } + + /** + * @return ConnectiveCollection|null + */ + public function inverseConnectives(string|array|null $connectionTypes = null, string|array|null $modelTypes = null): ?ConnectiveCollection + { + $incomingConnections = $this->inverseConnections($connectionTypes, $modelTypes); + $collection = ConnectiveCollection::make(); + + foreach ($incomingConnections as $incomingConnection) { + $fromModelType = $incomingConnection->from_model_type; + $fromModelId = $incomingConnection->from_model_id; + + $fromModelInstance = $fromModelType::find($fromModelId); + $collection->push($fromModelInstance); + } + + return $collection; + } } diff --git a/tests/Models/Connective.php b/tests/Models/Connective.php index f8ac03c..147eab8 100644 --- a/tests/Models/Connective.php +++ b/tests/Models/Connective.php @@ -5,6 +5,9 @@ use AuroraWebSoftware\Connective\Contracts\ConnectiveContract; use Illuminate\Database\Eloquent\Model; +/** + * @property string $name + */ class Connective extends Model implements ConnectiveContract { use \AuroraWebSoftware\Connective\Traits\Connective; diff --git a/tests/Models/OtherConnective.php b/tests/Models/OtherConnective.php index 1c4664d..0217888 100644 --- a/tests/Models/OtherConnective.php +++ b/tests/Models/OtherConnective.php @@ -5,6 +5,9 @@ use AuroraWebSoftware\Connective\Contracts\ConnectiveContract; use Illuminate\Database\Eloquent\Model; +/** + * @property string $name + */ class OtherConnective extends Model implements ConnectiveContract { use \AuroraWebSoftware\Connective\Traits\Connective; diff --git a/tests/PackageTest.php b/tests/PackageTest.php index 253845e..7dd0290 100644 --- a/tests/PackageTest.php +++ b/tests/PackageTest.php @@ -4,6 +4,7 @@ use AuroraWebSoftware\Connective\Exceptions\ConnectionTypeException; use AuroraWebSoftware\Connective\Facades\Connective; use AuroraWebSoftware\Connective\Models\Connection; +use AuroraWebSoftware\Connective\Tests\Models\OtherConnective; use Illuminate\Database\Schema\Blueprint; use Illuminate\Foundation\Auth\User; use Illuminate\Support\Facades\Artisan; @@ -228,7 +229,7 @@ 'name' => 'name63', ]); - $otherConnective1 = \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::create([ + $otherConnective1 = OtherConnective::create([ 'name' => 'othername1', ]); @@ -252,12 +253,12 @@ ->toHaveCount(1) ->each->toBeInstanceOf(ConnectiveContract::class); - expect($connective2->connectives(connectionTypes: 'b', modelTypes: \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::class)) + expect($connective2->connectives(connectionTypes: 'b', modelTypes: OtherConnective::class)) ->toHaveCount(0); $connective2->connectTo($otherConnective1, 'b'); - expect($connective2->connectives(connectionTypes: 'b', modelTypes: \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::class)) + expect($connective2->connectives(connectionTypes: 'b', modelTypes: OtherConnective::class)) ->toHaveCount(1); }); @@ -294,14 +295,14 @@ /** * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $otherConnective1 */ - $otherConnective1 = \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::create([ + $otherConnective1 = OtherConnective::create([ 'name' => 'othername71', ]); /** * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $otherConnective2 */ - $otherConnective2 = \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::create([ + $otherConnective2 = OtherConnective::create([ 'name' => 'othername72', ]); @@ -325,7 +326,7 @@ $connective2->connectives() ->connectives( ['a', 'b'], - \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::class)) + OtherConnective::class)) ->toHaveCount(2); expect( @@ -343,7 +344,7 @@ ['a', 'b'], [ \AuroraWebSoftware\Connective\Tests\Models\Connective::class, - \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::class, + OtherConnective::class, ])) ->toHaveCount(3); @@ -355,8 +356,143 @@ expect($connective2->connectives()->connectives()->connectives()->connectives(modelTypes: \AuroraWebSoftware\Connective\Tests\Models\Connective::class))->toHaveCount(2); - expect($connective2->connectives()->connectives()->connectives()->connectives(modelTypes: \AuroraWebSoftware\Connective\Tests\Models\OtherConnective::class))->toHaveCount(0); + expect($connective2->connectives()->connectives()->connectives()->connectives(modelTypes: OtherConnective::class))->toHaveCount(0); }); +it('can get inverse connections of a connective model', function () { + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective2 + */ + $connective2 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name200', + ]); + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective3 + */ + $connective3 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name201', + ]); + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective4 + */ + $connective4 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name202', + ]); + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective5 + */ + $connective5 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name203', + ]); + + $connective2->connectTo($connective3, 'a'); + $connective2->connectTo($connective3, 'b'); + + $connective2->connectTo($connective4, 'a'); + $connective2->connectTo($connective4, 'b'); + + $connective2->connectTo($connective5, 'b'); + + // all (without any paramaters) + expect($connective2->connections())->toHaveCount(5); + + // all inverse connections + expect($connective3->inverseConnections())->toHaveCount(2); + expect($connective4->inverseConnections())->toHaveCount(2); + expect($connective5->inverseConnections())->toHaveCount(1); + + // connection type "a" + expect($connective2->connections('a'))->toHaveCount(2); + expect($connective3->inverseConnections('a'))->toHaveCount(1); + + // connection type "b" + expect($connective2->connections('b'))->toHaveCount(3); + expect($connective4->inverseConnectives('b'))->toHaveCount(1); + + // a and b as (with array paramater) + expect($connective2->connections(['a', 'b']))->toHaveCount(5); + expect($connective3->inverseConnectives(['a', 'b']))->toHaveCount(2); + + // by model type + expect($connective2->connections(modelTypes: \AuroraWebSoftware\Connective\Tests\Models\Connective::class))->toHaveCount(5); + expect($connective2->inverseConnectives(modelTypes: \AuroraWebSoftware\Connective\Tests\Models\Connective::class))->toHaveCount(0); + expect($connective3->inverseConnectives(modelTypes: \AuroraWebSoftware\Connective\Tests\Models\Connective::class))->toHaveCount(2); + +}); + +it('can get inverse connectives of a model', function () { + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective2 + */ + $connective2 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name300', + ]); + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective3 + */ + $connective3 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name301', + ]); + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective4 + */ + $connective4 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name302', + ]); + + /** + * @var ConnectiveContract & \AuroraWebSoftware\Connective\Tests\Models\Connective $connective5 + */ + $connective5 = \AuroraWebSoftware\Connective\Tests\Models\Connective::create([ + 'name' => 'name303', + ]); + + $otherConnective1 = OtherConnective::create([ + 'name' => 'othername300', + ]); + + $connective2->connectTo($connective3, 'a'); + $connective2->connectTo($connective4, 'a'); + $connective2->connectTo($connective5, 'b'); + + expect($connective2->connectives()) + ->toHaveCount(3) + ->each->toBeInstanceOf(ConnectiveContract::class); + + expect($connective3->inverseConnectives()) + ->toHaveCount(1) + ->each->toBeInstanceOf(ConnectiveContract::class); + + expect($connective3->inverseConnectives(connectionTypes: 'a')) + ->toHaveCount(1) + ->each->toBeInstanceOf(ConnectiveContract::class); + + expect($connective2->connectives(connectionTypes: 'b')) + ->toHaveCount(1) + ->each->toBeInstanceOf(ConnectiveContract::class); + + expect($connective2->connectives(connectionTypes: 'b', modelTypes: \AuroraWebSoftware\Connective\Tests\Models\Connective::class)) + ->toHaveCount(1) + ->each->toBeInstanceOf(ConnectiveContract::class); + + expect($connective2->connectives(connectionTypes: 'b', modelTypes: OtherConnective::class)) + ->toHaveCount(0); + + $connective2->connectTo($otherConnective1, 'b'); + + expect($connective2->connectives(connectionTypes: 'b', modelTypes: OtherConnective::class)) + ->toHaveCount(1); + + expect($otherConnective1->inverseConnectives(connectionTypes: 'b', modelTypes: \AuroraWebSoftware\Connective\Tests\Models\Connective::class)) + ->toHaveCount(1); +}); + // connected to ve coonetedfrom testleri