From cc41d94d0ffba99b2a167fbb680a3d4fa23c70ac Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 8 Feb 2021 15:53:53 +0000 Subject: [PATCH] Issue #3128548 by anmolgoyal74, yonailo, sokru, joelpittet, daffie, johnwebdev, alexpott, mradcliffe, DuneBL, catch, xjm, mondrake: Add optional parameters to StatementInterface::fetchObject() to be in line with the PDO implementation of the method fetchObject() --- .../Drupal/Core/Database/StatementEmpty.php | 2 +- .../Core/Database/StatementInterface.php | 15 ++++++++++++- .../Core/Database/StatementPrefetch.php | 4 ++-- .../Drupal/Core/Database/StatementWrapper.php | 4 ++-- .../src/Functional/Database/FakeRecord.php | 21 ++++++++++++++++++- .../KernelTests/Core/Database/FetchTest.php | 3 ++- 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/core/lib/Drupal/Core/Database/StatementEmpty.php b/core/lib/Drupal/Core/Database/StatementEmpty.php index a87bca920a86..0bf78c664f26 100644 --- a/core/lib/Drupal/Core/Database/StatementEmpty.php +++ b/core/lib/Drupal/Core/Database/StatementEmpty.php @@ -68,7 +68,7 @@ public function fetchField($index = 0) { /** * {@inheritdoc} */ - public function fetchObject() { + public function fetchObject(string $class_name = NULL, array $constructor_arguments = NULL) { return NULL; } diff --git a/core/lib/Drupal/Core/Database/StatementInterface.php b/core/lib/Drupal/Core/Database/StatementInterface.php index 917eb8b9bffd..90a25c50dd1f 100644 --- a/core/lib/Drupal/Core/Database/StatementInterface.php +++ b/core/lib/Drupal/Core/Database/StatementInterface.php @@ -127,8 +127,21 @@ public function fetchField($index = 0); * * The object will be of the class specified by StatementInterface::setFetchMode() * or stdClass if not specified. + * + * phpcs:disable Drupal.Commenting + * @todo Remove PHPCS overrides https://www.drupal.org/node/3194677. + * + * @param string|null $class_name + * Name of the created class. + * @param array|null $constructor_arguments + * Elements of this array are passed to the constructor. + * phpcs:enable + * + * @return mixed + * The object of specified class or \stdClass if not specified. Returns + * FALSE or NULL if there is no next row. */ - public function fetchObject(); + public function fetchObject(/* string $class_name = NULL, array $constructor_arguments = NULL */); /** * Fetches the next row and returns it as an associative array. diff --git a/core/lib/Drupal/Core/Database/StatementPrefetch.php b/core/lib/Drupal/Core/Database/StatementPrefetch.php index 3f6efdf3644d..5e71c0947894 100644 --- a/core/lib/Drupal/Core/Database/StatementPrefetch.php +++ b/core/lib/Drupal/Core/Database/StatementPrefetch.php @@ -418,7 +418,7 @@ public function fetchField($index = 0) { /** * {@inheritdoc} */ - public function fetchObject($class_name = NULL, $constructor_args = []) { + public function fetchObject(string $class_name = NULL, array $constructor_arguments = NULL) { if (isset($this->currentRow)) { if (!isset($class_name)) { // Directly cast to an object to avoid a function call. @@ -428,7 +428,7 @@ public function fetchObject($class_name = NULL, $constructor_args = []) { $this->fetchStyle = \PDO::FETCH_CLASS; $this->fetchOptions = [ 'class' => $class_name, - 'constructor_args' => $constructor_args, + 'constructor_args' => $constructor_arguments, ]; // Grab the row in the format specified above. $result = $this->current(); diff --git a/core/lib/Drupal/Core/Database/StatementWrapper.php b/core/lib/Drupal/Core/Database/StatementWrapper.php index eff40102f46b..d770964f07ce 100644 --- a/core/lib/Drupal/Core/Database/StatementWrapper.php +++ b/core/lib/Drupal/Core/Database/StatementWrapper.php @@ -190,9 +190,9 @@ public function fetchAssoc() { /** * {@inheritdoc} */ - public function fetchObject(string $class_name = NULL) { + public function fetchObject(string $class_name = NULL, array $constructor_arguments = NULL) { if ($class_name) { - return $this->clientStatement->fetchObject($class_name); + return $this->clientStatement->fetchObject($class_name, $constructor_arguments); } return $this->clientStatement->fetchObject(); } diff --git a/core/modules/system/tests/src/Functional/Database/FakeRecord.php b/core/modules/system/tests/src/Functional/Database/FakeRecord.php index aa3a5fe35b37..e14f0cf7a303 100644 --- a/core/modules/system/tests/src/Functional/Database/FakeRecord.php +++ b/core/modules/system/tests/src/Functional/Database/FakeRecord.php @@ -9,4 +9,23 @@ * rather than just a stdClass or array. This class is for testing that * functionality. (See testQueryFetchClass() below) */ -class FakeRecord {} +class FakeRecord { + + /** + * A class variable. + * + * @var int + */ + public $fakeArg; + + /** + * Constructs a FakeRecord object with an optional constructor argument. + * + * @param int $fakeArg + * A class variable. + */ + public function __construct($fakeArg = 0) { + $this->fakeArg = $fakeArg; + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php b/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php index 2713e6db7cb4..bf499492d649 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/FetchTest.php @@ -88,10 +88,11 @@ public function testQueryFetchClass() { public function testQueryFetchObjectClass() { $records = 0; $query = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25]); - while ($result = $query->fetchObject(FakeRecord::class)) { + while ($result = $query->fetchObject(FakeRecord::class, [1])) { $records += 1; $this->assertInstanceOf(FakeRecord::class, $result); $this->assertSame('John', $result->name, '25 year old is John.'); + $this->assertSame(1, $result->fakeArg, 'The record has received an argument through its constructor.'); } $this->assertSame(1, $records, 'There is only one record.'); } -- GitLab