Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023

This commit is contained in:
Pantheon Automation 2015-09-04 13:20:09 -07:00 committed by Greg Anderson
parent 2720a9ec4b
commit f3791f1da3
1898 changed files with 54300 additions and 11481 deletions

View file

@ -7,7 +7,6 @@
namespace Drupal\views_ui\Controller;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\views\ViewExecutable;
@ -89,11 +88,16 @@ class ViewsUIController extends ControllerBase {
$header = array(t('Field name'), t('Used in'));
$rows = array();
foreach ($fields as $field_name => $views) {
$rows[$field_name]['data'][0] = SafeMarkup::checkPlain($field_name);
$rows[$field_name]['data'][0]['data']['#plain_text'] = $field_name;
foreach ($views as $view) {
$rows[$field_name]['data'][1][] = $this->l($view, new Url('entity.view.edit_form', array('view' => $view)));
}
$rows[$field_name]['data'][1] = SafeMarkup::set(implode(', ', $rows[$field_name]['data'][1]));
$item_list = [
'#theme' => 'item_list',
'#items' => $rows[$field_name]['data'][1],
'#context' => ['list_style' => 'comma-list'],
];
$rows[$field_name]['data'][1] = ['data' => $item_list];
}
// Sort rows by field name.
@ -121,7 +125,11 @@ class ViewsUIController extends ControllerBase {
foreach ($row['views'] as $row_name => $view) {
$row['views'][$row_name] = $this->l($view, new Url('entity.view.edit_form', array('view' => $view)));
}
$row['views'] = SafeMarkup::set(implode(', ', $row['views']));
$row['views']['data'] = [
'#theme' => 'item_list',
'#items' => $row['views'],
'#context' => ['list_style' => 'comma-list'],
];
}
// Sort rows by field name.

View file

@ -7,7 +7,7 @@
namespace Drupal\views_ui\Form\Ajax;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\ViewExecutable;
@ -52,7 +52,7 @@ class RearrangeFilter extends ViewsFormBase {
return $form;
}
$display = $executable->displayHandlers->get($display_id);
$form['#title'] = SafeMarkup::checkPlain($display->display['display_title']) . ': ';
$form['#title'] = Html::escape($display->display['display_title']) . ': ';
$form['#title'] .= $this->t('Rearrange @type', array('@type' => $types[$type]['ltitle']));
$form['#section'] = $display_id . 'rearrange-item';

View file

@ -35,6 +35,7 @@ class DisplayPathTest extends UITestBase {
public function testPathUI() {
$this->doBasicPathUITest();
$this->doAdvancedPathsValidationTest();
$this->doPathXssFilterTest();
}
/**
@ -59,6 +60,28 @@ class DisplayPathTest extends UITestBase {
$this->assertLink(t('View @display', array('@display' => 'Page')), 0, 'view page link found on the page.');
}
/**
* Tests that View paths are properly filtered for XSS.
*/
public function doPathXssFilterTest() {
$this->drupalGet('admin/structure/views/view/test_view');
$this->drupalPostForm(NULL, array(), 'Add Page');
$this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_2/path', array('path' => '<object>malformed_path</object>'), t('Apply'));
$this->drupalPostForm(NULL, array(), 'Add Page');
$this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_3/path', array('path' => '<script>alert("hello");</script>'), t('Apply'));
$this->drupalPostForm(NULL, array(), 'Add Page');
$this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_4/path', array('path' => '<script>alert("hello I have placeholders %");</script>'), t('Apply'));
$this->drupalPostForm('admin/structure/views/view/test_view', array(), t('Save'));
$this->drupalGet('admin/structure/views');
// The anchor text should be escaped.
$this->assertEscaped('/<object>malformed_path</object>');
$this->assertEscaped('/<script>alert("hello");</script>');
$this->assertEscaped('/<script>alert("hello I have placeholders %");</script>');
// Links should be url-encoded.
$this->assertRaw('/%3Cobject%3Emalformed_path%3C/object%3E');
$this->assertRaw('/%3Cscript%3Ealert%28%22hello%22%29%3B%3C/script%3E');
}
/**
* Tests a couple of invalid path patterns.
*/

View file

@ -7,6 +7,8 @@
namespace Drupal\views_ui\Tests;
use Drupal\views\Entity\View;
/**
* Tests exposed forms UI functionality.
*
@ -151,5 +153,25 @@ class ExposedFormUITest extends UITestBase {
// Check the label of the expose button.
$this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide sort'));
$this->assertFieldById('edit-options-expose-label', '', 'Make sure a label field is shown');
// Test adding a new exposed sort criteria.
$view_id = $this->randomView()['id'];
$this->drupalGet("admin/structure/views/nojs/add-handler/$view_id/default/sort");
$this->drupalPostForm(NULL, ['name[node_field_data.created]' => 1], t('Add and configure @handler', ['@handler' => t('sort criteria')]));
$this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'ASC', 'The default order is set.');
// Change the order and expose the sort.
$this->drupalPostForm(NULL, ['options[order]' => 'DESC'], t('Apply'));
$this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/sort/created", [], t('Expose sort'));
$this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'DESC');
$this->assertFieldByName('options[expose][label]', 'Authored on', 'The default label is set.');
// Change the label and save the view.
$edit = ['options[expose][label]' => $this->randomString()];
$this->drupalPostForm(NULL, $edit, t('Apply'));
$this->drupalPostForm(NULL, [], t('Save'));
// Check that the values were saved.
$display = View::load($view_id)->getDisplay('default');
$this->assertTrue($display['display_options']['sorts']['created']['exposed']);
$this->assertEqual($display['display_options']['sorts']['created']['expose'], ['label' => $edit['options[expose][label]']]);
$this->assertEqual($display['display_options']['sorts']['created']['order'], 'DESC');
}
}

View file

@ -150,7 +150,7 @@ class HandlerTest extends UITestBase {
$result = $this->xpath('//a[contains(@href, :href)]', array(':href' => $href));
$this->assertEqual(count($result), 1, SafeMarkup::format('Handler (%type) edit link found.', array('%type' => $type)));
$text = t('Broken/missing handler');
$text = 'Broken/missing handler';
$this->assertIdentical((string) $result[0], $text, 'Ensure the broken handler text was found.');

View file

@ -0,0 +1,60 @@
<?php
/**
* @file
* Contains \Drupal\views_ui\Tests\ReportFieldsTest.
*/
namespace Drupal\views_ui\Tests;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Tests the Views fields report page.
*
* @group views_ui
*/
class ReportFieldsTest extends UITestBase {
/**
* {@inheritdoc}
*/
public static $testViews = ['test_field_field_test'];
/**
* {@inheritdoc}
*/
public static $modules = ['entity_test'];
/**
* Tests the Views fields report page.
*/
public function testReportFields() {
$this->drupalGet('admin/reports/fields/views-fields');
$this->assertRaw('Used in views', 'Title appears correctly');
$this->assertRaw('No fields have been used in views yet.', 'No results message appears correctly.');
// Set up the field_test field.
$field_storage = FieldStorageConfig::create([
'field_name' => 'field_test',
'type' => 'integer',
'entity_type' => 'entity_test',
]);
$field_storage->save();
$field = FieldConfig::create([
'field_name' => 'field_test',
'entity_type' => 'entity_test',
'bundle' => 'entity_test',
]);
$field->save();
$this->drupalGet('admin/reports/fields/views-fields');
// Assert that the newly created field appears in the overview.
$this->assertRaw('<td>field_test</td>', 'Field name appears correctly');
$this->assertRaw('>test_field_field_test</a>', 'View name appears correctly');
$this->assertRaw('Used in views', 'Title appears correctly');
}
}

View file

@ -21,6 +21,14 @@ class SettingsTest extends UITestBase {
*/
protected $adminUser;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->drupalPlaceBlock('local_tasks_block');
}
/**
* Tests the settings for the edit ui.
*/

View file

@ -7,7 +7,7 @@
namespace Drupal\views_ui\Tests;
use Drupal\views\Tests\ViewUnitTestBase;
use Drupal\views\Tests\ViewKernelTestBase;
use Drupal\views_ui\Controller\ViewsUIController;
/**
@ -15,7 +15,7 @@ use Drupal\views_ui\Controller\ViewsUIController;
*
* @group views_ui
*/
class TagTest extends ViewUnitTestBase {
class TagTest extends ViewKernelTestBase {
/**
* Modules to enable.

View file

@ -0,0 +1,74 @@
<?php
/**
* @file
* Contains \Drupal\views_ui\Tests\ViewsListTest.
*/
namespace Drupal\views_ui\Tests;
use Drupal\simpletest\WebTestBase;
use Drupal\views\Entity\View;
use Drupal\views\Views;
/**
* Tests the views list.
*
* @group views_ui
*/
class ViewsListTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('block', 'views_ui');
/**
* A user with permission to administer views.
*
* @var \Drupal\user\Entity\User
*/
protected $adminUser;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->drupalPlaceBlock('local_tasks_block');
$this->drupalPlaceBlock('local_actions_block');
$this->adminUser = $this->drupalCreateUser(['administer views']);
$this->drupalLogin($this->adminUser);
}
/**
* Tests that the views list does not use a pager.
*/
public function testViewsListLimit() {
// Check if we can access the main views admin page.
$this->drupalGet('admin/structure/views');
$this->assertResponse(200);
$this->assertLink(t('Add new view'));
// Count default views to be subtracted from the limit.
$views = count(Views::getEnabledViews());
// Create multiples views.
$limit = 51;
$values = $this->config('views.view.test_view_storage')->get();
for ($i = 1; $i <= $limit - $views; $i++) {
$values['id'] = 'test_view_storage_new' . $i;
unset($values['uuid']);
$created = View::create($values);
$created->save();
}
$this->drupalGet('admin/structure/views');
// Check that all the rows are listed.
$this->assertEqual(count($this->xpath('//tbody/tr[contains(@class,"views-ui-list-enabled")]')), $limit);
}
}

View file

@ -23,10 +23,10 @@ class XssTest extends UITestBase {
public function testViewsUi() {
$this->drupalGet('admin/structure/views');
$this->assertRaw('&lt;script&gt;alert(&quot;foo&quot;);&lt;/script&gt;, &lt;marquee&gt;test&lt;/marquee&gt;', 'The view tag is properly escaped.');
$this->assertEscaped('<script>alert("foo");</script>, <marquee>test</marquee>', 'The view tag is properly escaped.');
$this->drupalGet('admin/structure/views/view/sa_contrib_2013_035');
$this->assertRaw('&amp;lt;marquee&amp;gt;test&amp;lt;/marquee&amp;gt;', 'Field admin label is properly escaped.');
$this->assertEscaped('<marquee>test</marquee>', 'Field admin label is properly escaped.');
$this->drupalGet('admin/structure/views/nojs/handler/sa_contrib_2013_035/page_1/header/area');
$this->assertRaw('[title] == &amp;lt;marquee&amp;gt;test&amp;lt;/marquee&amp;gt;', 'Token label is properly escaped.');

View file

@ -192,7 +192,7 @@ class ViewAddForm extends ViewFormBase {
return;
}
$this->entity->save();
drupal_set_message($this->t('The view %name has been saved.', array('%name' => $form_state->getValue('label'))));
$form_state->setRedirectUrl($this->entity->urlInfo('edit-form'));
}

View file

@ -414,13 +414,20 @@ class ViewEditForm extends ViewFormBase {
elseif ($view->status() && $view->getExecutable()->displayHandlers->get($display['id'])->hasPath()) {
$path = $view->getExecutable()->displayHandlers->get($display['id'])->getPath();
if ($path && (strpos($path, '%') === FALSE)) {
$uri = "base:$path";
if (!parse_url($path, PHP_URL_SCHEME)) {
// @todo Views should expect and store a leading /. See:
// https://www.drupal.org/node/2423913
$url = Url::fromUserInput('/' . ltrim($uri, '/'));
}
else {
$url = Url::fromUri($uri);
}
$build['top']['actions']['path'] = array(
'#type' => 'link',
'#title' => $this->t('View !display_title', array('!display_title' => $display_title)),
'#options' => array('alt' => array($this->t("Go to the real page for this display"))),
// @todo Use Url::fromPath() once
// https://www.drupal.org/node/2351379 is resolved.
'#url' => Url::fromUri("base:$path"),
'#url' => $url,
'#prefix' => '<li class="view">',
"#suffix" => '</li>',
);
@ -487,7 +494,7 @@ class ViewEditForm extends ViewFormBase {
$build['top']['display_title'] = array(
'#theme' => 'views_ui_display_tab_setting',
'#description' => $this->t('Display name'),
'#link' => $view->getExecutable()->displayHandlers->get($display['id'])->optionLink(SafeMarkup::checkPlain($display_title), 'display_title'),
'#link' => $view->getExecutable()->displayHandlers->get($display['id'])->optionLink($display_title, 'display_title'),
);
}
@ -661,12 +668,10 @@ class ViewEditForm extends ViewFormBase {
// Regenerate the main display area.
$build = $this->getDisplayTab($view);
static::addMicroweights($build);
$response->addCommand(new HtmlCommand('#views-tab-' . $display_id, $build));
// Regenerate the top area so changes to display names and order will appear.
$build = $this->renderDisplayTop($view);
static::addMicroweights($build);
$response->addCommand(new ReplaceCommand('#views-display-top', $build));
}
@ -1055,7 +1060,7 @@ class ViewEditForm extends ViewFormBase {
continue;
}
$field_name = SafeMarkup::checkPlain($handler->adminLabel(TRUE));
$field_name = $handler->adminLabel(TRUE);
if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
$field_name = '(' . $relationships[$field['relationship']] . ') ' . $field_name;
}
@ -1141,22 +1146,4 @@ class ViewEditForm extends ViewFormBase {
return $build;
}
/**
* Recursively adds microweights to a render array, similar to what
* \Drupal::formBuilder()->doBuildForm() does for forms.
*
* @todo Submit a core patch to fix drupal_render() to do this, so that all
* render arrays automatically preserve array insertion order, as forms do.
*/
public static function addMicroweights(&$build) {
$count = 0;
foreach (Element::children($build) as $key) {
if (!isset($build[$key]['#weight'])) {
$build[$key]['#weight'] = $count/1000;
}
static::addMicroweights($build[$key]);
$count++;
}
}
}

View file

@ -7,7 +7,6 @@
namespace Drupal\views_ui;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
@ -30,6 +29,11 @@ class ViewListBuilder extends ConfigEntityListBuilder {
*/
protected $displayManager;
/**
* {@inheritdoc}
*/
protected $limit;
/**
* {@inheritdoc}
*/
@ -55,6 +59,11 @@ class ViewListBuilder extends ConfigEntityListBuilder {
parent::__construct($entity_type, $storage);
$this->displayManager = $display_manager;
// This list builder uses client-side filters which requires all entities to
// be listed, disable the pager.
// @todo https://www.drupal.org/node/2536826 change the filtering to support
// a pager.
$this->limit = FALSE;
}
/**
@ -81,12 +90,6 @@ class ViewListBuilder extends ConfigEntityListBuilder {
*/
public function buildRow(EntityInterface $view) {
$row = parent::buildRow($view);
$display_paths = '';
$separator = '';
foreach ($this->getDisplayPaths($view) as $display_path) {
$display_paths .= $separator . SafeMarkup::escape($display_path);
$separator = ', ';
}
return array(
'data' => array(
'view_name' => array(
@ -98,12 +101,18 @@ class ViewListBuilder extends ConfigEntityListBuilder {
),
'description' => array(
'data' => array(
'#markup' => SafeMarkup::checkPlain($view->get('description')),
'#plain_text' => $view->get('description'),
),
'class' => array('views-table-filter-text-source'),
),
'tag' => $view->get('tag'),
'path' => SafeMarkup::set($display_paths),
'path' => array(
'data' => array(
'#theme' => 'item_list',
'#items' => $this->getDisplayPaths($view),
'#context' => ['list_style' => 'comma-list'],
),
),
'operations' => $row['operations'],
),
'title' => $this->t('Machine name: @name', array('@name' => $view->id())),
@ -268,7 +277,7 @@ class ViewListBuilder extends ConfigEntityListBuilder {
$all_paths[] = \Drupal::l('/' . $path, Url::fromUserInput('/' . $path));
}
else {
$all_paths[] = SafeMarkup::checkPlain('/' . $path);
$all_paths[] = '/' . $path;
}
}
}