diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index 0a27b0b33abc..3b85d760db4b 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -764,14 +764,18 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type $keyValue = $key; } + if ($keyValue === []) { + return $this; + } + // If the escape value was not set will base it on the global setting if (! is_bool($escape)) { $escape = $this->db->protectIdentifiers; } - foreach ($keyValue as $k => $v) { - $prefix = empty($this->{$qbKey}) ? $this->groupGetType('') : $this->groupGetType($type); + $prefix = empty($this->{$qbKey}) ? $this->groupGetType('') : $this->groupGetType($type); + foreach ($keyValue as $k => $v) { if ($rawSqlOnly) { $k = ''; $op = ''; @@ -830,6 +834,8 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type 'escape' => $escape, ]; } + + $prefix = $type; } return $this; @@ -1152,13 +1158,13 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri $keyValue = is_array($field) ? $field : [$field => $match]; + $prefix = $this->{$clause} === [] ? $this->groupGetType('') : $this->groupGetType($type); + foreach ($keyValue as $k => $v) { if ($insensitiveSearch) { $v = mb_strtolower($v, 'UTF-8'); } - $prefix = empty($this->{$clause}) ? $this->groupGetType('') : $this->groupGetType($type); - if ($side === 'none') { $bind = $this->setBind($k, $v, $escape); } elseif ($side === 'before') { @@ -1180,6 +1186,8 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri 'condition' => $likeStatement, 'escape' => $escape, ]; + + $prefix = $type; } return $this; diff --git a/tests/system/Database/Builder/LikeTest.php b/tests/system/Database/Builder/LikeTest.php index d2a534b5bf27..fc8a30339b7b 100644 --- a/tests/system/Database/Builder/LikeTest.php +++ b/tests/system/Database/Builder/LikeTest.php @@ -231,4 +231,79 @@ public function testDBPrefixAndCoulmnWithTablename(): void $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); $this->assertSame($expectedBinds, $builder->getBinds()); } + + public function testLikeMultipleFields(): void + { + $builder = new BaseBuilder('job', $this->db); + + $builder->like([ + 'name' => 'veloper', + 'title' => 'dev', + ]); + + $expectedSQL = "SELECT * FROM \"job\" WHERE \"name\" LIKE '%veloper%' ESCAPE '!' AND \"title\" LIKE '%dev%' ESCAPE '!'"; + $expectedBinds = [ + 'name' => [ + '%veloper%', + true, + ], + 'title' => [ + '%dev%', + true, + ], + ]; + + $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSame($expectedBinds, $builder->getBinds()); + } + + public function testLikeMultipleCallsWithRawSqlAndString(): void + { + $builder = new BaseBuilder('users', $this->db); + + $sql = "concat(users.name, ' ', users.surname)"; + $rawSql = new RawSql($sql); + + $builder->like($rawSql, 'value')->like('name', 'veloper'); + + $expectedSQL = "SELECT * FROM \"users\" WHERE {$sql} LIKE '%value%' ESCAPE '!' AND \"name\" LIKE '%veloper%' ESCAPE '!'"; + $expectedBinds = [ + $rawSql->getBindingKey() => [ + '%value%', + true, + ], + 'name' => [ + '%veloper%', + true, + ], + ]; + + $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSame($expectedBinds, $builder->getBinds()); + } + + public function testOrLikeMultipleFields(): void + { + $builder = new BaseBuilder('job', $this->db); + + $builder->orLike([ + 'name' => 'veloper', + 'title' => 'dev', + ]); + + $expectedSQL = "SELECT * FROM \"job\" WHERE \"name\" LIKE '%veloper%' ESCAPE '!' OR \"title\" LIKE '%dev%' ESCAPE '!'"; + $expectedBinds = [ + 'name' => [ + '%veloper%', + true, + ], + 'title' => [ + '%dev%', + true, + ], + ]; + + $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect())); + $this->assertSame($expectedBinds, $builder->getBinds()); + } } diff --git a/utils/phpstan-baseline/empty.notAllowed.neon b/utils/phpstan-baseline/empty.notAllowed.neon index 0f92e89f912e..e526a441d344 100644 --- a/utils/phpstan-baseline/empty.notAllowed.neon +++ b/utils/phpstan-baseline/empty.notAllowed.neon @@ -34,7 +34,7 @@ parameters: - message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#' - count: 28 + count: 27 path: ../../system/Database/BaseBuilder.php -