diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Data.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/WSEndpoint.php similarity index 85% rename from core/modules/views/lib/Drupal/views/Plugin/views/display/Data.php rename to core/modules/views/lib/Drupal/views/Plugin/views/display/WSEndpoint.php index 5beda9b..bcf4775 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Data.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/WSEndpoint.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\views\Plugin\views\display\Data. + * Contains \Drupal\views\Plugin\views\display\WSEndpoint. */ namespace Drupal\views\Plugin\views\display; @@ -13,20 +13,20 @@ use Drupal\views\ViewExecutable; /** - * The plugin that handles a Data response callbacks. + * The plugin that handles Data response callbacks for web service endpoints. * * @ingroup views_display_plugins * * @Plugin( - * id = "data", + * id = "ws_endpoint", * module = "views", - * title = @Translation("Data"), - * help = @Translation("Display views as data output formats"), + * title = @Translation("Web service endpoint"), + * help = @Translation("Create a web service endpoint for views data."), * uses_hook_menu = TRUE, - * admin = @Translation("Data") + * admin = @Translation("Web service endpoint") * ) */ -class Data extends PathPluginBase { +class WSEndpoint extends PathPluginBase { /** * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::$usesAJAX. @@ -85,7 +85,7 @@ public function initDisplay(ViewExecutable $view, array &$display, array &$optio * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::getStyleType(). */ protected function getStyleType() { - return 'data'; + return 'ws_endpoint'; } /** @@ -152,8 +152,8 @@ protected function defineOptions() { $options = parent::defineOptions(); // Set the default style plugin to 'json'. - $options['style']['contains']['type']['default'] = 'serialize'; - $options['row']['contains']['type']['default'] = 'data_entity'; + $options['style']['contains']['type']['default'] = 'serializer'; + $options['row']['contains']['type']['default'] = 'ws_endpoint_entity'; $options['defaults']['default']['style'] = FALSE; $options['defaults']['default']['row'] = FALSE; @@ -186,7 +186,8 @@ public function optionsSummary(&$categories, &$options) { $options['path']['category'] = 'path'; $options['path']['title'] = t('Path'); - // Remove css/exposed form settings, as they are not used for the data display. + // Remove css/exposed form settings, as they are not used for the data + // display. unset($options['exposed_form']); unset($options['exposed_block']); unset($options['css_class']); @@ -216,4 +217,14 @@ public function render() { return $output; } + /** + * Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::preview(). + * + * The DisplayPluginBase preview method assumes we will be returning a render + * array. The data plugin will already return the serialized string. + */ + public function preview() { + return $this->view->render(); + } + } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/row/DataEntityRow.php b/core/modules/views/lib/Drupal/views/Plugin/views/row/DataEntityRow.php index dd520d5..1c9755b 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/row/DataEntityRow.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/DataEntityRow.php @@ -17,11 +17,11 @@ * @ingroup views_row_plugins * * @Plugin( - * id = "data_entity", + * id = "ws_endpoint_entity", * module = "views", * title = @Translation("Entity"), * help = @Translation("Use entities as row data."), - * type = "data" + * type = "ws_endpoint" * ) */ class DataEntityRow extends RowPluginBase { diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/row/DataFieldRow.php b/core/modules/views/lib/Drupal/views/Plugin/views/row/DataFieldRow.php index edc902a..3c98c27 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/row/DataFieldRow.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/DataFieldRow.php @@ -18,11 +18,11 @@ * @ingroup views_row_plugins * * @Plugin( - * id = "data_field", + * id = "ws_endpoint_field", * module = "views", * title = @Translation("Fields"), * help = @Translation("Use fields as row data."), - * type = "data" + * type = "ws_endpoint" * ) */ class DataFieldRow extends RowPluginBase { @@ -71,7 +71,7 @@ public function buildOptionsForm(&$form, &$form_state) { $form['aliases'] = array( '#type' => 'fieldset', '#title' => t('Field ID aliases'), - '#description' => t('Rename views default field ID\'s in the output data.'), + '#description' => t('Rename views default field IDs in the output data.'), '#tree' => TRUE, ); @@ -91,10 +91,11 @@ public function buildOptionsForm(&$form, &$form_state) { */ public function validateOptionsForm(&$form, &$form_state) { $aliases = $form_state['values']['row_options']['aliases']; - if (array_unique($aliases) !== $aliases) { + // If array filter returns empty, no values have been entered. Unique keys + // should only be validated if we have some. + if (array_filter($aliases) && (array_unique($aliases) !== $aliases)) { form_set_error('aliases', t('All field aliases must be unique')); } - } /** @@ -104,7 +105,17 @@ public function render($row) { $output = array(); foreach ($this->view->field as $id => $field) { - $output[$this->getFieldKeyAlias($id)] = $row->{$field->field_alias}; + // If we don't have a field alias, Just try to get the rendered output + // from the field. + if ($field->field_alias == 'unknown') { + $value = $field->render($row); + } + // Get the value directly from the result row. + else { + $value = $row->{$field->field_alias}; + } + + $output[$this->getFieldKeyAlias($id)] = $value; } return $output; @@ -123,6 +134,7 @@ public function getFieldKeyAlias($id) { if (isset($this->replacementAliases[$id])) { return $this->replacementAliases[$id]; } + return $id; } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Serialize.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Serializer.php similarity index 92% rename from core/modules/views/lib/Drupal/views/Plugin/views/style/Serialize.php rename to core/modules/views/lib/Drupal/views/Plugin/views/style/Serializer.php index d8d603b..23d9c73 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/style/Serialize.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Serializer.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\views\Plugin\views\style\Serialize. + * Contains \Drupal\views\Plugin\views\style\Serializer. */ namespace Drupal\views\Plugin\views\style; @@ -18,14 +18,14 @@ * @ingroup views_style_plugins * * @Plugin( - * id = "serialize", + * id = "serializer", * module = "views", * title = @Translation("Serializer"), * help = @Translation("Serializes views row data using the Serializer component."), - * type = "data" + * type = "ws_endpoint" * ) */ -class Serialize extends StylePluginBase { +class Serializer extends StylePluginBase { /** * Overrides \Drupal\views\Plugin\views\style\StylePluginBase::$usesRowPlugin. diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleSerializeTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleSerializeTest.php index fadba33..c53bfcb 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleSerializeTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleSerializeTest.php @@ -56,9 +56,9 @@ protected function setUp() { } /** - * Checks the behavior of serialize callback paths and row plugins. + * Checks the behavior of the Serializer callback paths and row plugins. */ - public function testSerializeResponses() { + public function testSerializerResponses() { // Test the serialize callback. $view = views_get_view('test_serialize_display_field'); $view->initDisplay(); @@ -75,13 +75,26 @@ public function testSerializeResponses() { foreach ($view->result as $row) { $expected_row = array(); foreach ($view->field as $id => $field) { - $expected_row[$id] = $row->{$field->field_alias}; + if ($field->field_alias == 'unknown') { + $expected_row[$id] = $field->render($row); + } + else { + $expected_row[$id] = $row->{$field->field_alias}; + } } $expected[] = $expected_row; } $this->assertIdentical($actual_json, json_encode($expected), 'The expected JSON output was found.'); + + // Test that the rendered output and the preview output are the same. + $view->destroy(); + $view->setDisplay('ws_endpoint_1'); + // Mock the request content type by setting it on the display handler. + $view->display_handler->setContentType('json'); + $this->assertIdentical($actual_json, $view->preview(), 'The expected JSON preview output was found.'); + // Test a 403 callback. $this->drupalGet('test/serialize/denied'); $this->assertResponse(403); @@ -123,16 +136,17 @@ public function testUIFieldAlias() { $this->drupalLogin($this->adminUser); // Test the UI settings for adding field ID aliases. - $this->drupalGet('admin/structure/views/view/test_serialize_display_field/edit/data_1'); - $row_options = 'admin/structure/views/nojs/display/test_serialize_display_field/data_1/row_options'; + $this->drupalGet('admin/structure/views/view/test_serialize_display_field/edit/ws_endpoint_1'); + $row_options = 'admin/structure/views/nojs/display/test_serialize_display_field/ws_endpoint_1/row_options'; $this->assertLinkByHref($row_options); - // Test an empty string for an alias, this should not be used. + // Test an empty string for an alias, this should not be used. This also + // tests that the form can be submitted with no aliases. $this->drupalPost($row_options, array('row_options[aliases][name]' => ''), t('Apply')); $this->drupalPost(NULL, array(), t('Save')); $view = views_get_view('test_serialize_display_field'); - $view->setDisplay('data_1'); + $view->setDisplay('ws_endpoint_1'); $this->executeView($view); $expected = array(); @@ -140,7 +154,12 @@ public function testUIFieldAlias() { $expected_row = array(); foreach ($view->field as $id => $field) { // Original field key is expected. - $expected_row[$id] = $row->{$field->field_alias}; + if ($field->field_alias == 'unknown') { + $expected_row[$id] = $field->render($row); + } + else { + $expected_row[$id] = $row->{$field->field_alias}; + } } $expected[] = $expected_row; } @@ -148,21 +167,29 @@ public function testUIFieldAlias() { // Use an AJAX call, as this will return decoded JSON data. $this->assertIdentical($this->drupalGetAJAX('test/serialize/field'), $expected); - // Test a random alias for the name field, this should be replaced. + // Test a random aliases for fields, they should be replaced. $random_name = $this->randomName(); - $this->drupalPost($row_options, array('row_options[aliases][name]' => $random_name), t('Apply')); + $random_string = $this->randomString(); + $edit = array('row_options[aliases][name]' => $random_name, 'row_options[aliases][nothing]' => $random_string); + $this->drupalPost($row_options, $edit, t('Apply')); $this->drupalPost(NULL, array(), t('Save')); $view = views_get_view('test_serialize_display_field'); - $view->setDisplay('data_1'); + $view->setDisplay('ws_endpoint_1'); $this->executeView($view); $expected = array(); foreach ($view->result as $row) { $expected_row = array(); foreach ($view->field as $id => $field) { - // Replacement alias is expected. - $expected_row[$random_name] = $row->{$field->field_alias}; + // This will be the custom field. + if ($field->field_alias == 'unknown') { + $expected_row[$random_string] = $field->render($row); + } + // This will be the name field. + else { + $expected_row[$random_name] = $row->{$field->field_alias}; + } } $expected[] = $expected_row; } diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_entity.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_entity.yml index 7f08074..fe03987 100644 --- a/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_entity.yml +++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_entity.yml @@ -23,9 +23,9 @@ display: exposed_form: type: basic style: - type: serialize + type: serializer row: - type: data_entity + type: ws_endpoint_entity sorts: id: id: standard @@ -34,16 +34,16 @@ display: order: DESC title: 'Test serialize' arguments: { } - data_1: - display_plugin: data - id: data_1 - display_title: serialize + ws_endpoint_1: + display_plugin: ws_endpoint + id: ws_endpoint_1 + display_title: serializer position: '' display_options: defaults: access: false path: test/serialize/entity -base_field: nid +base_field: id disabled: '0' module: views langcode: und diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_field.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_field.yml index a3214e5..5cafeb4 100644 --- a/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_field.yml +++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_serialize_display_field.yml @@ -2,7 +2,7 @@ base_table: views_test_data name: test_serialize_display_field description: '' tag: '' -human_name: 'Test serialize display field rows' +human_name: 'Test serializer display field rows' core: 8.x api_version: '3.0' display: @@ -23,15 +23,27 @@ display: exposed_form: type: basic style: - type: serialize + type: serializer row: - type: data_field + type: ws_endpoint_field fields: name: id: name table: views_test_data field: name label: '' + nothing: + id: nothing + table: views + field: nothing + relationship: none + group_type: group + admin_label: '' + label: 'Custom text' + exclude: '0' + alter: + alter_text: '1' + text: TEST sorts: created: id: created @@ -40,10 +52,10 @@ display: order: DESC title: 'Test serialize' arguments: { } - data_1: - display_plugin: data - id: data_1 - display_title: serialize + ws_endpoint_1: + display_plugin: ws_endpoint + id: ws_endpoint_1 + display_title: serializer position: '' display_options: defaults: @@ -54,12 +66,12 @@ display: access: type: none style: - type: serialize + type: serializer row: - type: data_field - data_2: - display_plugin: data - id: data_2 + type: ws_endpoint_field + ws_endpoint_2: + display_plugin: ws_endpoint + id: ws_endpoint_2 display_title: 'serialize - access denied' position: '' display_options: @@ -73,9 +85,9 @@ display: options: perm: 'administer views' style: - type: serialize + type: serializer row: - type: data_field + type: ws_endpoint_field base_field: id disabled: '0' module: views