diff --git a/CHANGELOG.md b/CHANGELOG.md index b9b52a713a..ec88d7b7cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added default implementations for table and JSON output in CLI commons (Shell) #1326 ### Changed +- Add missing method getBinaryContent to the ParseNode interface(PHP). +- Split the Parsable interface into AdditionalData interface and Parsable interface(PHP) #1324. - Shell commands will now default to writing indented JSON. This option can be disabled through the CLI option `--json-no-indent` (Shell) #1326 - Update System.CommandLine version (Shell) #1338 - Add async writers in output formatters (Shell) #1326 diff --git a/abstractions/php/src/Serialization/AdditionalDataHolder.php b/abstractions/php/src/Serialization/AdditionalDataHolder.php new file mode 100644 index 0000000000..6f4dce93cb --- /dev/null +++ b/abstractions/php/src/Serialization/AdditionalDataHolder.php @@ -0,0 +1,17 @@ + The additional data for this object. + */ + public function getAdditionalData(): array; + + /** + * Sets the additional data for this object that did not belong to the properties. + * @param array $value The additional data for this object. + */ + public function setAdditionalData(array $value): void; +} \ No newline at end of file diff --git a/abstractions/php/src/Serialization/Parsable.php b/abstractions/php/src/Serialization/Parsable.php index 8925a1b24b..2afcc35a37 100644 --- a/abstractions/php/src/Serialization/Parsable.php +++ b/abstractions/php/src/Serialization/Parsable.php @@ -17,16 +17,4 @@ public function getFieldDeserializers(): array; * @param SerializationWriter $writer The writer to write to. */ public function serialize(SerializationWriter $writer): void; - - /** - * Gets the additional data for this object that did not belong to the properties. - * @return array|null The additional data for this object. - */ - public function getAdditionalData(): ?array; - - /** - * Sets the additional data for this object that did not belong to the properties. - * @param array $value The additional data for this object. - */ - public function setAdditionalData(array $value): void; } diff --git a/abstractions/php/src/Serialization/ParseNode.php b/abstractions/php/src/Serialization/ParseNode.php index ce4f2b7ba8..cfa07a0900 100644 --- a/abstractions/php/src/Serialization/ParseNode.php +++ b/abstractions/php/src/Serialization/ParseNode.php @@ -8,6 +8,7 @@ use Microsoft\Kiota\Abstractions\Types\Byte; use Microsoft\Kiota\Abstractions\Types\Date; use Microsoft\Kiota\Abstractions\Types\Time; +use Psr\Http\Message\StreamInterface; interface ParseNode { /** @@ -98,6 +99,11 @@ public function getEnumValue(string $targetEnum): ?Enum; */ public function getByteValue(): ?Byte; + /** + * Get a Stream from node. + * @return StreamInterface|null + */ + public function getBinaryContent(): ?StreamInterface; /** * Gets the callback called before the node is deserialized. * @return callable the callback called before the node is deserialized. diff --git a/serialization/php/json/src/JsonParseNode.php b/serialization/php/json/src/JsonParseNode.php index 3205735a77..6f31eb9547 100644 --- a/serialization/php/json/src/JsonParseNode.php +++ b/serialization/php/json/src/JsonParseNode.php @@ -8,6 +8,7 @@ use GuzzleHttp\Psr7\Utils; use InvalidArgumentException; use Microsoft\Kiota\Abstractions\Enum; +use Microsoft\Kiota\Abstractions\Serialization\AdditionalDataHolder; use Microsoft\Kiota\Abstractions\Serialization\Parsable; use Microsoft\Kiota\Abstractions\Serialization\ParseNode; use Microsoft\Kiota\Abstractions\Types\Byte; @@ -113,21 +114,34 @@ public function getObjectValue(string $type): ?Parsable { } /** - * @param Parsable $result + * @param Parsable|AdditionalDataHolder $result * @return void */ - private function assignFieldValues(Parsable $result): void { - $fieldDeserializers = $result->getFieldDeserializers(); - + private function assignFieldValues($result): void { + $fieldDeserializers = []; + if (is_a($result, Parsable::class)){ + $fieldDeserializers = $result->getFieldDeserializers(); + } + $isAdditionalDataHolder = false; + $additionalData = []; + if (is_a($result, AdditionalDataHolder::class)) { + $isAdditionalDataHolder = true; + $additionalData = $result->getAdditionalData(); + } foreach ($this->jsonNode as $key => $value){ $deserializer = $fieldDeserializers[$key] ?? null; if ($deserializer !== null){ $deserializer($result, new JsonParseNode($value)); } else { - $result->getAdditionalData()[$key] = $value; + $key = (string)$key; + $additionalData[$key] = $value; } } + + if ( $isAdditionalDataHolder ) { + $result->setAdditionalData($additionalData); + } } /** diff --git a/serialization/php/json/tests/JsonParseNodeTest.php b/serialization/php/json/tests/JsonParseNodeTest.php index 636639c297..71be7f7083 100644 --- a/serialization/php/json/tests/JsonParseNodeTest.php +++ b/serialization/php/json/tests/JsonParseNodeTest.php @@ -27,7 +27,7 @@ class JsonParseNodeTest extends TestCase private StreamInterface $stream; protected function setUp(): void { - $this->stream = Utils::streamFor('{"name": "Silas Kenneth", "age": 98, "height": 123.122, "maritalStatus": "complicated,single", "address": {"city": "Nairobi", "street": "Luthuli"}}'); + $this->stream = Utils::streamFor('{"@odata.type":"Missing", "name": "Silas Kenneth", "age": 98, "height": 123.122, "maritalStatus": "complicated,single", "address": {"city": "Nairobi", "street": "Luthuli"}}'); } public function testGetIntegerValue(): void { @@ -172,7 +172,7 @@ public function testGetChildNode(): void { /** @var Address $address */ $address = $child->getObjectValue(Address::class); $this->assertInstanceOf(Address::class, $address); - $this->assertEquals((string)'Nairobi', $address->getCity()); + $this->assertEquals('Nairobi', $address->getCity()); } } diff --git a/src/Kiota.Builder/Refiners/PhpRefiner.cs b/src/Kiota.Builder/Refiners/PhpRefiner.cs index e6bda4e300..3a6f383c2b 100644 --- a/src/Kiota.Builder/Refiners/PhpRefiner.cs +++ b/src/Kiota.Builder/Refiners/PhpRefiner.cs @@ -31,7 +31,7 @@ public override void Refine(CodeNamespace generatedCode) ReplaceDefaultDeserializationModules(generatedCode, "Microsoft\\Kiota\\Serialization\\Json\\JsonParseNodeFactory"); AliasUsingWithSameSymbol(generatedCode); AddSerializationModulesImport(generatedCode, new []{"Microsoft\\Kiota\\Abstractions\\ApiClientBuilder"}, null, '\\'); - CorrectCoreType(generatedCode, CorrectMethodType, CorrectPropertyType); + CorrectCoreType(generatedCode, CorrectMethodType, CorrectPropertyType, CorrectImplements); AddGetterAndSetterMethods(generatedCode, new() { CodePropertyKind.Custom, @@ -89,6 +89,8 @@ public override void Refine(CodeNamespace generatedCode) "Microsoft\\Kiota\\Abstractions", "HttpMethod", "RequestInformation", "RequestOption"), new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestExecutor), "Microsoft\\Kiota\\Abstractions", "ResponseHandler"), + new (x => x is CodeClass @class && @class.IsOfKind(CodeClassKind.Model) && @class.Properties.Any(x => x.IsOfKind(CodePropertyKind.AdditionalData)), + "Microsoft\\Kiota\\Abstractions\\Serialization", "AdditionalDataHolder"), new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.Serializer), "Microsoft\\Kiota\\Abstractions\\Serialization", "SerializationWriter"), new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.Deserializer), @@ -164,6 +166,9 @@ private static void CorrectParameterType(CodeElement codeElement) }); CrawlTree(codeElement, CorrectParameterType); } + private static void CorrectImplements(ProprietableBlockDeclaration block) { + block.Implements.Where(x => "IAdditionalDataHolder".Equals(x.Name, StringComparison.OrdinalIgnoreCase)).ToList().ForEach(x => x.Name = x.Name[1..]); // skipping the I + } private static void AliasUsingWithSameSymbol(CodeElement currentElement) { if(currentElement is CodeClass currentClass && currentClass.StartBlock != null && currentClass.StartBlock.Usings.Any(x => !x.IsExternal)) {