Loading config/schema/views_data_export.views.schema.yml +3 −0 Original line number Diff line number Diff line Loading @@ -136,3 +136,6 @@ views.style.data_export: item_node_name: type: string label: 'Item node name' format_output: type: boolean label: 'Format output' src/Plugin/views/style/DataExport.php +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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', Loading Loading @@ -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; } Loading Loading @@ -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, Loading @@ -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') { Loading tests/modules/views_data_export_test/test_views/views.view.test_xml_export.yml +43 −0 Original line number Diff line number Diff line Loading @@ -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 tests/src/Functional/ViewsDataExportXmlTest.php +110 −12 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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." ); } } } Loading
config/schema/views_data_export.views.schema.yml +3 −0 Original line number Diff line number Diff line Loading @@ -136,3 +136,6 @@ views.style.data_export: item_node_name: type: string label: 'Item node name' format_output: type: boolean label: 'Format output'
src/Plugin/views/style/DataExport.php +13 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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', Loading Loading @@ -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; } Loading Loading @@ -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, Loading @@ -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') { Loading
tests/modules/views_data_export_test/test_views/views.view.test_xml_export.yml +43 −0 Original line number Diff line number Diff line Loading @@ -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
tests/src/Functional/ViewsDataExportXmlTest.php +110 −12 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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." ); } } }