Skip to content

Commit 64df6f7

Browse files
Fix handling of Stringable objects in JSON update requests
1 parent c2744ff commit 64df6f7

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
### Added
99
- Solarium\Core\Query\AbstractQuery::setCpuAllowed()
1010

11+
### Fixed
12+
- JSON update requests correctly handle `Stringable` object set as field value
13+
1114

1215
## [6.3.5]
1316
### Added

src/QueryType/Update/Query/Document.php

+2
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ public function jsonSerialize()
498498
foreach ($fields as $key => &$value) {
499499
if ($value instanceof \DateTimeInterface) {
500500
$value = $this->getHelper()->formatDate($value);
501+
} elseif ($value instanceof \Stringable && !($value instanceof \JsonSerializable)) {
502+
$value = (string) $value;
501503
} elseif (\is_array($value) && is_numeric(array_key_first($value))) {
502504
// ensure consecutive indices so it doesn't serialize to an object
503505
$value = array_values($value);

tests/QueryType/Update/RequestBuilder/JsonTest.php

+98
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,104 @@ public function testBuildAddJsonWithMultivalueDateTimes()
711711
);
712712
}
713713

714+
public function testBuildAddJsonWithJsonSerializableObject()
715+
{
716+
$value = new class() implements \JsonSerializable {
717+
public function jsonSerialize(): mixed
718+
{
719+
return 'My value';
720+
}
721+
};
722+
723+
$command = new AddCommand();
724+
$command->addDocument(
725+
new Document(['id' => 1, 'my_field' => $value])
726+
);
727+
$json = [];
728+
729+
$this->builder->buildAddJson($command, $json);
730+
731+
$this->assertCount(1, $json);
732+
$this->assertJsonStringEqualsJsonString(
733+
'{
734+
"add": {
735+
"doc": {
736+
"id": 1,
737+
"my_field": "My value"
738+
}
739+
}
740+
}',
741+
'{'.$json[0].'}'
742+
);
743+
}
744+
745+
public function testBuildAddJsonWithStringableObject()
746+
{
747+
$value = new class() implements \Stringable {
748+
public function __toString(): string
749+
{
750+
return 'My value';
751+
}
752+
};
753+
754+
$command = new AddCommand();
755+
$command->addDocument(
756+
new Document(['id' => 1, 'my_field' => $value])
757+
);
758+
$json = [];
759+
760+
$this->builder->buildAddJson($command, $json);
761+
762+
$this->assertCount(1, $json);
763+
$this->assertJsonStringEqualsJsonString(
764+
'{
765+
"add": {
766+
"doc": {
767+
"id": 1,
768+
"my_field": "My value"
769+
}
770+
}
771+
}',
772+
'{'.$json[0].'}'
773+
);
774+
}
775+
776+
public function testBuildAddJsonWithJsonSerializableAndStringableObject()
777+
{
778+
$value = new class() implements \JsonSerializable, \Stringable {
779+
public function jsonSerialize(): mixed
780+
{
781+
return 'My JSON value';
782+
}
783+
784+
public function __toString(): string
785+
{
786+
return 'My string value';
787+
}
788+
};
789+
790+
$command = new AddCommand();
791+
$command->addDocument(
792+
new Document(['id' => 1, 'my_field' => $value])
793+
);
794+
$json = [];
795+
796+
$this->builder->buildAddJson($command, $json);
797+
798+
$this->assertCount(1, $json);
799+
$this->assertJsonStringEqualsJsonString(
800+
'{
801+
"add": {
802+
"doc": {
803+
"id": 1,
804+
"my_field": "My JSON value"
805+
}
806+
}
807+
}',
808+
'{'.$json[0].'}'
809+
);
810+
}
811+
714812
public function testBuildAddJsonWithFieldModifierAndNullValue()
715813
{
716814
$doc = new Document();

tests/QueryType/Update/RequestBuilder/XmlTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,26 @@ public function testBuildAddXmlWithMultivalueDateTimes()
522522
);
523523
}
524524

525+
public function testBuildAddXmlWithStringableObject()
526+
{
527+
$value = new class() implements \Stringable {
528+
public function __toString(): string
529+
{
530+
return 'My value';
531+
}
532+
};
533+
534+
$command = new AddCommand();
535+
$command->addDocument(
536+
new Document(['id' => 1, 'my_field' => $value])
537+
);
538+
539+
$this->assertSame(
540+
'<add><doc><field name="id">1</field><field name="my_field">My value</field></doc></add>',
541+
$this->builder->buildAddXml($command)
542+
);
543+
}
544+
525545
public function testBuildAddXmlWithFieldModifierAndNullValue()
526546
{
527547
$doc = new Document();

0 commit comments

Comments
 (0)