Skip to content

Commit

Permalink
work on 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
forxer committed Apr 1, 2024
1 parent 75eec7f commit ed8c972
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 129 deletions.
36 changes: 21 additions & 15 deletions rector.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
<?php

use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector;
use Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector;
use Rector\CodingStyle\Rector\Closure\StaticClosureRector;
use Rector\CodingStyle\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector;
use Rector\CodingStyle\Rector\PostInc\PostIncDecToPreIncDecRector;
use Rector\Config\RectorConfig;
use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector;
use Rector\Php81\Rector\FuncCall\NullToStrictStringFuncCallArgRector;
use Rector\Set\ValueObject\SetList;
use RectorLaravel\Rector\FuncCall\RemoveDumpDataDeadCodeRector;
Expand Down Expand Up @@ -55,25 +57,29 @@
// Ne pas changer les closure et Arrow Function en Static
StaticClosureRector::class,
StaticArrowFunctionRector::class,

// Particularités des classes mixins
CompleteDynamicPropertiesRector::class => [__DIR__.'/src/Eloquent/Mixins'],
RemoveExtraParametersRector::class => [__DIR__.'/src/Eloquent/Mixins'],
]);

// $rectorConfig->rules([
// EloquentWhereRelationTypeHintingParameterRector::class,
// EloquentWhereTypeHintClosureParameterRector::class,
// OptionalToNullsafeOperatorRector::class,
// RemoveDumpDataDeadCodeRector::class,
// ]);
$rectorConfig->rules([
EloquentWhereRelationTypeHintingParameterRector::class,
EloquentWhereTypeHintClosureParameterRector::class,
OptionalToNullsafeOperatorRector::class,
RemoveDumpDataDeadCodeRector::class,
]);

$rectorConfig->sets([
// LaravelSetList::LARAVEL_FACADE_ALIASES_TO_FULL_NAMES,
LaravelSetList::LARAVEL_FACADE_ALIASES_TO_FULL_NAMES,
SetList::PHP_82,
// SetList::DEAD_CODE,
// SetList::CODE_QUALITY,
// SetList::CODING_STYLE,
// //SetList::NAMING,
// SetList::TYPE_DECLARATION,
// //SetList::PRIVATIZATION,
// SetList::EARLY_RETURN,
// SetList::INSTANCEOF,
SetList::DEAD_CODE,
SetList::CODE_QUALITY,
SetList::CODING_STYLE,
//SetList::NAMING,
SetList::TYPE_DECLARATION,
//SetList::PRIVATIZATION,
SetList::EARLY_RETURN,
SetList::INSTANCEOF,
]);
};
18 changes: 4 additions & 14 deletions src/Eloquent/DefaultOrderScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@

class DefaultOrderScope implements Scope
{
/**
* @var array
*/
protected $orders;
protected array $orders;

/**
* Constructor.
Expand All @@ -24,10 +21,8 @@ public function __construct(array $orders)

/**
* Apply default "order by" clauses on query.
*
* @return void
*/
public function apply(Builder $builder, Model $model)
public function apply(Builder $builder, Model $model): void
{
if ($builder->getQuery()->orders) {
return;
Expand All @@ -36,22 +31,17 @@ public function apply(Builder $builder, Model $model)
foreach ($this->orders as $column => $option) {
if (\is_int($column)) {
$builder->orderBy($model->getTable().'.'.$option);

} elseif ($option === 'asc' || $option === 'desc') {
$builder->orderBy($model->getTable().'.'.$column, $option);

} elseif ($option === 'natural' || $option === 'natural_asc') {
$builder->orderByNatural($model->getTable().'.'.$column);

} elseif ($option === 'natural_desc') {
$builder->orderByNatural($model->getTable().'.'.$column, 'desc');

} elseif ($option === 'raw') {
$builder->orderByRaw($column);

} else {
throw new DefaultOrderException('Option "'.$option.'" not supported.');
}

throw new DefaultOrderException('Option "'.$option.'" not supported.');
}
}
}
12 changes: 4 additions & 8 deletions src/Eloquent/JoinRelBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ public function __construct(Model $model)
* @param Closure|null $callback
* @param string $type
* @param bool $withTrashed
* @return void
*/
public function apply(Builder $query, $relationName, $alias = null, $callback = null, $type = 'inner', $withTrashed = false)
public function apply(Builder $query, $relationName, $alias = null, $callback = null, $type = 'inner', $withTrashed = false): void
{
if (str_contains($relationName, '.')) {
[$parentAlias, $relationName] = explode('.', $relationName);
Expand Down Expand Up @@ -73,7 +72,7 @@ public function apply(Builder $query, $relationName, $alias = null, $callback =
$relation->getRelated()->setTable($alias);
$relation->getParent()->setTable($parentAlias);

$condition = function ($join) use ($relation, $callback, $withTrashed) {
$condition = function ($join) use ($relation, $callback, $withTrashed): void {
$this->addCondition($join, $relation, $callback, $withTrashed);
};

Expand Down Expand Up @@ -127,15 +126,12 @@ protected function addCondition(JoinClause $join, Relation $relation, $callback,

/**
* Adds extra "where" criteria to join clause.
*
* @param string $alias
* @return void
*/
protected function addExtraCriteria(JoinClause $join, array $wheres, $alias)
protected function addExtraCriteria(JoinClause $join, array $wheres, string $alias): void
{
foreach ($wheres as $where) {
if ($where['type'] === 'Nested') {
$join->where(function ($join) use ($where, $alias) {
$join->where(function (JoinClause $join) use ($where, $alias): void {
$this->addExtraCriteria($join, $where['query']->wheres, $alias);
});
} else {
Expand Down
7 changes: 5 additions & 2 deletions src/Eloquent/Mixins/JoinRelMixin.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Database\Eloquent\Builder;
use WeakMap;

/** @mixin Builder */
class JoinRelMixin
{
/**
Expand All @@ -17,7 +18,7 @@ class JoinRelMixin
*/
public function alias()
{
return function ($alias) {
return function (string $alias): Builder {
$this->model->setTable($alias);

return $this->from((new $this->model())->getTable().' as '.$alias);
Expand All @@ -30,11 +31,13 @@ public function alias()
* @param string $relationName
* @param string|null $alias
* @param Closure|null $callback
* @param string $type
* @param bool $withTrashed
* @return Builder
*/
public function joinRel()
{
return function ($relationName, $alias = null, $callback = null, $type = 'inner', $withTrashed = false) {
return function (string $relationName, ?string $alias = null, ?string $callback = null, string $type = 'inner', bool $withTrashed = false): Builder {
global $_joinRelBuildersWeakMap;

if (! isset($_joinRelBuildersWeakMap)) {
Expand Down
6 changes: 4 additions & 2 deletions src/Eloquent/Mixins/WhereHasInMixin.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

use Axn\Illuminate\Database\Eloquent\Exceptions\WhereHasInException;
use Closure;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
use Illuminate\Database\Eloquent\Relations\Relation;

/** @mixin Builder */
class WhereHasInMixin
{
/**
Expand All @@ -23,13 +25,13 @@ class WhereHasInMixin
*/
public function whereHasIn()
{
return function ($relationName, ?Closure $callback = null, $boolean = 'and', $not = false) {
return function ($relationName, ?Closure $callback = null, $boolean = 'and', $not = false): Builder {

$relation = Relation::noConstraints(fn () => $this->model->{$relationName}());

$relationSubQuery = $relation->getQuery();

if ($callback !== null) {
if ($callback instanceof Closure) {
$callback($relationSubQuery);
}

Expand Down
7 changes: 3 additions & 4 deletions src/Eloquent/SoftDeletes.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ trait SoftDeletes
* (these records will be retrieved even if they are trashed).
*
* @param int|array[int] $exceptId
* @return void
*/
public function scopeWithoutTrashedExcept(Builder $query, $exceptId = null)
public function scopeWithoutTrashedExcept(Builder $query, $exceptId = null): void
{
// Replaced :
// $query->where(function ($query) use ($exceptId) {
Expand All @@ -25,10 +24,10 @@ public function scopeWithoutTrashedExcept(Builder $query, $exceptId = null)
//
// If we do not do that, the builder loses his scopes...

$query->where(function () use ($query, $exceptId) {
$query->where(function () use ($query, $exceptId): void {
$query
->withoutTrashed()
->when($exceptId, function ($query, $exceptId) {
->when($exceptId, function ($query, $exceptId): void {
if (\is_array($exceptId)) {
$query->orWhereIn($this->getQualifiedKeyName(), $exceptId);
} else {
Expand Down
91 changes: 89 additions & 2 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,99 @@

namespace Axn\Illuminate\Database;

use Axn\Illuminate\Database\Eloquent\Mixins\JoinRelMixin;
use Axn\Illuminate\Database\Eloquent\Mixins\WhereHasInMixin;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
use Illuminate\Support\Str;

class ServiceProvider extends BaseServiceProvider
{
public function boot()
public function boot(): void
{
require __DIR__.'/macros.php';
$this->extendsQueryBuilder();
$this->extendsEloquentBuilder();
}

private function extendsQueryBuilder(): void
{
/**
* Natural sorting.
*
* @see http://kumaresan-drupal.blogspot.fr/2012/09/natural-sorting-in-mysql-or.html
*
* @param string $column
* @param string $direction
* @return QueryBuilder
*/
QueryBuilder::macro(
'orderByNatural',
function ($column, $direction = 'asc') {
$column = $this->grammar->wrap($column);
$direction = strtolower($direction) === 'asc' ? 'asc' : 'desc';

return $this->orderByRaw(
$column.' + 0 <> 0 '.($direction === 'asc' ? 'desc' : 'asc').', '
.sprintf('%s + 0 %s, ', $column, $direction)
.sprintf('length(%s) %s, ', $column, $direction)
.sprintf('%s %s', $column, $direction)
);
}
);

/**
* Natural sorting, descendant.
*
* @param string $column
* @return QueryBuilder
*/
QueryBuilder::macro(
'orderByNaturalDesc',
fn ($column) => $this->orderByNatural($column, 'desc')
);
}

private function extendsEloquentBuilder(): void
{
/**
* Searching models using a where like query.
*
* @see https://freek.dev/1182-searching-models-using-a-where-like-query-in-laravel
*
* @param string|array $attributes
* @param string $searchTerm
* @return EloquentBuilder
*/
EloquentBuilder::macro(
'whereLike',
function ($attributes, $searchTerm) {
$searchTerm = str_replace(' ', '%', $searchTerm);

$this->where(function (EloquentBuilder $query) use ($attributes, $searchTerm): void {
foreach (Arr::wrap($attributes) as $attribute) {
if (Str::contains($attribute, '.')) {
[$relationName, $relationAttribute] = explode('.', $attribute);

$query->orWhereHas($relationName, function (EloquentBuilder $query) use ($relationAttribute, $searchTerm): void {
$query->where($relationAttribute, 'like', '%'.$searchTerm.'%');
});
} else {
$query->orWhere($attribute, 'like', '%'.$searchTerm.'%');
}
}
});

return $this;
}
);

// Registering macros using mixin classes
// https://liamhammett.com/laravel-mixins-KEzjmLrx

EloquentBuilder::mixin(new JoinRelMixin());

EloquentBuilder::mixin(new WhereHasInMixin());
}
}
Loading

0 comments on commit ed8c972

Please sign in to comment.