Unverified Commit 6be806d9 authored by Dave Reid's avatar Dave Reid Committed by Dave Reid
Browse files

Issue #2387557 by Dave Reid: Support more advanced XML element output.

parent a9490a18
......@@ -314,7 +314,7 @@ class XmlSitemapGenerator implements XmlSitemapGeneratorInterface {
// @todo Should this be moved to XMLSitemapWriter::writeSitemapElement()?
$this->moduleHandler->alter('xmlsitemap_element', $element, $link, $sitemap);
$writer->writeSitemapElement('url', $element);
$writer->writeElement('url', $element);
}
return $link_count;
......@@ -351,7 +351,7 @@ class XmlSitemapGenerator implements XmlSitemapGeneratorInterface {
// @todo SHould the element be altered?
$writer->writeSitemapElement('sitemap', $element);
$writer->writeElement('sitemap', $element);
}
$writer->endDocument();
......
......@@ -2,6 +2,8 @@
namespace Drupal\xmlsitemap;
use Drupal\Component\Utility\Html;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
/**
......@@ -51,8 +53,17 @@ class XmlSitemapWriter extends \XMLWriter {
* The XML sitemap.
* @param int|string $page
* The current page of the sitemap being generated.
*
* @throws \InvalidArgumentException
* If the page is invalid.
* @throws \Drupal\xmlsitemap\XmlSitemapGenerationException
* If the file URI cannot be opened.
*/
public function __construct(XmlSitemapInterface $sitemap, $page) {
if ($page !== 'index' && !filter_var($page, FILTER_VALIDATE_INT)) {
throw new \InvalidArgumentException("Invalid XML sitemap page $page.");
}
$this->sitemap = $sitemap;
$this->page = $page;
$this->uri = xmlsitemap_sitemap_get_file($sitemap, $page);
......@@ -110,14 +121,8 @@ class XmlSitemapWriter extends \XMLWriter {
/**
* Adds the XML stylesheet to the XML page.
*
* @return mixed
* Returns TRUE on success.
*
* @codingStandardsIgnoreStart
*/
public function writeXSL() {
// @codingStandardsIgnoreEnd
$xls_url = Url::fromRoute('xmlsitemap.sitemap_xsl')->toString();
$settings = \Drupal::config('language.negotiation');
if ($settings) {
......@@ -184,17 +189,11 @@ class XmlSitemapWriter extends \XMLWriter {
* The element name.
* @param array $element
* An array of the elements properties and values.
*
* @deprecated Use \Drupal\xmlsitemap\XmlSitemapWriter::writeElement().
*/
public function writeSitemapElement($name, array $element) {
$this->writeElement($name, $element);
$this->writeRaw(PHP_EOL);
// After a certain number of elements have been added, flush the buffer
// to the output file.
$this->sitemapElementCount++;
if (($this->sitemapElementCount % $this->linkCountFlush) == 0) {
$this->flush();
}
}
/**
......@@ -208,16 +207,19 @@ class XmlSitemapWriter extends \XMLWriter {
public function writeElement($name, $content = NULL) {
if (is_array($content)) {
$this->startElement($name);
foreach ($content as $sub_name => $sub_content) {
$this->writeElement($sub_name, $sub_content);
}
$this->writeRaw($this->formatXmlElements($content));
$this->endElement();
}
elseif(is_object($content)) {
parent::writeElement($name, $content->toString());
}
else {
parent::writeElement($name, $content);
parent::writeElement($name, Html::escape(static::toString($content)));
}
$this->writeRaw(PHP_EOL);
// After a certain number of elements have been added, flush the buffer
// to the output file.
$this->sitemapElementCount++;
if (($this->sitemapElementCount % $this->linkCountFlush) == 0) {
$this->flush();
}
}
......@@ -267,8 +269,68 @@ class XmlSitemapWriter extends \XMLWriter {
return $return;
}
/**
* If the page being written is the index.
*
* @return bool
* TRUE if the sitemap index is being written, or FALSE otherwise.
*/
protected function isIndex() {
return $this->page === 'index';
}
/**
* Copy of Drupal 7's format_xml_elements() function.
*
* The extra whitespace has been removed.
*
* @param $array
*
* @return string
*/
public static function formatXmlElements($array) {
$output = '';
foreach ($array as $key => $value) {
if (is_numeric($key)) {
if ($value['key']) {
$output .= '<' . $value['key'];
if (isset($value['attributes'])) {
if (is_array($value['attributes'])) {
$value['attributes'] = new Attribute($value['attributes']);
}
$output .= static::toString($value['attributes']);
}
if (isset($value['value']) && $value['value'] != '') {
$output .= '>' . (is_array($value['value']) ? static::formatXmlElements($value['value']) : Html::escape(static::toString($value['value']))) . '</' . $value['key'] . ">";
}
else {
$output .= " />";
}
}
}
else {
$output .= '<' . $key . '>' . (is_array($value) ? static::formatXmlElements($value) : Html::escape(static::toString($value))) . "</{$key}>";
}
}
return $output;
}
/**
* Convert translatable strings and URLs to strings.
*
* @param mixed $value
* The value to turn into a string.
*
* @return string
*/
public static function toString($value) {
if (is_object($value)) {
if ($value instanceof Url) {
return $value->toString();
}
}
return (string) $value;
}
}
<?php
namespace Drupal\Tests\xmlsitemap\Kernel;
use Drupal\xmlsitemap\Entity\XmlSitemap;
use Drupal\xmlsitemap\XmlSitemapWriter;
/**
* Tests \Drupal\xmlsitemap\XmlSitemapWriter.
*
* @group xmlsitemap
*
* @coversDefaultClass \Drupal\xmlsitemap\XmlSitemapWriter
*/
class XmlSitemapWriterTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->sitemap = XmlSitemap::create();
}
/**
* Test that an invalid page cannot be passed to the constructor.
*
* @covers ::__construct
*/
public function testInvalidPage() {
$this->setExpectedException(\InvalidArgumentException::class);
new XmlSitemapWriter($this->sitemap, 'invalid');
}
/**
* Tests the writeElement() method.
*
* @covers ::writeElement
* @covers ::formatXmlElements
* @covers ::toString
*/
public function testWriteElement() {
$writer = new XmlSitemapWriter($this->sitemap, '1');
$writer->openMemory();
$writer->writeElement('url', [
'item1' => 'value1',
[
'key' => 'item2',
'value' => '<value2>',
],
[
'key' => 'item3',
'value' => [
'subkey' => 'subvalue',
],
'attributes' => [
'attr1key' => 'attr1value',
'attr2key' => '<attr2value>',
],
],
]);
$output = $writer->outputMemory();
$expected = '<url><item1>value1</item1><item2>&lt;value2&gt;</item2><item3 attr1key="attr1value" attr2key="&lt;attr2value&gt;"><subkey>subvalue</subkey></item3></url>' . PHP_EOL;
$this->assertEquals($expected, $output);
$writer->writeSitemapElement('url', [
'loc' => 'https://www.example.com/test',
'image:image' => [
'image:loc' => 'https://www.example.com/test.jpg',
'image:title' => t('The image title'),
'image:caption' => "'The image & its \"caption.\"'",
],
]);
$output = $writer->outputMemory();
$expected = '<url><loc>https://www.example.com/test</loc><image:image><image:loc>https://www.example.com/test.jpg</image:loc><image:title>The image title</image:title><image:caption>&#039;The image &amp; its &quot;caption.&quot;&#039;</image:caption></image:image></url>' . PHP_EOL;
$this->assertSame($expected, $output);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment