Commit 0c877588 authored by Steven Jones's avatar Steven Jones
Browse files

Issue #3523386 by steven jones: Allow pretty-printing XML

parent 8843239c
Loading
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -136,3 +136,6 @@ views.style.data_export:
        item_node_name:
          type: string
          label: 'Item node name'
        format_output:
          type: boolean
          label: 'Format output'
+13 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ class DataExport extends Serializer {
      'encoding' => ['default' => 'UTF-8'],
      'root_node_name' => ['default' => 'response'],
      'item_node_name' => ['default' => 'item'],
      'format_output' => ['default' => FALSE],
    ];

    return $options;
@@ -205,6 +206,7 @@ class DataExport extends Serializer {
            'encoding' => 'UTF-8',
            'root_node_name' => 'response',
            'item_node_name' => 'item',
            'format_output' => FALSE,
          ];
          $form['xml_settings']['encoding'] = [
            '#type' => 'select',
@@ -245,6 +247,12 @@ class DataExport extends Serializer {
              ],
            ],
          ];
          $form['xml_settings']['format_output'] = [
            '#type' => 'checkbox',
            '#title' => $this->t('Pretty-print output'),
            '#description' => $this->t('If the XML file is going to be consumed by humans, you might want to have it formatted with line breaks and indents.'),
            '#default_value' => $xml_options['format_output'],
          ];
        }
        break;
    }
@@ -394,6 +402,7 @@ class DataExport extends Serializer {
      'encoding' => 'UTF-8',
      'root_node_name' => 'response',
      'item_node_name' => 'item',
      'format_output' => FALSE,
    ];
    $context = [
      'views_style_plugin' => $this,
@@ -407,6 +416,10 @@ class DataExport extends Serializer {
      // @todo We can rely on the constant being defined once we drop support for Drupal 9.
      $context[defined('XmlEncoder::ENCODING') ? XmlEncoder::ENCODING : 'xml_encoding'] = $options['encoding'];
    }
    if ($options['format_output']) {
      // @todo We can rely on the constant being defined once we drop support for Drupal 9.
      $context[defined('XmlEncoder::FORMAT_OUTPUT') ? XmlEncoder::FORMAT_OUTPUT : 'xml_format_output'] = $options['format_output'];
    }

    $item_node_name = $options['item_node_name'] ?: 'item';
    if ($item_node_name != 'item') {
+43 −0
Original line number Diff line number Diff line
@@ -301,3 +301,46 @@ display:
      redirect_to_display: none
      custom_redirect_path: false
      include_query_params: false

  format_output:
    display_plugin: data_export
    id: format_output
    display_title: xml
    position: null
    display_options:
      path: test/data_export/xml/pretty_printing
      style:
        type: data_export
        options:
          formats:
            xml: xml
          xml_settings:
            format_output: true
      displays:
        page_1: page_1
        default: '0'

  batched_format_output:
    display_plugin: data_export
    id: batched_format_output
    display_title: 'Data export'
    position: null
    display_options:
      display_extenders: { }
      path: test/data_export/xml/batched/pretty_printing
      filename: test_1
      automatic_download: false
      redirect_path: ''
      style:
        type: data_export
        options:
          formats:
            xml: xml
          xml_settings:
            format_output: true
      export_method: batch
      export_batch_size: 1
      store_in_public_file_directory: true
      redirect_to_display: none
      custom_redirect_path: false
      include_query_params: false
+110 −12
Original line number Diff line number Diff line
@@ -191,6 +191,34 @@ XML,
    );
  }

  /**
   * Data provider for XML response tests.
   */
  public static function batchedXmlEncodingProvider(): array {
    return [
      'default root' => [
        'test/data_export/xml/batched/no_encoding',
        <<<XML
<?xml version="1.0"?>
<response><item key="0"><title>page node title: 4</title></item><item key="1"><title>page node title: 3</title></item><item key="2"><title>page node title: 2</title></item>

<item key="0"><title>page node title: 1</title></item><item key="1"><title>page node title: 0</title></item></response>

XML,
      ],
      'custom root' => [
        'test/data_export/xml/batched/utf8_encoding',
        <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<response><item key="0"><title>page node title: 4</title></item><item key="1"><title>page node title: 3</title></item><item key="2"><title>page node title: 2</title></item>

<item key="0"><title>page node title: 1</title></item><item key="1"><title>page node title: 0</title></item></response>

XML,
      ],
    ];
  }

  /**
   * Test VDE XML views with batch.
   *
@@ -228,29 +256,99 @@ XML,
  /**
   * Data provider for XML response tests.
   */
  public static function batchedXmlEncodingProvider(): array {
  public static function prettyPrintingXmlProvider(): array {
    return [
      'default root' => [
        'test/data_export/xml/batched/no_encoding',
      'pretty printing' => [
        'test/data_export/xml/pretty_printing',
        FALSE,
        <<<XML
<?xml version="1.0"?>
<response><item key="0"><title>page node title: 4</title></item><item key="1"><title>page node title: 3</title></item><item key="2"><title>page node title: 2</title></item>

<item key="0"><title>page node title: 1</title></item><item key="1"><title>page node title: 0</title></item></response>

<?xml version="1.0" encoding="UTF-8"?>
<response>
  <item key="0">
    <title>page node title: 2</title>
  </item>
  <item key="1">
    <title>page node title: 1</title>
  </item>
  <item key="2">
    <title>page node title: 0</title>
  </item>
</response>
XML,
      ],
      'custom root' => [
        'test/data_export/xml/batched/utf8_encoding',
      'batched pretty printing' => [
        'test/data_export/xml/batched/pretty_printing',
        TRUE,
        <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<response><item key="0"><title>page node title: 4</title></item><item key="1"><title>page node title: 3</title></item><item key="2"><title>page node title: 2</title></item>
<response>
  <item key="0">
    <title>page node title: 2</title>
  </item>



  <item key="0">
    <title>page node title: 1</title>
  </item>

<item key="0"><title>page node title: 1</title></item><item key="1"><title>page node title: 0</title></item></response>


  <item key="0">
    <title>page node title: 0</title>
  </item>
</response>

XML,
      ],
    ];
  }

  /**
   * Test XML responses.
   *
   * @dataProvider prettyPrintingXmlProvider
   */
  public function testPrettyPrinting(string $views_path, bool $batched, string $expected_xml): void {
    foreach (range(0, 2) as $i) {
      $this->createNode([
        'status' => TRUE,
        'type' => 'page',
        'title' => 'page node title: ' . $i,
        'created' => 280304046 + $i * 43200,
      ]);
    }

    if (!$batched) {
      $this->drupalGet($views_path);
      $this->assertSession()->statusCodeEquals(200);
      $actual_xml = $this->getSession()->getPage()->getContent();

      $this->assertSame(
        $expected_xml,
        $actual_xml,
        "The XML output matches for $views_path."
      );
    }
    else {
      // Fetch an XML file created with batching.
      $this->drupalGet($views_path);
      $link = $this->getSession()->getPage()->findLink('here');
      $path_to_file = $link->getAttribute('href');
      $this->drupalGet($path_to_file);
      $this->assertEquals(200, $this->getSession()->getStatusCode(), 'File was not created');

      $path_to_file = parse_url($path_to_file, PHP_URL_PATH);
      $public_directory_path = \Drupal::service('stream_wrapper_manager')->getViaScheme('public')->getDirectoryPath();
      $path_to_file = str_replace($_SERVER['REQUEST_URI'] . $public_directory_path, 'public:/', $path_to_file);
      $res1 = file_get_contents($path_to_file);

      $this->assertSame(
        $expected_xml,
        $res1,
        "The XML output matches for $views_path."
      );
    }
  }

}