diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php index 4a6d31e..82475a8 100644 --- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php @@ -370,10 +370,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { ); } - if (!\Drupal::moduleHandler()->moduleExists('block')) { - return $form; - } - + // Only offer the block settings if the module is enabled. + if (\Drupal::moduleHandler()->moduleExists('block')) { $form['displays']['block'] = array( '#type' => 'fieldset', '#title' => t('Block settings'), @@ -387,8 +385,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#id' => 'edit-block-create', ); - // All options for the block display are included in this container so they - // can be hidden as a group when the "Create a page" checkbox is unchecked. + // All options for the block display are included in this container so + // they can be hidden as a group when the "Create a block" checkbox is + // unchecked. $form['displays']['block']['options'] = array( '#type' => 'container', '#attributes' => array('class' => array('options-set')), @@ -421,8 +420,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { ); $style_form = &$form['displays']['block']['options']['style']; $style_form['style_plugin']['#default_value'] = static::getSelected($form_state, array('block', 'style', 'style_plugin'), 'default', $style_form['style_plugin']); - // Changing this dropdown updates $form['displays']['block']['options'] via - // AJAX. + // Changing this dropdown updates $form['displays']['block']['options'] + // via AJAX. views_ui_add_ajax_trigger($style_form, 'style_plugin', array('displays', 'block', 'options')); $this->buildFormStyle($form, $form_state, 'block'); @@ -437,6 +436,47 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#type' => 'checkbox', '#default_value' => FALSE, ); + } + + // Only offer the REST export settings if the module is enabled. + if (\Drupal::moduleHandler()->moduleExists('rest')) { + $form['displays']['rest_export'] = array( + '#type' => 'fieldset', + '#title' => t('REST export settings'), + '#attributes' => array('class' => array('views-attachment', 'fieldset-no-legend')), + '#tree' => TRUE, + ); + $form['displays']['rest_export']['create'] = array( + '#title' => t('Provide a REST export'), + '#type' => 'checkbox', + '#attributes' => array('class' => array('strong')), + '#id' => 'edit-rest-export-create', + ); + + // All options for the REST export display are included in this container + // so they can be hidden as a group when the "Provide a REST export" + // checkbox is unchecked. + $form['displays']['rest_export']['options'] = array( + '#type' => 'container', + '#attributes' => array('class' => array('options-set')), + '#states' => array( + 'visible' => array( + ':input[name="rest_export[create]"]' => array('checked' => TRUE), + ), + ), + '#prefix' => '
', + '#suffix' => '
', + '#parents' => array('rest_export'), + ); + + $form['displays']['rest_export']['options']['path'] = array( + '#title' => t('REST export path'), + '#type' => 'textfield', + '#field_prefix' => $path_prefix, + // Account for the leading backslash. + '#maxlength' => 254, + ); + } return $form; } @@ -699,6 +739,11 @@ protected function buildDisplayOptions($form, FormStateInterface $form_state) { $display_options['block'] = $this->blockDisplayOptions($form, $form_state); } + // Display: REST export. + if (!empty($form_state['values']['rest_export']['create'])) { + $display_options['rest_export'] = $this->restExportDisplayOptions($form, $form_state); + } + return $display_options; } @@ -755,6 +800,19 @@ protected function addDisplays(View $view, $display_options, $form, FormStateInt } } + // Display: REST export. + if (isset($display_options['rest_export'])) { + $display = $executable->newDisplay('rest_export', 'REST export', 'rest_export_1'); + // If there is no page or block, the REST export display options should + // become the overall view defaults. + if (!isset($display_options['page']) && !isset($display_options['block'])) { + $this->setDefaultOptions($display_options['rest_export'], $display, $default_display); + } + else { + $this->setOverrideOptions($display_options['rest_export'], $display, $default_display); + } + } + // Initialize displays and merge all plugin default values. $executable->mergeDefaults(); } @@ -1046,6 +1104,25 @@ protected function blockDisplayOptions(array $form, FormStateInterface $form_sta } /** + * Retrieves the REST export display options from the submitted form values. + * + * @param array $form + * The full wizard form array. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the wizard form. + * + * @return array + * Returns an array of display options. + */ + protected function restExportDisplayOptions(array $form, FormStateInterface $form_state) { + $display_options = array(); + $display_options['path'] = $form_state['values']['rest_export']['path']; + $display_options['style'] = array('type' => 'serializer'); + + return $display_options; + } + + /** * Retrieves the feed display options. * * @param array $form diff --git a/core/modules/views/src/Tests/Wizard/BasicTest.php b/core/modules/views/src/Tests/Wizard/BasicTest.php index 6c5fe34..09a36cb 100644 --- a/core/modules/views/src/Tests/Wizard/BasicTest.php +++ b/core/modules/views/src/Tests/Wizard/BasicTest.php @@ -7,6 +7,7 @@ namespace Drupal\views\Tests\Wizard; +use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\String; use Drupal\views\Views; @@ -40,6 +41,9 @@ function testViewsWizardAndListing() { $this->assertLinkByHref(url('admin/structure/views/view/' . $view1['id'] . '/delete')); $this->assertLinkByHref(url('admin/structure/views/view/' . $view1['id'] . '/duplicate')); + // The view should not have a REST export display. + $this->assertNoText('REST export', 'When no options are enabled in the wizard, the resulting view does not have a REST export display.'); + // This view should not have a block. $this->drupalGet('admin/structure/block'); $this->assertNoText($view1['label']); @@ -86,6 +90,9 @@ function testViewsWizardAndListing() { $this->assertText($view2['description']); $this->assertLinkByHref(url($view2['page[path]'])); + // The view should not have a REST export display. + $this->assertNoText('REST export', 'If only the page option was enabled in the wizard, the resulting view does not have a REST export display.'); + // This view should not have a block. $this->drupalGet('admin/structure/block'); $this->assertNoText('View: ' . $view2['label']); @@ -118,6 +125,9 @@ function testViewsWizardAndListing() { $this->assertText($view3['description']); $this->assertLinkByHref(url($view3['page[path]'])); + // The view should not have a REST export display. + $this->assertNoText('REST export', 'If only the page and block options were enabled in the wizard, the resulting view does not have a REST export display.'); + // Confirm that the block is available in the block administration UI. $this->drupalGet('admin/structure/block/list/' . \Drupal::config('system.theme')->get('default')); $this->assertText($view3['label']); @@ -133,6 +143,25 @@ function testViewsWizardAndListing() { // Make sure the listing page doesn't show disabled default views. $this->assertNoText('tracker', 'Default tracker view does not show on the listing page.'); + + // Create a view with only a REST export. + $view4 = array(); + $view4['label'] = $this->randomMachineName(16); + $view4['id'] = strtolower($this->randomMachineName(16)); + $view4['description'] = $this->randomMachineName(16); + $view4['show[wizard_key]'] = 'node'; + $view4['show[type]'] = 'page'; + $view4['rest_export[create]'] = 1; + $view4['rest_export[path]'] = $this->randomMachineName(16); + $this->drupalPostForm('admin/structure/views/add', $view4, t('Save and edit')); + + // Check that the REST export path works. + $this->drupalGet($view4['rest_export[path]']); + $this->assertResponse(200); + $data = Json::decode($this->content); + $this->assertEqual(count($data), 1, 'Only the node of type page is exported.'); + $node = reset($data); + $this->assertEqual($node['nid'][0]['value'], $node1->id(), 'The node of type page is exported.'); } /** diff --git a/core/modules/views/src/Tests/Wizard/WizardTestBase.php b/core/modules/views/src/Tests/Wizard/WizardTestBase.php index 1a8acd4..b153077 100644 --- a/core/modules/views/src/Tests/Wizard/WizardTestBase.php +++ b/core/modules/views/src/Tests/Wizard/WizardTestBase.php @@ -19,7 +19,7 @@ * * @var array */ - public static $modules = array('node', 'views_ui', 'block'); + public static $modules = array('node', 'views_ui', 'block', 'rest'); function setUp() { parent::setUp(); diff --git a/core/modules/views_ui/css/views_ui.admin.theme.css b/core/modules/views_ui/css/views_ui.admin.theme.css index 22f3b08..de30d2e 100644 --- a/core/modules/views_ui/css/views_ui.admin.theme.css +++ b/core/modules/views_ui/css/views_ui.admin.theme.css @@ -337,7 +337,8 @@ th.views-ui-operations { } .form-item-page-create label, -.form-item-block-create label { +.form-item-block-create label, +.form-item-rest-export-create label { font-weight: bold; } diff --git a/core/modules/views_ui/src/Tests/WizardTest.php b/core/modules/views_ui/src/Tests/WizardTest.php index 155dc16..3b63ef1 100644 --- a/core/modules/views_ui/src/Tests/WizardTest.php +++ b/core/modules/views_ui/src/Tests/WizardTest.php @@ -33,6 +33,8 @@ public function testWizardFieldLength() { $view['page[feed_properties][path]'] = $this->randomMachineName(255); $view['block[create]'] = TRUE; $view['block[title]'] = $this->randomMachineName(256); + $view['rest_export[create]'] = TRUE; + $view['rest_export[path]'] = $this->randomMachineName(255); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); @@ -42,6 +44,7 @@ public function testWizardFieldLength() { $this->assertText('View name cannot be longer than 255 characters but is currently 256 characters long.'); $this->assertText('Feed path cannot be longer than 254 characters but is currently 255 characters long.'); $this->assertText('Block title cannot be longer than 255 characters but is currently 256 characters long.'); + $this->assertText('REST export path cannot be longer than 254 characters but is currently 255 characters long.'); $view['label'] = $this->randomMachineName(255); $view['id'] = strtolower($this->randomMachineName(128)); @@ -52,6 +55,8 @@ public function testWizardFieldLength() { $view['page[feed_properties][path]'] = $this->randomMachineName(254); $view['block[create]'] = TRUE; $view['block[title]'] = $this->randomMachineName(255); + $view['rest_export[create]'] = TRUE; + $view['rest_export[path]'] = $this->randomMachineName(254); $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit')); $this->assertUrl('admin/structure/views/view/' . $view['id'], array(), 'Make sure the view saving was successful and the browser got redirected to the edit page.');