feat(php): generate toXml()/fromXml()/builders for xml-encoded object types (TwiML) - #17795
devin-ai-integration[bot] wants to merge 4 commits into
Conversation
… types (TwiML) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
…prefix unknown attrs, document namespace/text semantics Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Devin Review found 6 potential issues.
3 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)
…teral validation, reject map properties Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Docs Generation Benchmark ResultsComparing PR branch against median of 5 nightly run(s) on
Docs generation runs |
SDK Generation Benchmark ResultsComparing PR branch against median of 5 nightly run(s) on Full benchmark table (click to expand)
main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via |
Description
Linear ticket: Refs (none)
PHP counterpart of #17734 (Python), #17755 (Java), #17785 (TS), #17787 (C#) and #17792 (Go). Object types carrying IR xml encoding metadata (from #17732, IR 67.25.0) now generate XML serialization, parsing and fluent child builders — the TwiML helper-library surface.
Changes Made
generators/php/base/src/asIs/Xml/*: newCore\Xmlruntime (DOM/libxml only) —XmlElementgeneric node,XmlNodeinterface,XmlSerializableTypebase (extendsJsonSerializableType, holds unknown XML attributes/children +addChild()),XmlUtils(secure parser rejecting DOCTYPE/external entities, root-name/namespace validation, scalar/enum/list parsing, wrapped-list merge of unknown content). Emitted only when the IR contains xml-encoded types;composer.jsonthen also requiresext-dom/ext-libxml.generators/php/model/src/object/XmlObjectGenerator.ts: for xml-encoded objects generatestoXmlElement(),toXml(bool $xmlDeclaration = false),fromXml(string),fromXmlElement(XmlElement),__toString()(declaration included for root types only), and one builder per child type (say(Say|string|null $message = null, array $attributes = []): Say), with the sharedadd-prefix collision rule. Enum-typed values go throughXmlUtils::parseEnum/enumValuesso PHPStan keeps the enum literal unions in the generated array shapes.ObjectGenerator.ts: xml objects extendXmlSerializableTypeinstead ofJsonSerializableType.67.21.0→67.25.0for php-base/model/sdk.php-xml-twimlseed fixture (roots, nested children, attributes, namespaces/prefixes, wrapped lists, separator lists, enum lists, empty elements, 64-attrWide,number/Numbercollision) registered inseed/php-sdk/seed.yml; changelog undergenerators/php/sdk/changes/unreleased/.Testing
XmlElementTestships as a core test in generated SDKs.pnpm turbo run compile --filter @fern-api/php-sdk: 18/18 tasks; biome clean.pnpm seed test --generator php-sdk --fixture php-xml-twiml --skip-scripts --local: 1/1.composer install+ PHPUnitOK (98 tests, 369 assertions)including a 13-case TwiML round-trip suite (builders,fromXmltyped children, enum lists, wrapped lists, unknown attrs/children incl. prefixedx:extra, unknown wrapper content,Wide, empty elements, malformed/empty/wrong-root/wrong-namespace/DTD/invalid-enum/invalid-int errors); PHPStan exit 0 onsrc+tests.exhaustivefixture regenerated: 0 xml-related diff (only pre-existing drift from main, reverted).Known/shared limitation (same as the other languages): unknown children are re-emitted after typed children, so arbitrary mixed ordering isn't preserved.
Link to Devin session: https://app.devin.ai/sessions/311fe13ae5434245ada665a9b824809b
Open in Devin Desktop: https://app.devin.ai/desktop/session/311fe13ae5434245ada665a9b824809b?variant=devin