Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions lib/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,22 @@

/**
* Returns a fresh xml writer.
*
* @param ?resource $streamOutput Only available with PHP >= 8.4
*/
public function getWriter(): Writer
public function getWriter($streamOutput = null): Writer
{
$w = new Writer();
if (null !== $streamOutput) {
if (!is_resource($streamOutput)) {
throw new \InvalidArgumentException('$streamOutput must be a resource');
}
if (PHP_VERSION_ID < 80400) {
throw new \RuntimeException('Service::getWriter() requires PHP 8.4 or higher');
}
$w = Writer::toStream($streamOutput);

Check failure on line 93 in lib/Service.php

View workflow job for this annotation

GitHub Actions / PHPUnit (PHP 8.2)

Call to an undefined static method Sabre\Xml\Writer::toStream().

Check failure on line 93 in lib/Service.php

View workflow job for this annotation

GitHub Actions / PHPUnit (PHP 8.5)

Call to an undefined static method Sabre\Xml\Writer::toStream().
} else {
$w = new Writer();
}
$w->namespaceMap = $this->namespaceMap;
$w->classMap = $this->classMap;

Expand Down Expand Up @@ -226,6 +238,38 @@
return $w->outputMemory();
}

/**
* Generates an XML document in one go.
*
* The $rootElement must be specified in clark notation.
* The value must be a string, an array or an object implementing
* XmlSerializable. Basically, anything that's supported by the Writer
* object.
*
* $contextUri can be used to specify a sort of 'root' of the PHP application,
* in case the xml document is used as a http response.
*
* This allows an implementor to easily create URI's relative to the root
* of the domain.
*
* @param resource $outputStream
* @param string|array<int|string, mixed>|object|XmlSerializable $value
*
* @warning Only available with > PHP 8.4
*/
public function writeStream($outputStream, string $rootElementName, $value, ?string $contextUri = null): void
{
if (PHP_VERSION_ID < 80400) {
throw new \RuntimeException('Service::writeStream() requires PHP 8.4 or higher');
}

$w = $this->getWriter($outputStream);
$w->contextUri = $contextUri;
$w->setIndent(true);
$w->startDocument();
$w->writeElement($rootElementName, $value);
}

/**
* Map an XML element to a PHP class.
*
Expand Down
33 changes: 33 additions & 0 deletions tests/Sabre/Xml/ServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,39 @@
<stdClass:child>value</stdClass:child>
</stdClass:root>

XML;
self::assertEquals(
$expected,
$result
);
}

#[Depends('testGetWriter')]
public function testWriteStream(): void
{
if (PHP_VERSION_ID < 80400) {
$this->markTestSkipped('Requires PHP 8.4 or higher');

Check failure on line 254 in tests/Sabre/Xml/ServiceTest.php

View workflow job for this annotation

GitHub Actions / PHPUnit (PHP 8.2)

Dynamic call to static method PHPUnit\Framework\Assert::markTestSkipped().

Check failure on line 254 in tests/Sabre/Xml/ServiceTest.php

View workflow job for this annotation

GitHub Actions / PHPUnit (PHP 8.5)

Dynamic call to static method PHPUnit\Framework\Assert::markTestSkipped().
}
$util = new Service();
$util->namespaceMap = [
'http://sabre.io/ns' => 'stdClass',
];

$stream = fopen('php://temp', 'w+');
$this->assertNotFalse($stream);

Check failure on line 262 in tests/Sabre/Xml/ServiceTest.php

View workflow job for this annotation

GitHub Actions / PHPUnit (PHP 8.2)

Dynamic call to static method PHPUnit\Framework\Assert::assertNotFalse().

Check failure on line 262 in tests/Sabre/Xml/ServiceTest.php

View workflow job for this annotation

GitHub Actions / PHPUnit (PHP 8.5)

Dynamic call to static method PHPUnit\Framework\Assert::assertNotFalse().
$util->writeStream($stream, '{http://sabre.io/ns}root', [
'{http://sabre.io/ns}child' => 'value',
]);

rewind($stream);
$result = stream_get_contents($stream);

$expected = <<<XML
<?xml version="1.0"?>
<stdClass:root xmlns:stdClass="http://sabre.io/ns">
<stdClass:child>value</stdClass:child>
</stdClass:root>

XML;
self::assertEquals(
$expected,
Expand Down
Loading