diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml
new file mode 100644
index 0000000..cd358ad
--- /dev/null
+++ b/.github/workflows/coding-standards.yml
@@ -0,0 +1,29 @@
+name: Lint
+
+on: [push]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.2
+ extensions: json, dom, curl, libxml, mbstring
+ coverage: none
+
+ - name: Install Pint
+ run: composer global require laravel/pint
+
+ - name: Run Pint
+ run: pint
+
+ - name: Commit linted files
+ uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ commit_message: Fixed code styling
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 614da17..66835f5 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -1,4 +1,4 @@
-name: coverage
+name: Coverage
on:
push:
@@ -6,7 +6,7 @@ on:
jobs:
linux_tests:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
strategy:
fail-fast: true
@@ -20,7 +20,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
- php-version: 8.1
+ php-version: 8.2
extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, gd, xdebug
tools: composer:v2
coverage: xdebug
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
new file mode 100644
index 0000000..e1df0c5
--- /dev/null
+++ b/.github/workflows/static-analysis.yml
@@ -0,0 +1,31 @@
+name: Static Analysis
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ static:
+ name: Static Analysis
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: true
+ matrix:
+ php: ['8.1', '8.2']
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: json, dom, curl, libxml, mbstring
+ coverage: none
+
+ - name: Install Dependencies
+ run: composer update --prefer-stable --no-interaction --no-progress --ansi
+
+ - name: Run Static Analysis
+ run: composer test:static
diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
deleted file mode 100644
index d81f31d..0000000
--- a/.github/workflows/style.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: style
-
-on:
- push:
- pull_request:
-
-jobs:
- linux_tests:
- runs-on: ubuntu-20.04
-
- strategy:
- fail-fast: true
-
- name: Style Check
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v3
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: 8.1
- extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, gd
- tools: composer:v2
- coverage: none
-
- - name: Install dependencies
- uses: nick-invision/retry@v2
- with:
- timeout_minutes: 5
- max_attempts: 2
- command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress
-
- - name: Run PHPCS
- run: vendor/bin/phpcs
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 06764e6..7a294ea 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,4 +1,4 @@
-name: tests
+name: Tests
on:
push:
@@ -6,12 +6,12 @@ on:
jobs:
linux_tests:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
- php: ['7.3', '7.4', '8.0', '8.1']
+ php: ['8.0', '8.1', '8.2']
stability: [prefer-lowest, prefer-stable]
name: PHP ${{ matrix.php }} - ${{ matrix.stability }}
@@ -33,7 +33,7 @@ jobs:
with:
timeout_minutes: 5
max_attempts: 2
- command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress ${{ matrix.flags }}
+ command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
- name: Execute tests
run: vendor/bin/phpunit --verbose
diff --git a/README.md b/README.md
index 504fd99..39578c5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Laravel Relation Joins
-[![Laravel Version](https://img.shields.io/badge/Laravel-8.x%2F9.x%2F10.x-blue)](https://laravel.com/)
+[![Laravel Version](https://img.shields.io/badge/Laravel-9.x%2F10.x%2F11.x-blue)](https://laravel.com/)
[![Build Status](https://github.com/tylernathanreed/laravel-relation-joins/workflows/tests/badge.svg)](https://github.com/tylernathanreed/laravel-relation-joins/actions)
[![Style Status](https://github.com/tylernathanreed/laravel-relation-joins/workflows/style/badge.svg)](https://github.com/tylernathanreed/laravel-relation-joins/actions)
[![Coverage Status](https://coveralls.io/repos/github/tylernathanreed/laravel-relation-joins/badge.svg?branch=master)](https://coveralls.io/github/tylernathanreed/laravel-relation-joins?branch=master)
@@ -62,11 +62,15 @@ Reedware\LaravelRelationJoins\LaravelRelationJoinServiceProvider::class
### Versioning
-This package was built with the latest version of Laravel in mind, but support goes back to Laravel 8.x.
+This package is maintained with the latest version of Laravel in mind, but support follows Laravel's [Support Policy](https://laravel.com/docs/master/releases#support-policy).
-For Laravel 7.x, use version 3.x of this package.
-For Laravel 6.x, use version 2.x of this package.
-For Laravel 5.5, use version 1.x of this package.
+| Package | Laravel | PHP |
+| :-----: | :--------: | :--------: |
+| 5.x | 9.x - 11.x | 8.0 - 8.2+ |
+| 4.x | 8.x - 10.x | 7.3 - 8.0+ |
+| 3.x | 7.x - 9.x | 7.2 - 8.0+ |
+| 2.x | 6.x - 8.x | 7.2 - 8.0+ |
+| 1.x | 5.5 - 8.x | 7.1 - 8.0+ |
## Usage
diff --git a/composer.json b/composer.json
index b90f390..ad5905f 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,13 @@
{
"name": "reedware/laravel-relation-joins",
"description": "Adds the ability to join on a relationship by name.",
- "keywords": ["laravel", "relation", "join", "eloquent", "query"],
+ "keywords": [
+ "laravel",
+ "relation",
+ "join",
+ "eloquent",
+ "query"
+ ],
"license": "MIT",
"authors": [
{
@@ -10,17 +16,18 @@
}
],
"require": {
- "php": ">=7.3",
- "illuminate/contracts": "^8.83|^9.52|^10.0",
- "illuminate/database": "^8.83|^9.52|^10.0",
- "illuminate/support": "^8.83|^9.52|^10.0"
+ "php": ">=8.0",
+ "illuminate/contracts": "^9.52|^10.0",
+ "illuminate/database": "^9.52|^10.0",
+ "illuminate/support": "^9.52|^10.0"
},
"require-dev": {
- "illuminate/container": "^8.83|^9.52|^10.0",
- "mockery/mockery": "^1.5.1",
+ "illuminate/container": "^9.52|^10.0",
+ "laravel/pint": "^1.5",
+ "mockery/mockery": "^1.6.6",
"php-coveralls/php-coveralls": "^2.4",
- "phpunit/phpunit": "^8.5.33|^9.5",
- "squizlabs/php_codesniffer": "^3.6"
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^9.5"
},
"autoload": {
"psr-4": {
@@ -38,5 +45,20 @@
"Reedware\\LaravelRelationJoins\\LaravelRelationJoinServiceProvider"
]
}
+ },
+ "minimum-stability": "stable",
+ "config": {
+ "sort-packages": true,
+ "preferred-install": "dist"
+ },
+ "scripts": {
+ "test:coverage": [
+ "@test:suite",
+ "php-coveralls -v --dry-run"
+ ],
+ "test:static": "phpstan",
+ "test:style": "pint --test",
+ "test:style-fix": "pint",
+ "test:suite": "phpunit --verbose"
}
}
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..f6ef1fa
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,33 @@
+parameters:
+ level: 6
+ paths:
+ - src
+ excludePaths:
+ - tests/*
+ stubFiles:
+ - stubs/EloquentBuilder.stub
+ - stubs/QueryBuilder.stub
+ - stubs/Relation.stub
+ ignoreErrors:
+ -
+ message: '#Call to protected method \w+\(\) of class Illuminate\\Database\\Eloquent\\Builder.#'
+ path: src/Mixins/JoinsRelationships.php
+ -
+ message: '#Access to protected property Illuminate\\Database\\Eloquent\\Builder::\$\w+.#'
+ path: src/Mixins/JoinsRelationships.php
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/EloquentJoinClause.php b/src/EloquentJoinClause.php
index 2393481..39bcf1c 100644
--- a/src/EloquentJoinClause.php
+++ b/src/EloquentJoinClause.php
@@ -12,32 +12,21 @@ class EloquentJoinClause extends JoinClause
{
/**
* The model associated to this join.
- *
- * @var \Illuminate\Database\Eloquent\Model
*/
- public $model;
+ public Model $model;
/**
* The eloquent query representing this join.
- *
- * @var \Illuminate\Database\Eloquent\Builder
*/
- public $eloquent;
+ public Eloquent $eloquent;
/**
* Whether or not a method call is being forwarded through eloquent.
- *
- * @var boolean
*/
- protected $forwardingCall = false;
+ protected bool $forwardingCall = false;
/**
* Create a new join clause instance.
- *
- * @param \Illuminate\Database\Query\JoinClause $parentJoin
- * @param \Illuminate\Database\Eloquent\Model $model
- *
- * @return $this
*/
public function __construct(JoinClause $parentJoin, Model $model)
{
@@ -55,12 +44,8 @@ public function __construct(JoinClause $parentJoin, Model $model)
/**
* Merges the properties of the parent join into this join.
- *
- * @param \Illuminate\Database\Query\Builder $query
- *
- * @return void
*/
- protected function mergeQuery(Builder $query)
+ protected function mergeQuery(Builder $query): void
{
$properties = (new ReflectionClass(Builder::class))->getProperties();
@@ -77,10 +62,8 @@ protected function mergeQuery(Builder $query)
/**
* Apply the scopes to the eloquent builder instance and return it.
- *
- * @return static
*/
- public function applyScopes()
+ public function applyScopes(): static
{
$query = $this->eloquent->applyScopes();
@@ -91,10 +74,8 @@ public function applyScopes()
/**
* Returns a new query builder for the model's table.
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- public function newEloquentQuery()
+ public function newEloquentQuery(): Eloquent
{
return $this->model->registerGlobalScopes(
$this->newModelQuery()
@@ -103,30 +84,24 @@ public function newEloquentQuery()
/**
* Returns a new eloquent builder that doesn't have any global scopes or eager loading.
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- public function newModelQuery()
+ public function newModelQuery(): Eloquent
{
return $this->newEloquentBuilder()->setModel($this->model);
}
/**
* Returns a new eloquent builder for this join clause.
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- public function newEloquentBuilder()
+ public function newEloquentBuilder(): Eloquent
{
return new Eloquent($this);
}
/**
* Get a new instance of the join clause builder.
- *
- * @return \Illuminate\Database\Query\JoinClause
*/
- public function newQuery()
+ public function newQuery(): JoinClause
{
return new JoinClause($this->newParentQuery(), $this->type, $this->table);
}
@@ -134,11 +109,8 @@ public function newQuery()
/**
* Handle dynamic method calls into the method.
*
- * @phpcs:disable Squiz.Commenting.FunctionComment
- *
* @param string $method
- * @param array $parameters
- *
+ * @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
diff --git a/src/LaravelRelationJoinServiceProvider.php b/src/LaravelRelationJoinServiceProvider.php
index 51dc402..135251a 100644
--- a/src/LaravelRelationJoinServiceProvider.php
+++ b/src/LaravelRelationJoinServiceProvider.php
@@ -11,10 +11,8 @@ class LaravelRelationJoinServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
- *
- * @return void
*/
- public function boot()
+ public function boot(): void
{
Query::mixin(new Mixins\MergeJoins);
Query::mixin(new Mixins\JoinOperations);
diff --git a/src/Mixins/JoinOperations.php b/src/Mixins/JoinOperations.php
index c193e89..fd815ed 100644
--- a/src/Mixins/JoinOperations.php
+++ b/src/Mixins/JoinOperations.php
@@ -3,54 +3,44 @@
namespace Reedware\LaravelRelationJoins\Mixins;
use Closure;
+use Illuminate\Database\Query\Builder;
+/** @mixin Builder */
class JoinOperations
{
/**
* Defines the mixin for {@see $query->on()}.
- *
- * @return \Closure
*/
- public function on()
+ public function on(): Closure
{
/**
* Add an "on" clause to the join.
- *
- * @param \Closure|string $first
- * @param string|null $operator
- * @param string|null $second
- * @param string $boolean
- *
- * @return $this
*/
- return function ($first, $operator = null, $second = null, $boolean = 'and') {
-
+ return function (
+ Closure|string $first,
+ string $operator = null,
+ string $second = null,
+ string $boolean = 'and'
+ ): Builder {
+ /** @var Builder $this */
if ($first instanceof Closure) {
return $this->whereNested($first, $boolean);
}
return $this->whereColumn($first, $operator, $second, $boolean);
-
};
}
/**
* Defines the mixin for {@see $query->orOn()}.
- *
- * @return \Closure
*/
- public function orOn()
+ public function orOn(): Closure
{
/**
* Add an "or on" clause to the join.
- *
- * @param \Closure|string $first
- * @param string|null $operator
- * @param string|null $second
- *
- * @return $this
*/
- return function ($first, $operator = null, $second = null) {
+ return function (Closure|string $first, string $operator = null, string $second = null): Builder {
+ /** @var Builder $this */
return $this->on($first, $operator, $second, 'or');
};
}
diff --git a/src/Mixins/JoinsRelationships.php b/src/Mixins/JoinsRelationships.php
index 12fdb89..c980ca9 100644
--- a/src/Mixins/JoinsRelationships.php
+++ b/src/Mixins/JoinsRelationships.php
@@ -3,39 +3,42 @@
namespace Reedware\LaravelRelationJoins\Mixins;
use Closure;
-use Illuminate\Support\Arr;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
+use Illuminate\Database\Query\Builder as Query;
use Illuminate\Database\Query\JoinClause;
+use Illuminate\Support\Arr;
use LogicException;
use Reedware\LaravelRelationJoins\EloquentJoinClause;
use Reedware\LaravelRelationJoins\MorphTypes;
use RuntimeException;
+/** @mixin Builder */
class JoinsRelationships
{
/**
* Defines the mixin for {@see $query->joinRelation()}.
- *
- * @return \Closure
*/
- public function joinRelation()
+ public function joinRelation(): Closure
{
/**
* Add a relationship join condition to the query.
*
- * @param mixed $relation
- * @param \Closure|array|null $callback
- * @param string $type
- * @param bool $through
- * @param \Illuminate\Database\Eloquent\Builder $relatedQuery
- * @param mixed $morphTypes
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Relation|string|array $relation
+ * @param Closure|array|null $callback
+ * @param MorphTypes|array|string $morphTypes
*/
- return function ($relation, $callback = null, $type = 'inner', $through = false, Builder $relatedQuery = null, $morphTypes = ['*']) {
-
+ return function (
+ Relation|string|array $relation,
+ Closure|array $callback = null,
+ string $type = 'inner',
+ bool $through = false,
+ Builder $relatedQuery = null,
+ MorphTypes|array|string $morphTypes = ['*']
+ ): Builder {
+ /** @var Builder $this */
if (! $morphTypes instanceof MorphTypes) {
$morphTypes = new MorphTypes($morphTypes);
}
@@ -54,11 +57,13 @@ public function joinRelation()
$relation = ($relatedQuery ?: $this)->getRelationWithoutConstraints($relationName);
if (! $relation instanceof Relation) {
- throw new LogicException(sprintf('%s::%s must return a relationship instance.', get_class($this->getModel()), $relationName));
+ throw new LogicException(sprintf(
+ '%s::%s must return a relationship instance.',
+ get_class($this->getModel()),
+ $relationName)
+ );
}
- }
-
- else if (is_array($relation)) {
+ } elseif (is_array($relation)) {
[$relation, $alias] = $relation;
}
@@ -104,24 +109,22 @@ public function joinRelation()
/**
* Defines the mixin for {@see $query->joinNestedRelation()}.
- *
- * @return \Closure
*/
- protected function joinNestedRelation()
+ public function joinNestedRelation(): Closure
{
/**
* Add nested relationship join conditions to the query.
*
- * @param string $relations
- * @param \Closure|array|null $callbacks
- * @param string $type
- * @param bool $through
- * @param \Reedware\LaravelRelationJoins\MorphTypes $morphTypes
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callbacks
*/
- return function ($relations, $callbacks, $type, $through, MorphTypes $morphTypes) {
-
+ return function (
+ string $relations,
+ Closure|array|null $callbacks,
+ string $type,
+ bool $through,
+ MorphTypes $morphTypes
+ ): Builder {
+ /** @var Builder $this */
$relations = explode('.', $relations);
$relatedQuery = $this;
@@ -139,30 +142,30 @@ protected function joinNestedRelation()
$callback = $callbacks[$relation] ?? null;
$useThrough = count($relations) > 0 && $through;
- $relatedQuery = $this->joinRelation($relation, $callback, $type, $useThrough, $relatedQuery, $morphTypes);
+ $relatedQuery = $this->joinRelation(
+ $relation,
+ $callback,
+ $type,
+ $useThrough,
+ $relatedQuery,
+ $morphTypes
+ );
}
return $this;
-
};
}
/**
* Defines the mixin for {@see $query->applyJoinScopes()}.
- *
- * @return \Closure
*/
- protected function applyJoinScopes()
+ public function applyJoinScopes(): Closure
{
/**
* Applies the eloquent scopes to the specified query.
- *
- * @param \Illuminate\Database\Query\Builder $joinQuery
- *
- * @return \Illuminate\Database\Query\Builder
*/
- return function (Builder $joinQuery) {
-
+ return function (Builder $joinQuery): Builder {
+ /** @var Builder $this */
$joins = $joinQuery->getQuery()->joins ?: [];
foreach ($joins as $join) {
@@ -172,27 +175,19 @@ protected function applyJoinScopes()
}
return $joinQuery;
-
};
}
/**
* Defines the mixin for {@see $query->callJoinScope()}.
- *
- * @return \Closure
*/
- protected function callJoinScope()
+ public function callJoinScope(): Closure
{
/**
* Calls the provided callback on the join query.
- *
- * @param \Illuminate\Database\Query\Builder $joinQuery
- * @param \Closure $callback
- *
- * @return void
*/
- return function (Builder $joinQuery, Closure $callback) {
-
+ return function (Builder $joinQuery, Closure $callback): void {
+ /** @var Builder $this */
$joins = $joinQuery->getQuery()->joins ?: [];
array_unshift($joins, $joinQuery);
@@ -230,23 +225,19 @@ protected function callJoinScope()
foreach ($queries as $query) {
$joinQuery->addBinding($query->getBindings(), 'join');
}
-
};
}
/**
* Defines the mixin for {@see $query->getJoinType()}.
- *
- * @return \Closure
*/
- protected function getJoinType()
+ public function getJoinType(): Closure
{
/**
* Returns the custom provided join type.
- *
- * @return string|null
*/
- return function () {
+ return function (): ?string {
+ /** @var Builder $this */
if (! property_exists($this, 'type')) {
return null;
}
@@ -265,7 +256,7 @@ protected function getJoinType()
// @codeCoverageIgnoreStart
finally {
- // @codeCoverageIgnoreEnd
+ // @codeCoverageIgnoreEnd
return $type;
}
};
@@ -273,22 +264,14 @@ protected function getJoinType()
/**
* Defines the mixin for {@see $query->addJoinRelationWhere()}.
- *
- * @return \Closure
*/
- protected function addJoinRelationWhere()
+ public function addJoinRelationWhere(): Closure
{
/**
* Add the "join relation" condition where clause to the query.
- *
- * @param \Illuminate\Database\Eloquent\Builder $joinQuery
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param string $type
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
*/
- return function (Builder $joinQuery, Relation $relation, $type) {
-
+ return function (Builder $joinQuery, Relation $relation, string $type): Builder {
+ /** @var Builder $this */
$joinQuery->mergeConstraintsFrom($relation->getQuery());
$baseJoinQuery = $joinQuery->toBase();
@@ -310,79 +293,31 @@ protected function addJoinRelationWhere()
}, null, null, $type);
return $this;
-
- };
- }
-
- /**
- * Defines the mixin for {@see $query->replaceWhereNestedQueryBuildersWithJoinBuilders()}.
- *
- * @return \Closure
- */
- protected function replaceWhereNestedQueryBuildersWithJoinBuilders()
- {
- /**
- * Replaces the query builders in nested "where" clauses with join builders.
- *
- * @param \Illuminate\Database\Query\Builder $query
- *
- * @return void
- */
- return function ($query) {
-
- $wheres = $query->wheres;
-
- $wheres = array_map(function ($where) {
- if (! isset($where['query'])) {
- return $where;
- }
-
- if ($where['type'] == 'Exists' || $where['type'] == 'NotExists') {
- return $where;
- }
-
- $this->replaceWhereNestedQueryBuildersWithJoinBuilders($where['query']);
-
- $joinClause = new JoinClause($where['query'], 'inner', $where['query']->from);
-
- foreach (array_keys(get_object_vars($where['query'])) as $key) {
- $joinClause->{$key} = $where['query']->{$key};
- }
-
- $where['query'] = $joinClause;
-
- return $where;
- }, $wheres);
-
- $query->wheres = $wheres;
-
};
}
/**
* Defines the mixin for {@see $query->getBelongsToJoinRelation()}.
- *
- * @return \Closure
*/
- protected function getBelongsToJoinRelation()
+ public function getBelongsToJoinRelation(): Closure
{
/**
- * Description.
- *
- * @param \Illuminate\Database\Eloquent\Relations\MorphTo $relation
- * @param \Reedware\LaravelRelationJoins\MorphTypes $morphTypes
- * @param \Illuminate\Database\Eloquent\Builder $relatedQuery
- *
- * @return array
+ * Returns the belongs to relation for the next morph.
*/
- return function (MorphTo $relation, MorphTypes $morphTypes, Builder $relatedQuery) {
+ return function (MorphTo $relation, MorphTypes $morphTypes, Builder $relatedQuery): BelongsTo {
+ /** @var Builder $this */
// When it comes to joining across morph types, we can really only support
// a single type. However, when we're provided multiple types, we will
// instead use these one at a time and pass the information along.
if ($morphTypes->items === ['*']) {
- $types = $relatedQuery->model->distinct()->pluck($relation->getMorphType())->filter()->all();
+ $types = $relatedQuery->model
+ ->newQuery()
+ ->distinct()
+ ->pluck($relation->getMorphType())
+ ->filter()
+ ->all();
$types = array_unique(array_map(function ($morphType) {
return Relation::getMorphedModel($morphType) ?? $morphType;
@@ -410,325 +345,300 @@ protected function getBelongsToJoinRelation()
);
return $belongsTo;
-
};
}
/**
* Defines the mixin for {@see $query->leftJoinRelation()}.
- *
- * @return \Closure
*/
- public function leftJoinRelation()
+ public function leftJoinRelation(): Closure
{
/**
* Add a relationship left join condition to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- * @param bool $through
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null, $through = false) {
+ return function (string $relation, Closure|array $callback = null, bool $through = false): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'left', $through);
};
}
/**
* Defines the mixin for {@see $query->rightJoinRelation()}.
- *
- * @return \Closure
*/
- public function rightJoinRelation()
+ public function rightJoinRelation(): Closure
{
/**
* Add a relationship right join condition to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- * @param bool $through
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null, $through = false) {
+ return function (string $relation, Closure|array $callback = null, bool $through = false): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'right', $through);
};
}
/**
* Defines the mixin for {@see $query->crossJoinRelation()}.
- *
- * @return \Closure
*/
- public function crossJoinRelation()
+ public function crossJoinRelation(): Closure
{
/**
* Add a relationship cross join condition to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- * @param bool $through
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null, $through = false) {
+ return function (string $relation, Closure|array $callback = null, bool $through = false): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'cross', $through);
};
}
/**
* Defines the mixin for {@see $query->joinThroughRelation()}.
- *
- * @return \Closure
*/
- public function joinThroughRelation()
+ public function joinThroughRelation(): Closure
{
/**
* Add a relationship join condition through a related model to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- * @param string $type
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null, $type = 'inner') {
+ return function (string $relation, Closure|array $callback = null, string $type = 'inner'): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, $type, true);
};
}
/**
* Defines the mixin for {@see $query->leftJoinThroughRelation()}.
- *
- * @return \Closure
*/
- public function leftJoinThroughRelation()
+ public function leftJoinThroughRelation(): Closure
{
/**
* Add a relationship left join condition through a related model to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null) {
+ return function (string $relation, Closure|array $callback = null): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'left', true);
};
}
/**
* Defines the mixin for {@see $query->rightJoinThroughRelation()}.
- *
- * @return \Closure
*/
- public function rightJoinThroughRelation()
+ public function rightJoinThroughRelation(): Closure
{
/**
* Add a relationship right join condition through a related model to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null) {
+ return function (string $relation, Closure|array $callback = null): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'right', true);
};
}
/**
* Defines the mixin for {@see $query->crossJoinThroughRelation()}.
- *
- * @return \Closure
*/
- public function crossJoinThroughRelation()
+ public function crossJoinThroughRelation(): Closure
{
/**
* Add a relationship cross join condition through a related model to the query.
*
- * @param string $relation
- * @param \Closure|array|null $callback
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param Closure|array|null $callback
*/
- return function ($relation, $callback = null) {
+ return function (string $relation, Closure|array $callback = null): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'cross', true);
};
}
/**
* Defines the mixin for {@see $query->joinMorphRelation()}.
- *
- * @return \Closure
*/
- public function joinMorphRelation()
+ public function joinMorphRelation(): Closure
{
/**
* Add a morph to relationship join condition to the query.
*
- * @param string|array $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- * @param string $type
- * @param bool $through
- * @param \Illuminate\Database\Eloquent\Builder $relatedQuery
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null, $type = 'inner', $through = false, Builder $relatedQuery = null) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null,
+ string $type = 'inner',
+ bool $through = false,
+ Builder $relatedQuery = null
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, $type, $through, $relatedQuery, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->leftJoinMorphRelation()}.
- *
- * @return \Closure
*/
- public function leftJoinMorphRelation()
+ public function leftJoinMorphRelation(): Closure
{
/**
* Add a morph to relationship left join condition to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- * @param bool $through
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null, $through = false) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null,
+ bool $through = false
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'left', $through, null, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->rightJoinMorphRelation()}.
- *
- * @return \Closure
*/
- public function rightJoinMorphRelation()
+ public function rightJoinMorphRelation(): Closure
{
/**
* Add a morph to relationship right join condition to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- * @param bool $through
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null, $through = false) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null,
+ bool $through = false
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'right', $through, null, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->crossJoinMorphRelation()}.
- *
- * @return \Closure
*/
- public function crossJoinMorphRelation()
+ public function crossJoinMorphRelation(): Closure
{
/**
* Add a morph to relationship cross join condition to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- * @param bool $through
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null, $through = false) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null,
+ bool $through = false
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'cross', $through, null, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->joinThroughMorphRelation()}.
- *
- * @return \Closure
*/
- public function joinThroughMorphRelation()
+ public function joinThroughMorphRelation(): Closure
{
/**
* Add a morph to relationship join condition through a related model to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- * @param string $type
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null, $type = 'inner') {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null,
+ string $type = 'inner'
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, $type, true, null, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->leftJoinThroughMorphRelation()}.
- *
- * @return \Closure
*/
- public function leftJoinThroughMorphRelation()
+ public function leftJoinThroughMorphRelation(): Closure
{
/**
* Add a morph to relationship left join condition through a related model to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'left', true, null, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->rightJoinThroughMorphRelation()}.
- *
- * @return \Closure
*/
- public function rightJoinThroughMorphRelation()
+ public function rightJoinThroughMorphRelation(): Closure
{
/**
* Add a morph to relationship right join condition through a related model to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'right', true, null, $morphTypes);
};
}
/**
* Defines the mixin for {@see $query->crossJoinThroughMorphRelation()}.
- *
- * @return \Closure
*/
- public function crossJoinThroughMorphRelation()
+ public function crossJoinThroughMorphRelation(): Closure
{
/**
* Add a morph to relationship cross join condition through a related model to the query.
*
- * @param string $relation
- * @param string|array $morphTypes
- * @param \Closure|array|null $callback
- *
- * @return \Illuminate\Database\Eloquent\Builder|static
+ * @param string|array $relation
+ * @param array|string $morphTypes
+ * @param Closure|array|null $callback
*/
- return function ($relation, $morphTypes = ['*'], $callback = null) {
+ return function (
+ string|array $relation,
+ array|string $morphTypes = ['*'],
+ Closure|array $callback = null
+ ): Builder {
+ /** @var Builder $this */
return $this->joinRelation($relation, $callback, 'cross', true, null, $morphTypes);
};
}
diff --git a/src/Mixins/MergeJoins.php b/src/Mixins/MergeJoins.php
index de8458f..7ae6e2f 100644
--- a/src/Mixins/MergeJoins.php
+++ b/src/Mixins/MergeJoins.php
@@ -2,24 +2,23 @@
namespace Reedware\LaravelRelationJoins\Mixins;
+use Closure;
+use Illuminate\Database\Query\Builder;
+use Illuminate\Database\Query\JoinClause;
+
+/** @mixin Builder */
class MergeJoins
{
/**
* Defines the mixin for {@see $query->mergeJoins()}.
- *
- * @return \Closure
*/
- public function mergeJoins()
+ public function mergeJoins(): Closure
{
/**
* Merges an array of join clauses and bindings.
- *
- * @param array $joins
- * @param array $bindings
- *
- * @return void
*/
- return function ($joins, $bindings) {
+ return function (array $joins, array $bindings): void {
+ /** @var Builder $this */
$this->joins = array_merge($this->joins ?: [], (array) $joins);
$this->bindings['join'] = array_values(
@@ -27,4 +26,42 @@ public function mergeJoins()
);
};
}
+
+ /**
+ * Defines the mixin for {@see $query->replaceWhereNestedQueryBuildersWithJoinBuilders()}.
+ */
+ public function replaceWhereNestedQueryBuildersWithJoinBuilders(): Closure
+ {
+ /**
+ * Replaces the query builders in nested "where" clauses with join builders.
+ */
+ return function (Builder $query): void {
+ /** @var Builder $this */
+ $wheres = $query->wheres;
+
+ $wheres = array_map(function ($where) {
+ if (! isset($where['query'])) {
+ return $where;
+ }
+
+ if ($where['type'] == 'Exists' || $where['type'] == 'NotExists') {
+ return $where;
+ }
+
+ $this->replaceWhereNestedQueryBuildersWithJoinBuilders($where['query']);
+
+ $joinClause = new JoinClause($where['query'], 'inner', $where['query']->from);
+
+ foreach (array_keys(get_object_vars($where['query'])) as $key) {
+ $joinClause->{$key} = $where['query']->{$key};
+ }
+
+ $where['query'] = $joinClause;
+
+ return $where;
+ }, $wheres);
+
+ $query->wheres = $wheres;
+ };
+ }
}
diff --git a/src/Mixins/RelationJoinQueries.php b/src/Mixins/RelationJoinQueries.php
index 69c2738..bb7b77a 100644
--- a/src/Mixins/RelationJoinQueries.php
+++ b/src/Mixins/RelationJoinQueries.php
@@ -2,29 +2,24 @@
namespace Reedware\LaravelRelationJoins\Mixins;
+use Closure;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Relations\Relation;
use Reedware\LaravelRelationJoins\RelationJoinQuery;
+/** @mixin Relation */
class RelationJoinQueries
{
/**
* Defines the mixin for {@see $relation->getRelationJoinQuery()}.
- *
- * @return \Closure
*/
- public function getRelationJoinQuery()
+ public function getRelationJoinQuery(): Closure
{
/**
* Adds the constraints for a relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- return function (Builder $query, Builder $parentQuery, $type = 'inner', $alias = null) {
+ return function (Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null): Builder {
+ /** @var Relation $this */
return RelationJoinQuery::get($this, $query, $parentQuery, $type, $alias);
};
}
diff --git a/src/MorphTypes.php b/src/MorphTypes.php
index a75a847..a949e8d 100644
--- a/src/MorphTypes.php
+++ b/src/MorphTypes.php
@@ -7,16 +7,14 @@ class MorphTypes
/**
* The underlying morph types.
*
- * @var array
+ * @var array
*/
- public $items;
+ public array $items;
/**
* Creates a new morph types instance.
*
- * @param string|array $items
- *
- * @return $this;
+ * @param string|array $items
*/
public function __construct($items)
{
diff --git a/src/RelationJoinQuery.php b/src/RelationJoinQuery.php
index dfcd536..2999c6d 100644
--- a/src/RelationJoinQuery.php
+++ b/src/RelationJoinQuery.php
@@ -20,97 +20,74 @@ class RelationJoinQuery
{
/**
* Adds the constraints for a relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- public static function get(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ public static function get(
+ Relation $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if ($relation instanceof BelongsTo) {
return static::belongsTo($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof MorphToMany) {
+ } elseif ($relation instanceof MorphToMany) {
return static::morphToMany($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof BelongsToMany) {
+ } elseif ($relation instanceof BelongsToMany) {
return static::belongsToMany($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof HasMany) {
+ } elseif ($relation instanceof HasMany) {
return static::hasOneOrMany($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof HasOneThrough) {
+ } elseif ($relation instanceof HasOneThrough) {
return static::hasOneOrManyThrough($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof HasManyThrough) {
+ } elseif ($relation instanceof HasManyThrough) {
return static::hasOneOrManyThrough($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof HasOne) {
+ } elseif ($relation instanceof HasOne) {
return static::hasOneOrMany($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof MorphMany) {
+ } elseif ($relation instanceof MorphMany) {
return static::morphOneOrMany($relation, $query, $parentQuery, $type, $alias);
- }
-
- else if ($relation instanceof MorphOne) {
+ } elseif ($relation instanceof MorphOne) {
return static::morphOneOrMany($relation, $query, $parentQuery, $type, $alias);
}
- throw new InvalidArgumentException('Unsupported relation type [' . get_class($relation) . '].');
+ throw new InvalidArgumentException('Unsupported relation type ['.get_class($relation).'].');
}
/**
* Adds the constraints for a belongs to relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- protected static function belongsTo(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ protected static function belongsTo(
+ BelongsTo $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if (is_null($alias) && $query->getQuery()->from == $parentQuery->getQuery()->from) {
$alias = $relation->getRelationCountHash();
}
if (! is_null($alias) && $alias != $query->getModel()->getTable()) {
- $query->from($query->getModel()->getTable() . ' as ' . $alias);
+ $query->from($query->getModel()->getTable().' as '.$alias);
$query->getModel()->setTable($alias);
}
- return $query->whereColumn(
+ $query->whereColumn(
$relation->getQualifiedOwnerKeyName(), '=', $relation->getQualifiedForeignKeyName()
);
+
+ return $query;
}
/**
* Adds the constraints for a belongs to many relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- protected static function belongsToMany(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ protected static function belongsToMany(
+ BelongsToMany $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if (! is_null($alias) && strpos($alias, ',') !== false) {
[$pivotAlias, $farAlias] = explode(',', $alias);
} else {
@@ -122,13 +99,13 @@ protected static function belongsToMany(Relation $relation, Builder $query, Buil
}
if (! is_null($farAlias) && $farAlias != $relation->getRelated()->getTable()) {
- $query->from($relation->getRelated()->getTable() . ' as ' . $farAlias);
+ $query->from($relation->getRelated()->getTable().' as '.$farAlias);
$relation->getRelated()->setTable($farAlias);
}
if (! is_null($pivotAlias) && $pivotAlias != $relation->getTable()) {
- $table = $relation->getTable() . ' as ' . $pivotAlias;
+ $table = $relation->getTable().' as '.$pivotAlias;
$on = $pivotAlias;
} else {
@@ -136,7 +113,7 @@ protected static function belongsToMany(Relation $relation, Builder $query, Buil
}
$query->join($table, function ($join) use ($relation, $on) {
- $join->on($on . '.' . $relation->getForeignPivotKeyName(), '=', $relation->getQualifiedParentKeyName());
+ $join->on($on.'.'.$relation->getForeignPivotKeyName(), '=', $relation->getQualifiedParentKeyName());
}, null, null, $type);
// When a belongs to many relation uses an eloquent model to define the pivot
@@ -150,37 +127,40 @@ protected static function belongsToMany(Relation $relation, Builder $query, Buil
);
}
- return $query->whereColumn(
- $relation->getRelated()->qualifyColumn($relation->getRelatedKeyName()), '=', $on . '.' . $relation->getRelatedPivotKeyName()
+ $query->whereColumn(
+ $relation->getRelated()->qualifyColumn($relation->getRelatedKeyName()),
+ '=',
+ $on.'.'.$relation->getRelatedPivotKeyName()
);
+
+ return $query;
}
/**
* Adds the constraints for a has one or has many relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- protected static function hasOneOrMany(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ protected static function hasOneOrMany(
+ HasOne|HasMany|MorphOne|MorphMany $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if (is_null($alias) && $query->getQuery()->from == $parentQuery->getQuery()->from) {
$alias = $relation->getRelationCountHash();
}
if (! is_null($alias) && $alias != $query->getModel()->getTable()) {
- $query->from($query->getModel()->getTable() . ' as ' . $alias);
+ $query->from($query->getModel()->getTable().' as '.$alias);
$query->getModel()->setTable($alias);
}
- return $query->whereColumn(
+ $query->whereColumn(
$query->qualifyColumn($relation->getForeignKeyName()), '=', $relation->getQualifiedParentKeyName()
);
+
+ return $query;
}
/**
@@ -191,17 +171,14 @@ protected static function hasOneOrMany(Relation $relation, Builder $query, Build
* is nearing EoL, and 7.x is already EoL, we'll let it slide for now.
*
* @see https://github.com/laravel/framework/commit/de4c42f04d609b119a4e0a7e6223c37bfe54cb87
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- protected static function hasOneOrManyThrough(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ protected static function hasOneOrManyThrough(
+ HasOne|HasManyThrough $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if (! is_null($alias) && strpos($alias, ',') !== false) {
[$throughAlias, $farAlias] = explode(',', $alias);
} else {
@@ -217,13 +194,13 @@ protected static function hasOneOrManyThrough(Relation $relation, Builder $query
}
if (! is_null($farAlias) && $farAlias != $query->getModel()->getTable()) {
- $query->from($query->getModel()->getTable() . ' as ' . $farAlias);
+ $query->from($query->getModel()->getTable().' as '.$farAlias);
$query->getModel()->setTable($farAlias);
}
if (! is_null($throughAlias) && $throughAlias != $relation->getParent()->getTable()) {
- $table = $relation->getParent()->getTable() . ' as ' . $throughAlias;
+ $table = $relation->getParent()->getTable().' as '.$throughAlias;
$on = $throughAlias;
} else {
@@ -231,7 +208,11 @@ protected static function hasOneOrManyThrough(Relation $relation, Builder $query
}
$query->join($table, function ($join) use ($relation, $parentQuery, $on) {
- $join->on($on . '.' . $relation->getFirstKeyName(), '=', $parentQuery->qualifyColumn($relation->getLocalKeyName()));
+ $join->on(
+ $on.'.'.$relation->getFirstKeyName(),
+ '=',
+ $parentQuery->qualifyColumn($relation->getLocalKeyName())
+ );
}, null, null, $type);
// The has one/many through relations use an eloquent model to define the step
@@ -243,26 +224,25 @@ protected static function hasOneOrManyThrough(Relation $relation, Builder $query
$relation->getParent()->newInstance()->setTable($on)
);
- return $query->whereColumn(
- $relation->getQualifiedForeignKeyName(), '=', $on . '.' . $relation->getSecondLocalKeyName()
+ $query->whereColumn(
+ $relation->getQualifiedForeignKeyName(), '=', $on.'.'.$relation->getSecondLocalKeyName()
);
+
+ return $query;
}
/**
* Adds the constraints for a morph one or morph many relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- protected static function morphOneOrMany(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ protected static function morphOneOrMany(
+ MorphOne|MorphMany $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if (! is_null($alias) && $alias != $relation->getRelated()->getTable()) {
- $query->from($relation->getRelated()->getTable() . ' as ' . $alias);
+ $query->from($relation->getRelated()->getTable().' as '.$alias);
$relation->getRelated()->setTable($alias);
}
@@ -274,17 +254,14 @@ protected static function morphOneOrMany(Relation $relation, Builder $query, Bui
/**
* Adds the constraints for a morph to many relationship join.
- *
- * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
- * @param \Illuminate\Database\Eloquent\Builder $query
- * @param \Illuminate\Database\Eloquent\Builder $parentQuery
- * @param string $type
- * @param string|null $alias
- *
- * @return \Illuminate\Database\Eloquent\Builder
*/
- protected static function morphToMany(Relation $relation, Builder $query, Builder $parentQuery, string $type = 'inner', string $alias = null)
- {
+ protected static function morphToMany(
+ MorphToMany $relation,
+ Builder $query,
+ Builder $parentQuery,
+ string $type = 'inner',
+ string $alias = null
+ ): Builder {
if (! is_null($alias) && strpos($alias, ',') !== false) {
[$pivotAlias, $farAlias] = explode(',', $alias);
} else {
@@ -296,25 +273,23 @@ protected static function morphToMany(Relation $relation, Builder $query, Builde
}
if (! is_null($farAlias) && $farAlias != $relation->getRelated()->getTable()) {
- $query->from($relation->getRelated()->getTable() . ' as ' . $farAlias);
+ $query->from($relation->getRelated()->getTable().' as '.$farAlias);
$relation->getRelated()->setTable($farAlias);
}
if (! is_null($pivotAlias) && $pivotAlias != $relation->getTable()) {
- $table = $relation->getTable() . ' as ' . $pivotAlias;
+ $table = $relation->getTable().' as '.$pivotAlias;
$on = $pivotAlias;
} else {
$table = $on = $relation->getTable();
}
- $query = $query ?: $relation->getQuery();
-
$query->join($table, function ($join) use ($relation, $on) {
- $join->on($on . '.' . $relation->getForeignPivotKeyName(), '=', $relation->getQualifiedParentKeyName());
+ $join->on($on.'.'.$relation->getForeignPivotKeyName(), '=', $relation->getQualifiedParentKeyName());
- $join->where($on . '.' . $relation->getMorphType(), '=', $relation->getMorphClass());
+ $join->where($on.'.'.$relation->getMorphType(), '=', $relation->getMorphClass());
}, null, null, $type);
// When a belongs to many relation uses an eloquent model to define the pivot
@@ -328,8 +303,12 @@ protected static function morphToMany(Relation $relation, Builder $query, Builde
);
}
- return $query->whereColumn(
- $relation->getRelated()->qualifyColumn($relation->getRelatedKeyName()), '=', $on . '.' . $relation->getRelatedPivotKeyName()
+ $query->whereColumn(
+ $relation->getRelated()->qualifyColumn($relation->getRelatedKeyName()),
+ '=',
+ $on.'.'.$relation->getRelatedPivotKeyName()
);
+
+ return $query;
}
}
diff --git a/stubs/EloquentBuilder.stub b/stubs/EloquentBuilder.stub
new file mode 100644
index 0000000..81edaba
--- /dev/null
+++ b/stubs/EloquentBuilder.stub
@@ -0,0 +1,39 @@
+joinRelation('posts', [
- function ($join) { $join->where('posts.active', '=', true); }
+ function ($join) {
+ $join->where('posts.active', '=', true);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ?', $builder->toSql());
@@ -63,14 +68,19 @@ function ($join) { $join->where('posts.active', '=', true); }
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_sequential(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments', [
- function ($join) { $join->where('posts.active', '=', true); },
- function ($join) { $join->where('comments.likes', '>=', 10); }
+ function ($join) {
+ $join->where('posts.active', '=', true);
+ },
+ function ($join) {
+ $join->where('comments.likes', '>=', 10);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ? inner join "comments" on "comments"."post_id" = "posts"."id" and "comments"."likes" >= ?', $builder->toSql());
@@ -80,14 +90,41 @@ function ($join) { $join->where('comments.likes', '>=', 10); }
/**
* @test
+ *
+ * @dataProvider queryDataProvider
+ */
+ public function multiconstraint_leftJoinRelation(Closure $query, string $builderClass)
+ {
+ $builder = $query(new EloquentUserModelStub)
+ ->leftJoinRelation('posts.comments', [
+ function ($join) {
+ $join->where('posts.active', '=', true);
+ },
+ function ($join) {
+ $join->where('comments.likes', '>=', 10);
+ },
+ ]);
+
+ $this->assertEquals('select * from "users" left join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ? left join "comments" on "comments"."post_id" = "posts"."id" and "comments"."likes" >= ?', $builder->toSql());
+ $this->assertEquals([true, 10], $builder->getBindings());
+ $this->assertEquals($builderClass, get_class($builder));
+ }
+
+ /**
+ * @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_associative(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments', [
- 'comments' => function ($join) { $join->where('comments.likes', '>=', 10); },
- 'posts' => function ($join) { $join->where('posts.active', '=', true); }
+ 'comments' => function ($join) {
+ $join->where('comments.likes', '>=', 10);
+ },
+ 'posts' => function ($join) {
+ $join->where('posts.active', '=', true);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ? inner join "comments" on "comments"."post_id" = "posts"."id" and "comments"."likes" >= ?', $builder->toSql());
@@ -97,14 +134,19 @@ public function multiconstraint_associative(Closure $query, string $builderClass
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_alias(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts as articles.comments as threads', [
- 'comments as threads' => function ($join) { $join->where('threads.likes', '>=', 10); },
- 'posts as articles' => function ($join) { $join->where('articles.active', '=', true); }
+ 'comments as threads' => function ($join) {
+ $join->where('threads.likes', '>=', 10);
+ },
+ 'posts as articles' => function ($join) {
+ $join->where('articles.active', '=', true);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" as "articles" on "articles"."user_id" = "users"."id" and "articles"."active" = ? inner join "comments" as "threads" on "threads"."post_id" = "articles"."id" and "threads"."likes" >= ?', $builder->toSql());
@@ -114,13 +156,16 @@ public function multiconstraint_alias(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_single_first(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments', [
- 'posts' => function ($join) { $join->where('posts.active', '=', true); }
+ 'posts' => function ($join) {
+ $join->where('posts.active', '=', true);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ? inner join "comments" on "comments"."post_id" = "posts"."id"', $builder->toSql());
@@ -130,13 +175,16 @@ public function multiconstraint_single_first(Closure $query, string $builderClas
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_single_last(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments', [
- 'comments' => function ($join) { $join->where('comments.likes', '>=', 10); }
+ 'comments' => function ($join) {
+ $join->where('comments.likes', '>=', 10);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" inner join "comments" on "comments"."post_id" = "posts"."id" and "comments"."likes" >= ?', $builder->toSql());
@@ -146,13 +194,16 @@ public function multiconstraint_single_last(Closure $query, string $builderClass
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_single_middle(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments.likes', [
- 'comments' => function ($join) { $join->where('comments.likes', '>=', 10); }
+ 'comments' => function ($join) {
+ $join->where('comments.likes', '>=', 10);
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" inner join "comments" on "comments"."post_id" = "posts"."id" and "comments"."likes" >= ? inner join "likes" on "likes"."comment_id" = "comments"."id"', $builder->toSql());
@@ -162,15 +213,20 @@ public function multiconstraint_single_middle(Closure $query, string $builderCla
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_skip_middle_sequential(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments.likes', [
- function ($join) { $join->where('posts.active', '=', true); },
+ function ($join) {
+ $join->where('posts.active', '=', true);
+ },
null,
- function ($join) { $join->where('likes.emoji', '=', 'thumbs-up'); }
+ function ($join) {
+ $join->where('likes.emoji', '=', 'thumbs-up');
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ? inner join "comments" on "comments"."post_id" = "posts"."id" inner join "likes" on "likes"."comment_id" = "comments"."id" and "likes"."emoji" = ?', $builder->toSql());
@@ -180,14 +236,19 @@ function ($join) { $join->where('likes.emoji', '=', 'thumbs-up'); }
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_skip_middle_associative(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments.likes', [
- 'posts' => function ($join) { $join->where('posts.active', '=', true); },
- 'likes' => function ($join) { $join->where('likes.emoji', '=', 'thumbs-up'); }
+ 'posts' => function ($join) {
+ $join->where('posts.active', '=', true);
+ },
+ 'likes' => function ($join) {
+ $join->where('likes.emoji', '=', 'thumbs-up');
+ },
]);
$this->assertEquals('select * from "users" inner join "posts" on "posts"."user_id" = "users"."id" and "posts"."active" = ? inner join "comments" on "comments"."post_id" = "posts"."id" inner join "likes" on "likes"."comment_id" = "comments"."id" and "likes"."emoji" = ?', $builder->toSql());
@@ -197,14 +258,19 @@ public function multiconstraint_skip_middle_associative(Closure $query, string $
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multiconstraint_mix_type(Closure $query, string $builderClass)
{
$builder = $query(new EloquentUserModelStub)
->joinRelation('posts.comments.likes', [
- 'posts' => function ($join) { $join->type = 'left'; },
- 'likes' => function ($join) { $join->type = 'right'; }
+ 'posts' => function ($join) {
+ $join->type = 'left';
+ },
+ 'likes' => function ($join) {
+ $join->type = 'right';
+ },
]);
$this->assertEquals('select * from "users" left join "posts" on "posts"."user_id" = "users"."id" inner join "comments" on "comments"."post_id" = "posts"."id" right join "likes" on "likes"."comment_id" = "comments"."id"', $builder->toSql());
diff --git a/tests/Unit/MorphManyTest.php b/tests/Unit/MorphManyTest.php
index 9c3188b..140494e 100644
--- a/tests/Unit/MorphManyTest.php
+++ b/tests/Unit/MorphManyTest.php
@@ -9,6 +9,7 @@ class MorphManyTest extends TestCase
{
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function basic(Closure $query, string $builderClass)
@@ -23,6 +24,7 @@ public function basic(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function alias(Closure $query, string $builderClass)
@@ -37,6 +39,7 @@ public function alias(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function leftJoin(Closure $query, string $builderClass)
diff --git a/tests/Unit/MorphOneTest.php b/tests/Unit/MorphOneTest.php
index bbd5bb7..1ba67ab 100644
--- a/tests/Unit/MorphOneTest.php
+++ b/tests/Unit/MorphOneTest.php
@@ -9,6 +9,7 @@ class MorphOneTest extends TestCase
{
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function basic(Closure $query, string $builderClass)
@@ -23,6 +24,7 @@ public function basic(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function alias_not_nested(Closure $query, string $builderClass)
@@ -37,6 +39,7 @@ public function alias_not_nested(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function alias_nested(Closure $query, string $builderClass)
@@ -51,6 +54,7 @@ public function alias_nested(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function leftJoin(Closure $query, string $builderClass)
diff --git a/tests/Unit/MorphToManyTest.php b/tests/Unit/MorphToManyTest.php
index e50378f..867e2a2 100644
--- a/tests/Unit/MorphToManyTest.php
+++ b/tests/Unit/MorphToManyTest.php
@@ -9,6 +9,7 @@ class MorphToManyTest extends TestCase
{
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function basic(Closure $query, string $builderClass)
@@ -23,6 +24,7 @@ public function basic(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function alias_far(Closure $query, string $builderClass)
@@ -37,6 +39,7 @@ public function alias_far(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function alias_pivot(Closure $query, string $builderClass)
@@ -51,6 +54,7 @@ public function alias_pivot(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function leftJoin(Closure $query, string $builderClass)
@@ -65,6 +69,7 @@ public function leftJoin(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function constraints(Closure $query, string $builderClass)
@@ -81,6 +86,7 @@ public function constraints(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function constraints_pivot(Closure $query, string $builderClass)
@@ -97,6 +103,7 @@ public function constraints_pivot(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function constraints_pivot_model(Closure $query, string $builderClass)
@@ -113,6 +120,7 @@ public function constraints_pivot_model(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function constraints_pivot_model_scope(Closure $query, string $builderClass)
@@ -129,6 +137,7 @@ public function constraints_pivot_model_scope(Closure $query, string $builderCla
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function constraints_pivot_model_softDeletes(Closure $query, string $builderClass)
@@ -143,6 +152,7 @@ public function constraints_pivot_model_softDeletes(Closure $query, string $buil
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function constraints_pivot_model_softDeletes_withTrashed(Closure $query, string $builderClass)
diff --git a/tests/Unit/MorphToTest.php b/tests/Unit/MorphToTest.php
index d86062c..2ebaf6a 100644
--- a/tests/Unit/MorphToTest.php
+++ b/tests/Unit/MorphToTest.php
@@ -3,7 +3,6 @@
namespace Reedware\LaravelRelationJoins\Tests\Unit;
use Closure;
-use Illuminate\Database\Eloquent\Model;
use Reedware\LaravelRelationJoins\Tests\Models\EloquentFileModelStub;
use Reedware\LaravelRelationJoins\Tests\Models\EloquentImageModelStub;
use Reedware\LaravelRelationJoins\Tests\Models\EloquentPostModelStub;
@@ -15,9 +14,6 @@ class MorphToTest extends TestCase
/**
* Mocks the specified select query.
*
- * @param string $sql
- * @param array $bindings
- * @param array $results
*
* @return void
*/
@@ -32,11 +28,6 @@ protected function mockSelect(string $sql, array $bindings, array $results)
/**
* Mocks the morph selection used by {@see $query->joinMorphRelation()}.
*
- * @param string $model
- * @param string $relation
- * @param array $results
- * @param string|null $where
- * @param array $bindings
*
* @return void
*/
@@ -47,7 +38,7 @@ protected function mockMorphSelect(string $model, string $relation, array $resul
$column = $model->{$relation}()->getMorphType();
$this->mockSelect(
- "select distinct \"{$column}\" from \"{$table}\"" . ($where ? ' where ' . $where : ''),
+ "select distinct \"{$column}\" from \"{$table}\"".($where ? ' where '.$where : ''),
$bindings,
array_map(function ($result) use ($column) {
return [$column => $result];
@@ -57,12 +48,13 @@ protected function mockMorphSelect(string $model, string $relation, array $resul
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function basic(Closure $query, string $builderClass)
{
$this->mockMorphSelect(EloquentImageModelStub::class, 'imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$builder = $query(new EloquentImageModelStub)
@@ -75,12 +67,13 @@ public function basic(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function basic_alias(Closure $query, string $builderClass)
{
$this->mockMorphSelect(EloquentImageModelStub::class, 'imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$builder = $query(new EloquentImageModelStub)
@@ -93,6 +86,7 @@ public function basic_alias(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function withMorphType(Closure $query, string $builderClass)
@@ -107,6 +101,7 @@ public function withMorphType(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function withMorphType_alias(Closure $query, string $builderClass)
@@ -121,6 +116,7 @@ public function withMorphType_alias(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function withMorphTypes(Closure $query, string $builderClass)
@@ -128,7 +124,7 @@ public function withMorphTypes(Closure $query, string $builderClass)
$builder = $query(new EloquentFileModelStub)
->joinMorphRelation('link.imageable', [
EloquentImageModelStub::class,
- EloquentUserModelStub::class
+ EloquentUserModelStub::class,
]);
$this->assertEquals('select * from "files" inner join "images" on "images"."id" = "files"."link_id" and "files"."link_type" = ? inner join "users" on "users"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
@@ -138,6 +134,7 @@ public function withMorphTypes(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function withMorphTypes_normal_in(Closure $query, string $builderClass)
@@ -145,7 +142,7 @@ public function withMorphTypes_normal_in(Closure $query, string $builderClass)
$builder = $query(new EloquentUserModelStub)
->joinMorphRelation('uploadedFiles.link.imageable', [
EloquentImageModelStub::class,
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "users" inner join "files" on "files"."uploaded_by_id" = "users"."id" inner join "images" on "images"."id" = "files"."link_id" and "files"."link_type" = ? inner join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
@@ -155,6 +152,7 @@ public function withMorphTypes_normal_in(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function withMorphTypes_normal_between(Closure $query, string $builderClass)
@@ -162,7 +160,7 @@ public function withMorphTypes_normal_between(Closure $query, string $builderCla
$builder = $query(new EloquentFileModelStub)
->joinMorphRelation('link.uploadedImages.imageable', [
EloquentUserModelStub::class,
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "files" inner join "users" on "users"."id" = "files"."link_id" and "files"."link_type" = ? inner join "images" on "images"."uploaded_by_id" = "users"."id" inner join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
@@ -172,6 +170,7 @@ public function withMorphTypes_normal_between(Closure $query, string $builderCla
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function asBelongsTo(Closure $query, string $builderClass)
@@ -186,6 +185,7 @@ public function asBelongsTo(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function multitype(Closure $query, string $builderClass)
@@ -204,12 +204,13 @@ public function multitype(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function nested_in(Closure $query, string $builderClass)
{
$this->mockMorphSelect(EloquentImageModelStub::class, 'imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$builder = $query(new EloquentUserModelStub)
@@ -222,13 +223,14 @@ public function nested_in(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function nested_out(Closure $query, string $builderClass)
{
$builder = $query(new EloquentImageModelStub)
->joinMorphRelation('imageable.comments', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "images" inner join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ? inner join "comments" on "comments"."post_id" = "posts"."id"', $builder->toSql());
@@ -238,6 +240,7 @@ public function nested_out(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function leftJoin(Closure $query, string $builderClass)
@@ -252,6 +255,7 @@ public function leftJoin(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function rightJoin(Closure $query, string $builderClass)
@@ -266,6 +270,7 @@ public function rightJoin(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function crossJoin(Closure $query, string $builderClass)
@@ -280,6 +285,7 @@ public function crossJoin(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function joinThrough_in(Closure $query, string $builderClass)
@@ -287,7 +293,7 @@ public function joinThrough_in(Closure $query, string $builderClass)
$builder = $query(new EloquentUserModelStub)
->joinRelation('uploadedImages')
->joinThroughMorphRelation('uploadedImages.imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "users" inner join "images" on "images"."uploaded_by_id" = "users"."id" inner join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
@@ -297,6 +303,7 @@ public function joinThrough_in(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function joinThrough_out(Closure $query, string $builderClass)
@@ -312,6 +319,7 @@ public function joinThrough_out(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function leftJoinThrough(Closure $query, string $builderClass)
@@ -319,7 +327,7 @@ public function leftJoinThrough(Closure $query, string $builderClass)
$builder = $query(new EloquentUserModelStub)
->joinRelation('uploadedImages')
->leftJoinThroughMorphRelation('uploadedImages.imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "users" inner join "images" on "images"."uploaded_by_id" = "users"."id" left join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
@@ -329,6 +337,7 @@ public function leftJoinThrough(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function rightJoinThrough(Closure $query, string $builderClass)
@@ -336,7 +345,7 @@ public function rightJoinThrough(Closure $query, string $builderClass)
$builder = $query(new EloquentUserModelStub)
->joinRelation('uploadedImages')
->rightJoinThroughMorphRelation('uploadedImages.imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "users" inner join "images" on "images"."uploaded_by_id" = "users"."id" right join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
@@ -346,6 +355,7 @@ public function rightJoinThrough(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function crossJoinThrough(Closure $query, string $builderClass)
@@ -353,7 +363,7 @@ public function crossJoinThrough(Closure $query, string $builderClass)
$builder = $query(new EloquentUserModelStub)
->joinRelation('uploadedImages')
->crossJoinThroughMorphRelation('uploadedImages.imageable', [
- EloquentPostModelStub::class
+ EloquentPostModelStub::class,
]);
$this->assertEquals('select * from "users" inner join "images" on "images"."uploaded_by_id" = "users"."id" cross join "posts" on "posts"."id" = "images"."imageable_id" and "images"."imageable_type" = ?', $builder->toSql());
diff --git a/tests/Unit/MorphedByManyTest.php b/tests/Unit/MorphedByManyTest.php
index 788a4b8..0c96ec7 100644
--- a/tests/Unit/MorphedByManyTest.php
+++ b/tests/Unit/MorphedByManyTest.php
@@ -10,6 +10,7 @@ class MorphedByManyTest extends TestCase
{
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function basic(Closure $query, string $builderClass)
@@ -24,6 +25,7 @@ public function basic(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function alias(Closure $query, string $builderClass)
@@ -38,6 +40,7 @@ public function alias(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function circular(Closure $query, string $builderClass)
@@ -52,6 +55,7 @@ public function circular(Closure $query, string $builderClass)
/**
* @test
+ *
* @dataProvider queryDataProvider
*/
public function leftJoin(Closure $query, string $builderClass)
diff --git a/tests/Unit/RelationJoinQueryTest.php b/tests/Unit/RelationJoinQueryTest.php
index 21ccb42..4a9b7ca 100644
--- a/tests/Unit/RelationJoinQueryTest.php
+++ b/tests/Unit/RelationJoinQueryTest.php
@@ -13,7 +13,7 @@ class RelationJoinQueryTest extends TestCase
public function nonRelation()
{
$this->expectException(LogicException::class);
- $this->expectExceptionMessage(EloquentUserModelStub::class . '::active must return a relationship instance.');
+ $this->expectExceptionMessage(EloquentUserModelStub::class.'::active must return a relationship instance.');
$builder = (new EloquentUserModelStub)
->useCustomBuilder(false)
@@ -24,7 +24,7 @@ public function nonRelation()
public function unsupportedRelation()
{
$this->expectException(InvalidArgumentException::class);
- $this->expectExceptionMessage('Unsupported relation type [' . CustomRelation::class . '].');
+ $this->expectExceptionMessage('Unsupported relation type ['.CustomRelation::class.'].');
$builder = (new EloquentUserModelStub)
->useCustomBuilder(false)
diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php
index c5f7aa0..2ad6616 100644
--- a/tests/Unit/TestCase.php
+++ b/tests/Unit/TestCase.php
@@ -26,8 +26,6 @@ class TestCase extends TestBase
/**
* Prepares the test for execution.
- *
- * @return void
*/
protected function setUp(): void
{
@@ -39,8 +37,6 @@ protected function setUp(): void
/**
* Mocks the connection resolver for testing.
- *
- * @return void
*/
protected function setUpConnectionResolver(): void
{
@@ -74,8 +70,6 @@ protected function setUpConnectionResolver(): void
/**
* Registers the package service provider.
- *
- * @return void
*/
protected function registerServiceProvider(): void
{
@@ -88,8 +82,6 @@ protected function registerServiceProvider(): void
/**
* Cleans up after the test has been exected.
- *
- * @return void
*/
protected function tearDown(): void
{
@@ -113,7 +105,7 @@ public function queryDataProvider()
return [
'Eloquent Builder' => [$newQuery, EloquentBuilder::class],
- 'Custom Builder' => [$customQuery, CustomBuilder::class]
+ 'Custom Builder' => [$customQuery, CustomBuilder::class],
];
}
}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 86f9239..bc39414 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -12,7 +12,7 @@
|
*/
-require __DIR__ . '/../vendor/autoload.php';
+require __DIR__.'/../vendor/autoload.php';
use Illuminate\Support\Carbon;