Skip to content

Commit

Permalink
Merge pull request #5 from mr-punyapal/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
MrPunyapal authored Dec 12, 2023
2 parents bb82551 + ddf63f7 commit 7fd03a9
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 156 deletions.
2 changes: 2 additions & 0 deletions config/extended-relationships.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

// config for Mrpunyapal/LaravelExtendedRelationships
return [

Expand Down
1 change: 0 additions & 1 deletion debug.log

This file was deleted.

8 changes: 8 additions & 0 deletions pint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"preset": "laravel",
"rules": {
"declare_strict_types": true,
"strict_param":true,
"strict_comparison":true
}
}
35 changes: 14 additions & 21 deletions src/HasExtendedRelationships.php
Original file line number Diff line number Diff line change
@@ -1,46 +1,39 @@
<?php

declare(strict_types=1);

namespace Mrpunyapal\LaravelExtendedRelationships;

use Illuminate\Contracts\Database\Query\Builder;
use Mrpunyapal\LaravelExtendedRelationships\Relations\BelongsToArrayColumn;
use Mrpunyapal\LaravelExtendedRelationships\Relations\BelongsToManyKeys;
use Mrpunyapal\LaravelExtendedRelationships\Relations\HasManyArrayColumn;
use Mrpunyapal\LaravelExtendedRelationships\Relations\HasManyKeys;

trait HasExtendedRelationships
{
/**
* @param string|null $foreignKey
* @param string[]|null $relations
*/
public function belongsToManyKeys(string $related, string $foreignKey, array $relations): BelongsToManyKeys
public function belongsToManyKeys(string $related, ?string $foreignKey, ?array $relations): BelongsToManyKeys
{
$instance = new $related();

return new BelongsToManyKeys($instance->newQuery(), $this, $foreignKey, $relations);
return new BelongsToManyKeys($this->relatedNewQuery($related), $this, $foreignKey, $relations);
}

/**
* @param string[]|null $relations
*/
public function hasManyKeys(string $related, ?array $relations = null, ?string $localKey = null): HasManyKeys
public function hasManyKeys(string $related, ?array $relations, ?string $localKey): HasManyKeys
{
$instance = new $related();

return new HasManyKeys($instance->newQuery(), $this, $relations, $localKey);
return new HasManyKeys($this->relatedNewQuery($related), $this, $relations, $localKey);
}

public function hasManyArrayColumn(string $related, ?string $foreignKey, ?string $localKey): HasManyArrayColumn
{
$instance = new $related();

return new HasManyArrayColumn($instance->newQuery(), $this, $foreignKey, $localKey);
return new HasManyArrayColumn($this->relatedNewQuery($related), $this, $foreignKey, $localKey);
}

public function belongsToArrayColumn(string $related, ?string $foreignKey, ?string $localKey, $isString = false): BelongsToArrayColumn
public function belongsToArrayColumn(string $related, ?string $foreignKey, ?string $localKey, bool $isString = false): BelongsToArrayColumn
{
$instance = new $related();
return new BelongsToArrayColumn($this->relatedNewQuery($related), $this, $foreignKey, $localKey, null, $isString);
}

return new BelongsToArrayColumn($instance->newQuery(), $this, $foreignKey, $localKey, null, $isString);
protected function relatedNewQuery($related): Builder
{
return (new $related())->newQuery();
}
}
58 changes: 20 additions & 38 deletions src/Relations/BelongsToArrayColumn.php
Original file line number Diff line number Diff line change
@@ -1,61 +1,47 @@
<?php

declare(strict_types=1);

namespace Mrpunyapal\LaravelExtendedRelationships\Relations;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class BelongsToArrayColumn extends BelongsTo
{
/**
* Indicates whether the value is a string.
*
* @var bool
*/
protected $isString;

/**
* Create a new belongs to relationship instance.
*
* @param string $foreignKey
* @param string $ownerKey
* @param string $relationName
* @param bool $isString
* @return void
* Create a new belongs to array Column relationship instance.
*/
public function __construct(Builder $query, Model $child, $foreignKey, $ownerKey, $relationName, $isString = false)
public function __construct(Builder $query, Model $child, string $foreignKey, string $ownerKey, ?string $relationName, protected bool $isString = false)
{
$this->isString = $isString;
parent::__construct($query, $child, $foreignKey, $ownerKey, $relationName);
}

/**
* Set the base constraints on the relation query.
*
* @return void
*/
public function addConstraints()
public function addConstraints(): void
{
if (static::$constraints) {
$query = $this->getBaseQuery();
if (! static::$constraints) {
return;
}
$query = $this->getBaseQuery();

$query->when($this->isString, function ($q) {
$q->whereJsonContains($this->ownerKey, (string) $this->getParentKey());
}, function ($q) {
$q->whereJsonContains($this->ownerKey, $this->getParentKey());
});
$query->when($this->isString, function ($q) {
$q->whereJsonContains($this->ownerKey, (string) $this->getParentKey());
}, function ($q) {
$q->whereJsonContains($this->ownerKey, $this->getParentKey());
});

$query->whereNotNull($this->ownerKey);
}
$query->whereNotNull($this->ownerKey);
}

/**
* Set the constraints for an eager load of the relation.
*
* @return void
*/
public function addEagerConstraints(array $models)
public function addEagerConstraints(array $models): void
{
$ids = $this->getEagerModelKeys($models);
$this->query->where(function ($q) use ($ids) {
Expand All @@ -72,18 +58,16 @@ public function addEagerConstraints(array $models)
/**
* Match the eagerly loaded results to their many parents.
*
* @param \Illuminate\Database\Eloquent\Collection $results
* @param string $relation
* @return array
*/
public function match(array $models, $results, $relation)
public function match(array $models, Collection $results, $relation): array
{
$owner = $this->getOwnerKeyName();
foreach ($models as $model) {
$id = $model->getAttribute($this->foreignKey);
$collection = collect();
foreach ($results as $data) {
if (in_array($id, $data->{$owner})) {
if (in_array($id, $data->{$owner}, true)) {
$collection->push($data);
}
}
Expand All @@ -95,10 +79,8 @@ public function match(array $models, $results, $relation)

/**
* Get the results of the relationship.
*
* @return mixed
*/
public function getResults()
public function getResults(): mixed
{
return $this->query->get();
}
Expand Down
70 changes: 33 additions & 37 deletions src/Relations/BelongsToManyKeys.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Mrpunyapal\LaravelExtendedRelationships\Relations;

use Illuminate\Database\Eloquent\Builder;
Expand All @@ -12,63 +14,51 @@ class BelongsToManyKeys extends Relation
/**
* The local keys of the parent model.
*
* @var string[]
* @var array<string>
*/
protected $localKeys;
protected array $localKeys;

/**
* The local keys of the parent model.
*
* @var string[]
*/
protected $relations;

/**
* The foreign key of the related model.
*
* @var string
* @var array<string>
*/
protected $foreignKey;
protected array $relations;

/**
* Create a new has one or many relationship instance.
*
* @param array $localKeys
* @return void
*/
public function __construct(Builder $query, Model $parent, string $foreignKey, array $relations)
public function __construct(Builder $query, Model $parent, protected string $foreignKey, array $relations)
{
$this->localKeys = array_keys($relations);
$this->foreignKey = $foreignKey;
$this->relations = $relations;
parent::__construct($query, $parent);
}

/**
* Set the base constraints on the relation query.
* Note: Used to load relations of one model.
*
* @return void
*/
public function addConstraints()
public function addConstraints(): void
{
if (static::$constraints) {
$this->query->where(function ($query) {
foreach ($this->localKeys as $localKey) {
$query->orWhere(function ($query) use ($localKey) {
$query->where($this->foreignKey, '=', $this->getParentKey($localKey))
->whereNotNull($this->foreignKey);
});
}
});
if (! static::$constraints) {
return;
}
$this->query->where(function ($query) {
foreach ($this->localKeys as $localKey) {
$query->orWhere(function ($query) use ($localKey) {
$query->where($this->foreignKey, '=', $this->getParentKey($localKey))
->whereNotNull($this->foreignKey);
});
}
});
}

/**
* Set the constraints for an eager load of the relation.
* Note: Used to load relations of multiple models at once.
*/
public function addEagerConstraints(array $models)
public function addEagerConstraints(array $models): void
{
$localKeys = $this->localKeys;
$foreignKey = $this->foreignKey;
Expand All @@ -83,9 +73,8 @@ public function addEagerConstraints(array $models)
* Initialize the relation on a set of models.
*
* @param string $relation
* @return array
*/
public function initRelation(array $models, $relation)
public function initRelation(array $models, $relation): array|Collection
{
foreach ($models as $model) {
$model->setRelation($relation, $this->related->newCollection());
Expand All @@ -94,7 +83,10 @@ public function initRelation(array $models, $relation)
return $models;
}

public function match(array $models, Collection $results, $relation)
/**
* Match the related models with the given models based on the local keys.
*/
public function match(array $models, Collection $results, $relation): array
{
$dictionary = $this->buildDictionary($results);

Expand All @@ -112,7 +104,10 @@ public function match(array $models, Collection $results, $relation)
return $models;
}

public function buildDictionary(Collection $models)
/**
* Build a dictionary using the given models.
*/
public function buildDictionary(Collection $models): array|Collection
{
$dictionary = [];
foreach ($models as $model) {
Expand All @@ -122,17 +117,18 @@ public function buildDictionary(Collection $models)
return $dictionary;
}

public function getParentKey($localKey)
/**
* Get the parent key value for the given local key.
*/
public function getParentKey(string $localKey): mixed
{
return $this->parent->getAttribute($localKey);
}

/**
* Get the results of the relationship.
*
* @return mixed
*/
public function getResults()
public function getResults(): mixed
{
if (! static::$constraints) {
return $this->query->get();
Expand Down
Loading

0 comments on commit 7fd03a9

Please sign in to comment.