Browse Source

Merge pull request #17155 from cakephp/5.x-finder-variadic

Fix call to finders with variadic argument.
othercorey 2 years ago
parent
commit
8999c0106f

+ 13 - 7
src/ORM/Table.php

@@ -2676,6 +2676,7 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
             if (
                 count($params) === 2 &&
                 $secondParam?->name === 'options' &&
+                !$secondParam->isVariadic() &&
                 ($secondParamType === null || $secondParamTypeName === 'array')
             ) {
                 if (isset($args[0])) {
@@ -2712,14 +2713,19 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
             $args = $query->getOptions();
 
             unset($params[0]);
-            $paramNames = [];
-            foreach ($params as $param) {
-                $paramNames[] = $param->getName();
-            }
+            $lastParam = end($params);
+            reset($params);
+
+            if ($lastParam === false || !$lastParam->isVariadic()) {
+                $paramNames = [];
+                foreach ($params as $param) {
+                    $paramNames[] = $param->getName();
+                }
 
-            foreach ($args as $key => $value) {
-                if (is_string($key) && !in_array($key, $paramNames, true)) {
-                    unset($args[$key]);
+                foreach ($args as $key => $value) {
+                    if (is_string($key) && !in_array($key, $paramNames, true)) {
+                        unset($args[$key]);
+                    }
                 }
             }
         }

+ 19 - 0
tests/TestCase/ORM/TableTest.php

@@ -1286,6 +1286,25 @@ class TableTest extends TestCase
         $this->assertSame(2, $author->id);
     }
 
+    public function testFindForFinderVariadic(): void
+    {
+        $testTable = $this->fetchTable('Test');
+
+        $testTable->find('variadic', foo: 'bar');
+        $this->assertNull($testTable->first);
+        $this->assertSame(['foo' => 'bar'], $testTable->variadic);
+
+        $testTable->find('variadic', first: 'one', foo: 'bar');
+        $this->assertSame('one', $testTable->first);
+        $this->assertSame(['foo' => 'bar'], $testTable->variadic);
+
+        $testTable->find('variadicOptions');
+        $this->assertSame([], $testTable->variadicOptions);
+
+        $testTable->find('variadicOptions', foo: 'bar');
+        $this->assertSame(['foo' => 'bar'], $testTable->variadicOptions);
+    }
+
     /**
      * Tests find('list')
      */

+ 19 - 0
tests/test_app/TestApp/Model/Table/TestTable.php

@@ -11,6 +11,10 @@ use Cake\ORM\Table;
  */
 class TestTable extends Table
 {
+    public mixed $first;
+    public array $variadic;
+    public array $variadicOptions;
+
     /**
      * @param array $config
      */
@@ -28,4 +32,19 @@ class TestTable extends Table
     {
         return $query->applyOptions(['this' => 'worked']);
     }
+
+    public function findVariadicOptions(SelectQuery $query, ...$options)
+    {
+        $this->variadicOptions = $options;
+
+        return $query;
+    }
+
+    public function findVariadic(SelectQuery $query, mixed $first = null, mixed ...$variadic)
+    {
+        $this->first = $first;
+        $this->variadic = $variadic;
+
+        return $query;
+    }
 }