scrnhq /
laravel-bakery
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | namespace Bakery\Traits; |
||||||
| 4 | |||||||
| 5 | use Bakery\Support\Arguments; |
||||||
| 6 | use Bakery\Eloquent\ModelSchema; |
||||||
| 7 | use Bakery\Support\TypeRegistry; |
||||||
| 8 | use Illuminate\Support\Facades\DB; |
||||||
| 9 | use Illuminate\Database\Connection; |
||||||
| 10 | use Illuminate\Database\Eloquent\Model; |
||||||
| 11 | use Illuminate\Database\Query\Grammars; |
||||||
| 12 | use Illuminate\Database\Eloquent\Builder; |
||||||
| 13 | |||||||
| 14 | /** |
||||||
| 15 | * @property ModelSchema $modelSchema |
||||||
| 16 | * @property TypeRegistry $registry |
||||||
| 17 | */ |
||||||
| 18 | trait SearchesQueries |
||||||
| 19 | { |
||||||
| 20 | /** |
||||||
| 21 | * Apply search on the query. |
||||||
| 22 | * |
||||||
| 23 | * @param \Illuminate\Database\Eloquent\Builder $query |
||||||
| 24 | * @param Arguments $args |
||||||
| 25 | * @return Builder |
||||||
| 26 | */ |
||||||
| 27 | protected function applySearch(Builder $query, Arguments $args) |
||||||
| 28 | { |
||||||
| 29 | // If the query is empty, we don't need to perform any search. |
||||||
| 30 | if (empty($args['query'])) { |
||||||
| 31 | return $query; |
||||||
| 32 | } |
||||||
| 33 | |||||||
| 34 | /** @var Connection $connection */ |
||||||
| 35 | $connection = DB::connection(); |
||||||
| 36 | |||||||
| 37 | $this->tsFields = []; |
||||||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||||
| 38 | |||||||
| 39 | $needle = $args['query']; |
||||||
| 40 | $fields = $args['fields']; |
||||||
| 41 | |||||||
| 42 | $relations = $this->modelSchema->getRelationFields(); |
||||||
| 43 | $qualifiedNeedle = preg_quote($needle); |
||||||
| 44 | |||||||
| 45 | foreach ($fields as $key => $value) { |
||||||
| 46 | $field = $this->modelSchema->getFieldByKey($key); |
||||||
| 47 | $accessor = $field->getAccessor(); |
||||||
| 48 | if ($relations->keys()->contains($key)) { |
||||||
| 49 | $this->applyRelationalSearch($query, $this->model, $accessor, $needle, $value->toArray()); |
||||||
|
0 ignored issues
–
show
It seems like
$needle can also be of type null; however, parameter $needle of Bakery\Traits\SearchesQu...applyRelationalSearch() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 50 | } else { |
||||||
| 51 | $this->tsFields[] = $this->model->getTable().'.'.$accessor; |
||||||
| 52 | } |
||||||
| 53 | } |
||||||
| 54 | |||||||
| 55 | if (empty($needle) || empty($this->tsFields)) { |
||||||
| 56 | return $query; |
||||||
| 57 | } |
||||||
| 58 | |||||||
| 59 | $grammar = $connection->getQueryGrammar(); |
||||||
| 60 | |||||||
| 61 | if ($grammar instanceof Grammars\PostgresGrammar) { |
||||||
| 62 | $dictionary = config('bakery.postgresDictionary'); |
||||||
| 63 | $fields = implode(', ', $this->tsFields); |
||||||
| 64 | $query->whereRaw("to_tsvector('${dictionary}', concat_ws(' ', ".$fields.")) @@ to_tsquery('${dictionary}', ?)", |
||||||
| 65 | ["'{$qualifiedNeedle}':*"]); |
||||||
| 66 | } |
||||||
| 67 | |||||||
| 68 | return $query; |
||||||
| 69 | } |
||||||
| 70 | |||||||
| 71 | /** |
||||||
| 72 | * Apply a relational search. |
||||||
| 73 | * |
||||||
| 74 | * @param \Illuminate\Database\Eloquent\Builder $query |
||||||
| 75 | * @param \Illuminate\Database\Eloquent\Model $model |
||||||
| 76 | * @param string $relation |
||||||
| 77 | * @param string $needle |
||||||
| 78 | * @param array $fields |
||||||
| 79 | */ |
||||||
| 80 | protected function applyRelationalSearch( |
||||||
| 81 | Builder $query, |
||||||
| 82 | Model $model, |
||||||
| 83 | string $relation, |
||||||
| 84 | string $needle, |
||||||
| 85 | array $fields |
||||||
| 86 | ) { |
||||||
| 87 | /** @var \Illuminate\Database\Eloquent\Relations\Relation $relation */ |
||||||
| 88 | $relation = $model->$relation(); |
||||||
| 89 | $related = $relation->getRelated(); |
||||||
| 90 | $this->joinRelation($query, $relation, 'left'); |
||||||
|
0 ignored issues
–
show
It seems like
joinRelation() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 91 | |||||||
| 92 | foreach ($fields as $key => $value) { |
||||||
| 93 | $schema = $this->registry->getSchemaForModel($related); |
||||||
| 94 | |||||||
| 95 | $relations = $schema->getRelationFields(); |
||||||
| 96 | if ($relations->keys()->contains($key)) { |
||||||
| 97 | $this->applyRelationalSearch($query, $related, $key, $needle, $value); |
||||||
| 98 | } else { |
||||||
| 99 | $this->tsFields[] = $related->getTable().'.'.$key; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 100 | } |
||||||
| 101 | } |
||||||
| 102 | } |
||||||
| 103 | } |
||||||
| 104 |