From cf014b1cc93360ba38dc68920f9320adb3a2f33f Mon Sep 17 00:00:00 2001 From: Phil Dodd Date: Tue, 23 Jul 2019 10:37:58 +1000 Subject: [PATCH 1/2] support for wildcards inside -lk params --- src/Parser.php | 10 +++++----- tests/ApiHandlerTest.php | 11 ++++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Parser.php b/src/Parser.php index d9b82b5..f9e1adf 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -213,7 +213,7 @@ public function parse($options, $multiple = false) } else { $primaryKey = $this->getQualifiedColumnName('id'); } - + $this->query->where($primaryKey, $identification); } } @@ -377,7 +377,7 @@ protected function parseWith($withParam) $relationType = $this->getRelationType($relation); if ($relationType === 'BelongsTo') { - $firstKey = $relation->getQualifiedForeignKey(); + $firstKey = $relation->getQualifiedForeignKeyName(); $secondKey = $relation->getQualifiedParentKeyName(); } else if ($relationType === 'HasMany' || $relationType === 'HasOne') { $firstKey = $relation->getQualifiedParentKeyName(); @@ -553,7 +553,7 @@ protected function parseFilter($filterParams) $this->query->where(function ($query) use ($column, $comparator, $values) { foreach ($values as $value) { if ($comparator == 'LIKE' || $comparator == 'NOT LIKE') { - $value = preg_replace('/(^\*|\*$)/', '%', $value); + $value = str_replace('*','%',$value); } //Link the filters with AND of there is a "not" and with OR if there's none @@ -568,7 +568,7 @@ protected function parseFilter($filterParams) $value = $values[0]; if ($comparator == 'LIKE' || $comparator == 'NOT LIKE') { - $value = preg_replace('/(^\*|\*$)/', '%', $value); + $value = str_replace('*','%',$value); } if ($comparator == 'NULL' || $comparator == 'NOT NULL') { @@ -736,7 +736,7 @@ protected function isRelation($model, $relationName) */ protected function getQualifiedColumnName($column, $table = null) { - //Check whether there is a matching column expression that contains an + //Check whether there is a matching column expression that contains an //alias and should therefore not be turned into a qualified column name. $isAlias = count(array_filter($this->query->columns ?: [], function($queryColumn) use ($column) { return preg_match('/.*[\s\'"`]as\s*[\s\'"`]' . $column . '[\'"`]?$/', trim($queryColumn)); diff --git a/tests/ApiHandlerTest.php b/tests/ApiHandlerTest.php index 914b9db..dbad179 100644 --- a/tests/ApiHandlerTest.php +++ b/tests/ApiHandlerTest.php @@ -2,6 +2,7 @@ use Mockery as m; use \Illuminate\Database\Eloquent\Collection; use \Illuminate\Database\Query\Expression; +use Illuminate\Database\Query\Builder as BaseBuilder; use \Illuminate\Http\JsonResponse; use \Illuminate\Support\Facades\Config; use \Illuminate\Support\Facades\Input; @@ -20,6 +21,7 @@ public function setUp() '_fields' => 'title,description,comments.title,user.first_name', //Filters 'title-lk' => 'Example Title|Another Title', + 'description-lk' => '*aaa*bbb*', 'title' => 'Example Title', 'title-not-lk' => 'Example Title', 'title-not' => 'Example Title|Another Title', @@ -88,7 +90,7 @@ public function setUp() ->with('Something to search')->andReturn('Something to search'); //Mock the connection the same way as laravel does: - //tests/Database/DatabaseEloquentBuilderTest.php#L408-L418 (mockConnectionForModel($model, $database)) + //tests/Database/DatabaseEloquentBuilderTest.php#L1187-L1198 (mockConnectionForModel($model, $database)) $grammar = new Illuminate\Database\Query\Grammars\MySqlGrammar; $processor = new Illuminate\Database\Query\Processors\MySqlProcessor; $connection = m::mock('Illuminate\Database\ConnectionInterface', ['getQueryGrammar' => $grammar, 'getPostProcessor' => $processor]); @@ -97,6 +99,10 @@ public function setUp() $connection->shouldReceive('raw')->once()->with('MATCH(posts.title,posts.description) AGAINST("Something to search" IN BOOLEAN MODE) as `_score`') ->andReturn($this->fulltextSelectExpression); $connection->shouldReceive('getPdo')->once()->andReturn($pdo); + $connection->shouldReceive('query')->andReturnUsing(function () use ($connection, $grammar, $processor) { + return new BaseBuilder($connection, $grammar, $processor); + }); + $connection->shouldReceive('getName')->andReturn('myConnection'); $resolver = m::mock('Illuminate\Database\ConnectionResolverInterface', ['connection' => $connection]); @@ -168,6 +174,9 @@ public function testGetBuilder() //assert for title-not-lk $this->assertContains(['type' => 'Basic', 'column' => 'posts.title', 'operator' => 'NOT LIKE', 'value' => 'Example Title', 'boolean' => 'and'], $wheres); + //assert for description-lk + $this->assertContains(['type' => 'Basic', 'column' => 'posts.description', 'operator' => 'LIKE', 'value' => '%aaa%bbb%', 'boolean' => 'and'], $wheres); + //assert for id-min $this->assertContains(['type' => 'Basic', 'column' => 'posts.id', 'operator' => '>=', 'value' => 5, 'boolean' => 'and'], $wheres); From c30296b7cf152baeefdd7378235f6d9760269743 Mon Sep 17 00:00:00 2001 From: Phil Dodd Date: Wed, 24 Jul 2019 07:19:50 +1000 Subject: [PATCH 2/2] compatibility for laravel >= 5.8 --- src/Parser.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Parser.php b/src/Parser.php index f9e1adf..cae8b4d 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -377,7 +377,10 @@ protected function parseWith($withParam) $relationType = $this->getRelationType($relation); if ($relationType === 'BelongsTo') { - $firstKey = $relation->getQualifiedForeignKeyName(); + // Compatibility for Laravel < 5.8 + $firstKey = (method_exists($relation, 'getQualifiedForeignKeyName')) + ? $relation->getQualifiedForeignKeyName() + : $relation->getQualifiedForeignKey(); $secondKey = $relation->getQualifiedParentKeyName(); } else if ($relationType === 'HasMany' || $relationType === 'HasOne') { $firstKey = $relation->getQualifiedParentKeyName();