From 314b0e08293bdb1e0800b9a8178995d6976434b8 Mon Sep 17 00:00:00 2001 From: zigzagdev Date: Mon, 27 Oct 2025 14:12:55 +0900 Subject: [PATCH 1/2] feat: add new method in ElasticSearch class --- src/Response/Elasticsearch.php | 43 +++++++++++++++------------- tests/Response/ElasticsearchTest.php | 31 +++++++++++++------- 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/Response/Elasticsearch.php b/src/Response/Elasticsearch.php index 6fb4caef1..f5fe96998 100644 --- a/src/Response/Elasticsearch.php +++ b/src/Response/Elasticsearch.php @@ -10,7 +10,7 @@ * Elasticsearch B.V licenses this file to you under the MIT License. * See the LICENSE file in the project root for more information. */ -declare(strict_types = 1); +declare(strict_types=1); namespace Elastic\Elasticsearch\Response; @@ -36,11 +36,10 @@ */ class Elasticsearch implements ElasticsearchInterface, ResponseInterface, ArrayAccess { - const HEADER_CHECK = 'X-Elastic-Product'; - const PRODUCT_NAME = 'Elasticsearch'; - use ProductCheckTrait; use MessageResponseTrait; + public const HEADER_CHECK = 'X-Elastic-Product'; + public const PRODUCT_NAME = 'Elasticsearch'; protected array $asArray; protected object $asObject; @@ -67,6 +66,10 @@ public function setResponse(ResponseInterface $response, bool $throwException = // Check for Serverless response $this->serverless = $this->isServerlessResponse($response); $this->response = $response; + + unset($this->asArray, $this->asObject); + $this->asString = ''; + $status = $response->getStatusCode(); if ($throwException && $status > 399 && $status < 500) { $error = new ClientResponseException( @@ -104,14 +107,14 @@ public function isServerless(): bool */ public function asBool(): bool { - return $this->response->getStatusCode() >=200 && $this->response->getStatusCode() < 300; + return $this->response->getStatusCode() >= 200 && $this->response->getStatusCode() < 300; } /** * Converts the body content to array, if possible. * Otherwise, it throws an UnknownContentTypeException * if Content-Type is not specified or unknown. - * + * * @throws UnknownContentTypeException */ public function asArray(): array @@ -147,7 +150,7 @@ public function asArray(): array * Converts the body content to object, if possible. * Otherwise, it throws an UnknownContentTypeException * if Content-Type is not specified or unknown. - * + * * @throws UnknownContentTypeException */ public function asObject(): object @@ -197,7 +200,7 @@ public function __toString(): string /** * Access the body content as object properties - * + * * @see https://www.php.net/manual/en/language.oop5.overloading.php#object.get */ public function __get($name) @@ -207,17 +210,17 @@ public function __get($name) /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php */ public function offsetExists($offset): bool { return isset($this->asArray()[$offset]); } - + /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php * * @return mixed @@ -230,7 +233,7 @@ public function offsetGet($offset) /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php */ public function offsetSet($offset, $value): void @@ -240,7 +243,7 @@ public function offsetSet($offset, $value): void /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php */ public function offsetUnset($offset): void @@ -251,11 +254,11 @@ public function offsetUnset($offset): void /** * Map the response body to an object of a specific class * by default the class is the PHP standard one (stdClass) - * + * * This mapping works only for ES|QL results (with columns and values) * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html - * - * @return object[] + * + * @return object[] */ public function mapTo(string $class = stdClass::class): array { @@ -264,13 +267,13 @@ public function mapTo(string $class = stdClass::class): array throw new UnknownContentTypeException(sprintf( "The response is not a valid ES|QL result. I cannot mapTo(\"%s\")", $class - )); + )); } $iterator = []; $ncol = count($response['columns']); foreach ($response['values'] as $value) { - $obj = new $class; - for ($i=0; $i < $ncol; $i++) { + $obj = new $class(); + for ($i = 0; $i < $ncol; $i++) { $field = Utility::formatVariableName($response['columns'][$i]['name']); if ($class !== stdClass::class && !property_exists($obj, $field)) { continue; @@ -306,4 +309,4 @@ public function mapTo(string $class = stdClass::class): array } return $iterator; } -} \ No newline at end of file +} diff --git a/tests/Response/ElasticsearchTest.php b/tests/Response/ElasticsearchTest.php index dd48f4acb..2acdcfaf9 100644 --- a/tests/Response/ElasticsearchTest.php +++ b/tests/Response/ElasticsearchTest.php @@ -10,7 +10,7 @@ * Elasticsearch B.V licenses this file to you under the MIT License. * See the LICENSE file in the project root for more information. */ -declare(strict_types = 1); +declare(strict_types=1); namespace Elastic\Elasticsearch\Tests\Response; @@ -26,6 +26,7 @@ use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use stdClass; + class ElasticsearchTest extends TestCase { protected Psr17Factory $psr17Factory; @@ -38,7 +39,7 @@ public function setUp(): void { $this->psr17Factory = new Psr17Factory(); $this->elasticsearch = new Elasticsearch(); - + $this->response200 = $this->psr17Factory->createResponse(200) ->withHeader('X-Elastic-Product', 'Elasticsearch') ->withHeader('Content-Type', 'application/json'); @@ -86,11 +87,8 @@ public function testAsBoolIsTrueWith200() public function testAsBoolIsFalseWith400() { - try { - $this->elasticsearch->setResponse($this->response400); - } catch (ClientResponseException $e) { - $this->assertFalse($this->elasticsearch->asBool()); - } + $this->elasticsearch->setResponse($this->response400, false); + $this->assertFalse($this->elasticsearch->asBool()); } /** @@ -141,9 +139,9 @@ public function testSetResponseWith400AndThrowFalseDoesNotThrowException() $this->elasticsearch->setResponse($this->response400, false); } - /** - * @doesNotPerformAssertions - */ + /** + * @doesNotPerformAssertions + */ public function testSetResponseWith500AndThrowFalseDoesNotThrowException() { $this->elasticsearch->setResponse($this->response500, false); @@ -317,4 +315,15 @@ public function testIsServerlessFalseIfNotServerlessResponse() $this->elasticsearch->setResponse($this->response200); $this->assertFalse($this->elasticsearch->isServerless()); } -} \ No newline at end of file + + public function testCacheIsClearedOnSetResponse() + { + $firstBody = $this->psr17Factory->createStream(json_encode(['foo' => 'bar'])); + $this->elasticsearch->setResponse($this->response200->withBody($firstBody)); + $this->assertSame('bar', $this->elasticsearch->asArray()['foo']); + + $secondBody = $this->psr17Factory->createStream(json_encode(['foo' => 'baz'])); + $this->elasticsearch->setResponse($this->response200->withBody($secondBody)); + $this->assertSame('baz', $this->elasticsearch->asArray()['foo']); + } +} From d34e49ec25c2dd1357f493589fc82efbf26ca119 Mon Sep 17 00:00:00 2001 From: Application-drop-up Date: Sat, 13 Dec 2025 17:46:43 +0900 Subject: [PATCH 2/2] chore: remove unrelated formatting changes --- src/Response/Elasticsearch.php | 41 ++++++++++++++-------------- tests/Response/ElasticsearchTest.php | 22 ++++++++------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/Response/Elasticsearch.php b/src/Response/Elasticsearch.php index f5fe96998..2cfd08d6f 100644 --- a/src/Response/Elasticsearch.php +++ b/src/Response/Elasticsearch.php @@ -10,7 +10,7 @@ * Elasticsearch B.V licenses this file to you under the MIT License. * See the LICENSE file in the project root for more information. */ -declare(strict_types=1); +declare(strict_types = 1); namespace Elastic\Elasticsearch\Response; @@ -36,10 +36,11 @@ */ class Elasticsearch implements ElasticsearchInterface, ResponseInterface, ArrayAccess { + const HEADER_CHECK = 'X-Elastic-Product'; + const PRODUCT_NAME = 'Elasticsearch'; + use ProductCheckTrait; use MessageResponseTrait; - public const HEADER_CHECK = 'X-Elastic-Product'; - public const PRODUCT_NAME = 'Elasticsearch'; protected array $asArray; protected object $asObject; @@ -65,11 +66,11 @@ public function setResponse(ResponseInterface $response, bool $throwException = $this->productCheck($response); // Check for Serverless response $this->serverless = $this->isServerlessResponse($response); - $this->response = $response; unset($this->asArray, $this->asObject); $this->asString = ''; + $this->response = $response; $status = $response->getStatusCode(); if ($throwException && $status > 399 && $status < 500) { $error = new ClientResponseException( @@ -107,14 +108,14 @@ public function isServerless(): bool */ public function asBool(): bool { - return $this->response->getStatusCode() >= 200 && $this->response->getStatusCode() < 300; + return $this->response->getStatusCode() >=200 && $this->response->getStatusCode() < 300; } /** * Converts the body content to array, if possible. * Otherwise, it throws an UnknownContentTypeException * if Content-Type is not specified or unknown. - * + * * @throws UnknownContentTypeException */ public function asArray(): array @@ -150,7 +151,7 @@ public function asArray(): array * Converts the body content to object, if possible. * Otherwise, it throws an UnknownContentTypeException * if Content-Type is not specified or unknown. - * + * * @throws UnknownContentTypeException */ public function asObject(): object @@ -200,7 +201,7 @@ public function __toString(): string /** * Access the body content as object properties - * + * * @see https://www.php.net/manual/en/language.oop5.overloading.php#object.get */ public function __get($name) @@ -210,17 +211,17 @@ public function __get($name) /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php */ public function offsetExists($offset): bool { return isset($this->asArray()[$offset]); } - + /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php * * @return mixed @@ -233,7 +234,7 @@ public function offsetGet($offset) /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php */ public function offsetSet($offset, $value): void @@ -243,7 +244,7 @@ public function offsetSet($offset, $value): void /** * ArrayAccess interface - * + * * @see https://www.php.net/manual/en/class.arrayaccess.php */ public function offsetUnset($offset): void @@ -254,11 +255,11 @@ public function offsetUnset($offset): void /** * Map the response body to an object of a specific class * by default the class is the PHP standard one (stdClass) - * + * * This mapping works only for ES|QL results (with columns and values) * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html - * - * @return object[] + * + * @return object[] */ public function mapTo(string $class = stdClass::class): array { @@ -267,13 +268,13 @@ public function mapTo(string $class = stdClass::class): array throw new UnknownContentTypeException(sprintf( "The response is not a valid ES|QL result. I cannot mapTo(\"%s\")", $class - )); + )); } $iterator = []; $ncol = count($response['columns']); foreach ($response['values'] as $value) { - $obj = new $class(); - for ($i = 0; $i < $ncol; $i++) { + $obj = new $class; + for ($i=0; $i < $ncol; $i++) { $field = Utility::formatVariableName($response['columns'][$i]['name']); if ($class !== stdClass::class && !property_exists($obj, $field)) { continue; @@ -309,4 +310,4 @@ public function mapTo(string $class = stdClass::class): array } return $iterator; } -} +} \ No newline at end of file diff --git a/tests/Response/ElasticsearchTest.php b/tests/Response/ElasticsearchTest.php index 2acdcfaf9..80ffc4c9e 100644 --- a/tests/Response/ElasticsearchTest.php +++ b/tests/Response/ElasticsearchTest.php @@ -10,7 +10,7 @@ * Elasticsearch B.V licenses this file to you under the MIT License. * See the LICENSE file in the project root for more information. */ -declare(strict_types=1); +declare(strict_types = 1); namespace Elastic\Elasticsearch\Tests\Response; @@ -26,7 +26,6 @@ use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use stdClass; - class ElasticsearchTest extends TestCase { protected Psr17Factory $psr17Factory; @@ -39,7 +38,7 @@ public function setUp(): void { $this->psr17Factory = new Psr17Factory(); $this->elasticsearch = new Elasticsearch(); - + $this->response200 = $this->psr17Factory->createResponse(200) ->withHeader('X-Elastic-Product', 'Elasticsearch') ->withHeader('Content-Type', 'application/json'); @@ -87,8 +86,11 @@ public function testAsBoolIsTrueWith200() public function testAsBoolIsFalseWith400() { - $this->elasticsearch->setResponse($this->response400, false); - $this->assertFalse($this->elasticsearch->asBool()); + try { + $this->elasticsearch->setResponse($this->response400); + } catch (ClientResponseException $e) { + $this->assertFalse($this->elasticsearch->asBool()); + } } /** @@ -139,9 +141,9 @@ public function testSetResponseWith400AndThrowFalseDoesNotThrowException() $this->elasticsearch->setResponse($this->response400, false); } - /** - * @doesNotPerformAssertions - */ + /** + * @doesNotPerformAssertions + */ public function testSetResponseWith500AndThrowFalseDoesNotThrowException() { $this->elasticsearch->setResponse($this->response500, false); @@ -316,7 +318,7 @@ public function testIsServerlessFalseIfNotServerlessResponse() $this->assertFalse($this->elasticsearch->isServerless()); } - public function testCacheIsClearedOnSetResponse() + public function testCacheIsClearedOnSetResponse(): void { $firstBody = $this->psr17Factory->createStream(json_encode(['foo' => 'bar'])); $this->elasticsearch->setResponse($this->response200->withBody($firstBody)); @@ -326,4 +328,4 @@ public function testCacheIsClearedOnSetResponse() $this->elasticsearch->setResponse($this->response200->withBody($secondBody)); $this->assertSame('baz', $this->elasticsearch->asArray()['foo']); } -} +} \ No newline at end of file