diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Data.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Data.php new file mode 100644 index 0000000..dbdf59d --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Data.php @@ -0,0 +1,129 @@ + t('Path settings'), + 'column' => 'second', + 'build' => array( + '#weight' => -10, + ), + ); + + $options['path']['category'] = 'path'; + $options['path']['title'] = t('Path'); + } + + /** + * Overrides Drupal\views\Plugin\views\display\PathPluginBase::execute(). + */ + public function execute() { + parent::execute(); + $output = $this->view->render(); + + $response = $this->view->getResponse(); + $response->setContent($output); + + return $response; + } + + /** + * Overrides Drupal\views\Plugin\views\display\DisplayPluginBase::render(). + */ + public function render() { + $output = $this->view->style_plugin->render(); + if (!empty($this->view->live_preview)) { + return '
' . $output . '
'; + } + return $output; + } + +} 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 new file mode 100644 index 0000000..c635e5e --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/DataEntityRow.php @@ -0,0 +1,41 @@ +_entity; + } + +} 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 new file mode 100644 index 0000000..22a3a02 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/views/row/DataFieldRow.php @@ -0,0 +1,91 @@ + 'fieldset', + '#title' => t('Field ID aliases'), + '#description' => t('Rename views default field ID\'s in the output data.'), + '#tree' => TRUE, + ); + + if ($fields = $this->view->display_handler->getOption('fields')) { + $options = $this->options; + + foreach ($fields as $id => $field) { + $form['aliases'][$id] = array( + '#type' => 'textfield', + '#title' => $id, + '#default_value' => isset($options['aliases'][$id]) ? $options['aliases'][$id] : '', + ); + } + } + } + + /** + * Overrides \Drupal\views\Plugin\views\row\RowPluginBase::render(). + */ + public function render($row) { + $ouput = array(); + + foreach ($this->view->field as $id => $field) { + $output[$this->getFieldKeyAlias($id)] = $row->{$field->field_alias}; + } + + return $output; + } + + /** + * Return an alias for a field ID, as set in the options form. + * + * @param string $id + * The field id to lookup an alias for. + * + * @return string + * The matches user entered alias, or the original ID if nothing is found. + */ + public function getFieldKeyAlias($id) { + if (isset($this->options['aliases'][$id])) { + return trim($this->options['aliases'][$id]); + } + return $id; + } + +} diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Json.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Json.php new file mode 100644 index 0000000..deddee3 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Json.php @@ -0,0 +1,73 @@ +view->setResponse($response); + } + + + /** + * Overrides Drupal\views\Plugin\views\style\StylePluginBase::render(). + */ + public function render() { + $rows = array(); + + foreach ($this->view->result as $row) { + $rows[] = $this->row_plugin->render($row); + } + $response = $this->view->getResponse(); + $response->setData($rows); + + return $response->getContent(); + } + +} diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayJsonTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayJsonTest.php new file mode 100644 index 0000000..6558195 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayJsonTest.php @@ -0,0 +1,125 @@ + 'Style: JSON plugin', + 'description' => 'Tests the JSON style plugin.', + 'group' => 'Views Plugins', + ); + } + + protected function setUp() { + parent::setUp(); + + for ($i = 1; $i <= 10; $i++) { + $this->drupalCreateNode(); + } + + $this->enableViewsTestModule(); + + $this->adminUser = $this->drupalCreateUser(array('administer views', 'bypass node access', 'access user profiles', 'view revisions')); + } + + /** + * Checks the behavior of JSON callback paths and row plugins. + */ + public function testJsonResponses() { + $view = views_get_view('test_json_display_field'); + $view->initDisplay(); + $this->executeView($view); + + // Test the JSON callback. + $actual_json = $this->drupalGet('test/json/field'); + $this->assertResponse(200); + + // Test the http content-type. + $headers = $this->drupalGetHeaders(); + $this->assertEqual($headers['content-type'], 'application/json', 'The header content-type is correct.'); + + $expected = array(); + foreach ($view->result as $row) { + $expected_row = array(); + foreach ($view->field as $id => $field) { + $expected_row[$id] = $row->{$field->field_alias}; + } + $expected[] = $expected_row; + } + + $this->assertIdentical($actual_json, json_encode($expected), 'The expected JSON output was found.'); + + // Test a 403 callback. + $this->drupalGet('test/json/denied'); + $this->assertResponse(403); + + // Test the entity rows. + $view = views_get_view('test_json_display_entity'); + $view->initDisplay(); + $this->executeView($view); + + $actual_json = $this->drupalGet('test/json/entity'); + $this->assertResponse(200); + + $expected = array(); + foreach ($view->result as $row) { + $expected[] = $row->_entity; + } + + $this->assertIdentical($actual_json, json_encode($expected), 'The expected JSON output was found.'); + } + + /** + * Test the field ID alias functionality of the DataFieldRow plugin. + */ + public function testUIFieldAlias() { + $this->drupalLogin($this->adminUser); + + // Test the UI settings for adding field ID aliases. + $this->drupalGet('admin/structure/views/view/test_json_display_field/edit/data_1'); + $row_options = 'admin/structure/views/nojs/display/test_json_display_field/data_1/row_options'; + $this->assertLinkByHref($row_options); + + // Add a random alias for the name field and save the view. + $random_name = $this->randomName(); + $this->drupalPost($row_options, array('row_options[aliases][name]' => $random_name), t('Apply')); + $this->drupalPost(NULL, array(), t('Save')); + + $view = views_get_view('test_json_display_field'); + $view->setDisplay('data_1'); + $this->executeView($view); + + $expected = array(); + foreach ($view->result as $row) { + $expected_row = array(); + foreach ($view->field as $id => $field) { + $expected_row[$random_name] = $row->{$field->field_alias}; + } + $expected[] = $expected_row; + } + + $this->assertIdentical($this->drupalGet('test/json/field'), json_encode($expected)); + } + +} diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php index 0367905..29377a9 100644 --- a/core/modules/views/lib/Drupal/views/ViewExecutable.php +++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php @@ -1241,9 +1241,6 @@ public function render($display_id = NULL) { drupal_theme_initialize(); $config = config('views.settings'); - // Set the response so other parts can alter it. - $this->response = new Response('', 200); - $start = microtime(TRUE); if (!empty($this->live_preview) && $config->get('ui.show.additional_queries')) { $this->startQueryCapture(); @@ -1274,6 +1271,11 @@ public function render($display_id = NULL) { // Initialize the style plugin. $this->initStyle(); + if (!isset($this->response)) { + // Set the response so other parts can alter it. + $this->response = new Response('', 200); + } + // Give field handlers the opportunity to perform additional queries // using the entire resultset prior to rendering. if ($this->style_plugin->usesFields()) { diff --git a/core/modules/views/tests/views_test_config/config/views.view.test_json_display_entity.yml b/core/modules/views/tests/views_test_config/config/views.view.test_json_display_entity.yml new file mode 100644 index 0000000..49efa18 --- /dev/null +++ b/core/modules/views/tests/views_test_config/config/views.view.test_json_display_entity.yml @@ -0,0 +1,49 @@ +base_table: node +name: test_json_display_entity +description: '' +tag: '' +human_name: 'Test JSON display entity rows' +core: 8.x +api_version: '3.0' +display: + default: + display_plugin: default + id: default + display_title: Master + position: '' + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: none + query: + type: views_query + exposed_form: + type: basic + style: + type: json + row: + type: data_entity + sorts: + created: + id: created + table: node + field: created + order: DESC + title: 'Test JSON' + arguments: { } + data_1: + display_plugin: data + id: data_1 + display_title: Json + position: '' + display_options: + defaults: + access: false + path: test/json/entity +base_field: nid +disabled: '0' +module: views +langcode: und diff --git a/core/modules/views/tests/views_test_config/config/views.view.test_json_display_field.yml b/core/modules/views/tests/views_test_config/config/views.view.test_json_display_field.yml new file mode 100644 index 0000000..b62cb3b --- /dev/null +++ b/core/modules/views/tests/views_test_config/config/views.view.test_json_display_field.yml @@ -0,0 +1,70 @@ +base_table: views_test_data +name: test_json_display_field +description: '' +tag: '' +human_name: 'Test JSON display field rows' +core: 8.x +api_version: '3.0' +display: + default: + display_plugin: default + id: default + display_title: Master + position: '' + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: none + query: + type: views_query + exposed_form: + type: basic + style: + type: json + row: + type: data_field + fields: + name: + id: name + table: views_test_data + field: name + label: '' + sorts: + created: + id: created + table: views_test_data + field: created + order: DESC + title: 'Test JSON' + arguments: { } + data_1: + display_plugin: data + id: data_1 + display_title: Json + position: '' + display_options: + defaults: + access: false + path: test/json/field + access: + type: none + data_2: + display_plugin: data + id: data_2 + display_title: 'Json - access denied' + position: '' + display_options: + defaults: + access: false + path: test/json/denied + access: + type: perm + options: + perm: 'administer views' +base_field: id +disabled: '0' +module: views +langcode: und