Update core 8.3.0

This commit is contained in:
Rob Davies 2017-04-13 15:53:35 +01:00
parent da7a7918f8
commit cd7a898e66
6144 changed files with 132297 additions and 87747 deletions

View file

@ -33,10 +33,10 @@ class EditorDialogSave implements CommandInterface {
* {@inheritdoc}
*/
public function render() {
return array(
return [
'command' => 'editorDialogSave',
'values' => $this->values,
);
];
}
}

View file

@ -38,7 +38,7 @@ class EditorController extends ControllerBase {
// Direct text editing is only supported for single-valued fields.
$field = $entity->getTranslation($langcode)->$field_name;
$editable_text = check_markup($field->value, $field->format, $langcode, array(FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE));
$editable_text = check_markup($field->value, $field->format, $langcode, [FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE]);
$response->addCommand(new GetUntransformedTextCommand($editable_text));
return $response;

View file

@ -35,7 +35,7 @@ class Standard extends Xss implements EditorXssFilterInterface {
// directly.
// <iframe> is considered safe because it only allows HTML content to be
// embedded, hence ensuring the same origin policy always applies.
$dangerous_tags = array('script', 'style', 'link', 'embed', 'object');
$dangerous_tags = ['script', 'style', 'link', 'embed', 'object'];
// Simply blacklisting these five dangerous tags would bring safety, but
// also user frustration: what if a text format is configured to allow
@ -130,13 +130,13 @@ class Standard extends Xss implements EditorXssFilterInterface {
*/
protected static function getAllowedTags($restrictions) {
if ($restrictions === FALSE || !isset($restrictions['allowed'])) {
return array();
return [];
}
$allowed_tags = array_keys($restrictions['allowed']);
// Exclude the wildcard tag, which is used to set attribute restrictions on
// all tags simultaneously.
$allowed_tags = array_diff($allowed_tags, array('*'));
$allowed_tags = array_diff($allowed_tags, ['*']);
return $allowed_tags;
}
@ -154,7 +154,7 @@ class Standard extends Xss implements EditorXssFilterInterface {
*/
protected static function getForbiddenTags($restrictions) {
if ($restrictions === FALSE || !isset($restrictions['forbidden_tags'])) {
return array();
return [];
}
else {
return $restrictions['forbidden_tags'];

View file

@ -32,7 +32,7 @@ class Element {
/**
* Additional #pre_render callback for 'text_format' elements.
*/
function preRenderTextFormat(array $element) {
public function preRenderTextFormat(array $element) {
// Allow modules to programmatically enforce no client-side editor by
// setting the #editor property to FALSE.
if (isset($element['#editor']) && !$element['#editor']) {
@ -64,14 +64,14 @@ class Element {
if (!$element['format']['format']['#access']) {
// Use the first (and only) available text format.
$format_id = $format_ids[0];
$element['format']['editor'] = array(
$element['format']['editor'] = [
'#type' => 'hidden',
'#name' => $element['format']['format']['#name'],
'#value' => $format_id,
'#attributes' => array(
'#attributes' => [
'data-editor-for' => $field_id,
),
);
],
];
}
// Otherwise, attach to text format selector.
else {

View file

@ -49,14 +49,14 @@ class Editor extends ConfigEntityBase implements EditorInterface {
*
* @var array
*/
protected $settings = array();
protected $settings = [];
/**
* The structured array of image upload settings.
*
* @var array
*/
protected $image_upload = array();
protected $image_upload = [];
/**
* The filter format this text editor is associated with.

View file

@ -94,26 +94,26 @@ class EditorImageDialog extends FormBase {
$existing_file = isset($image_element['data-entity-uuid']) ? \Drupal::entityManager()->loadEntityByUuid('file', $image_element['data-entity-uuid']) : NULL;
$fid = $existing_file ? $existing_file->id() : NULL;
$form['fid'] = array(
$form['fid'] = [
'#title' => $this->t('Image'),
'#type' => 'managed_file',
'#upload_location' => $image_upload['scheme'] . '://' . $image_upload['directory'],
'#default_value' => $fid ? array($fid) : NULL,
'#upload_validators' => array(
'file_validate_extensions' => array('gif png jpg jpeg'),
'file_validate_size' => array($max_filesize),
'file_validate_image_resolution' => array($max_dimensions),
),
'#default_value' => $fid ? [$fid] : NULL,
'#upload_validators' => [
'file_validate_extensions' => ['gif png jpg jpeg'],
'file_validate_size' => [$max_filesize],
'file_validate_image_resolution' => [$max_dimensions],
],
'#required' => TRUE,
);
];
$form['attributes']['src'] = array(
$form['attributes']['src'] = [
'#title' => $this->t('URL'),
'#type' => 'textfield',
'#default_value' => isset($image_element['src']) ? $image_element['src'] : '',
'#maxlength' => 2048,
'#required' => TRUE,
);
];
// If the editor has image uploads enabled, show a managed_file form item,
// otherwise show a (file URL) text form item.
@ -137,7 +137,7 @@ class EditorImageDialog extends FormBase {
if ($alt === '' && !empty($image_element['src'])) {
$alt = '""';
}
$form['attributes']['alt'] = array(
$form['attributes']['alt'] = [
'#title' => $this->t('Alternative text'),
'#placeholder' => $this->t('Short description for the visually impaired'),
'#type' => 'textfield',
@ -145,51 +145,51 @@ class EditorImageDialog extends FormBase {
'#required_error' => $this->t('Alternative text is required.<br />(Only in rare cases should this be left empty. To create empty alternative text, enter <code>""</code> — two double quotes without any content).'),
'#default_value' => $alt,
'#maxlength' => 2048,
);
];
// When Drupal core's filter_align is being used, the text editor may
// offer the ability to change the alignment.
if (isset($image_element['data-align']) && $editor->getFilterFormat()->filters('filter_align')->status) {
$form['align'] = array(
$form['align'] = [
'#title' => $this->t('Align'),
'#type' => 'radios',
'#options' => array(
'#options' => [
'none' => $this->t('None'),
'left' => $this->t('Left'),
'center' => $this->t('Center'),
'right' => $this->t('Right'),
),
],
'#default_value' => $image_element['data-align'] === '' ? 'none' : $image_element['data-align'],
'#wrapper_attributes' => array('class' => array('container-inline')),
'#attributes' => array('class' => array('container-inline')),
'#parents' => array('attributes', 'data-align'),
);
'#wrapper_attributes' => ['class' => ['container-inline']],
'#attributes' => ['class' => ['container-inline']],
'#parents' => ['attributes', 'data-align'],
];
}
// When Drupal core's filter_caption is being used, the text editor may
// offer the ability to in-place edit the image's caption: show a toggle.
if (isset($image_element['hasCaption']) && $editor->getFilterFormat()->filters('filter_caption')->status) {
$form['caption'] = array(
$form['caption'] = [
'#title' => $this->t('Caption'),
'#type' => 'checkbox',
'#default_value' => $image_element['hasCaption'] === 'true',
'#parents' => array('attributes', 'hasCaption'),
);
'#parents' => ['attributes', 'hasCaption'],
];
}
$form['actions'] = array(
$form['actions'] = [
'#type' => 'actions',
);
$form['actions']['save_modal'] = array(
];
$form['actions']['save_modal'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
// No regular submit-handler. This form only works via JavaScript.
'#submit' => array(),
'#ajax' => array(
'#submit' => [],
'#ajax' => [
'callback' => '::submitForm',
'event' => 'click',
),
);
],
];
return $form;
}
@ -202,22 +202,22 @@ class EditorImageDialog extends FormBase {
// Convert any uploaded files from the FID values to data-entity-uuid
// attributes and set data-entity-type to 'file'.
$fid = $form_state->getValue(array('fid', 0));
$fid = $form_state->getValue(['fid', 0]);
if (!empty($fid)) {
$file = $this->fileStorage->load($fid);
$file_url = file_create_url($file->getFileUri());
// Transform absolute image URLs to relative image URLs: prevent problems
// on multisite set-ups and prevent mixed content errors.
$file_url = file_url_transform_relative($file_url);
$form_state->setValue(array('attributes', 'src'), $file_url);
$form_state->setValue(array('attributes', 'data-entity-uuid'), $file->uuid());
$form_state->setValue(array('attributes', 'data-entity-type'), 'file');
$form_state->setValue(['attributes', 'src'], $file_url);
$form_state->setValue(['attributes', 'data-entity-uuid'], $file->uuid());
$form_state->setValue(['attributes', 'data-entity-type'], 'file');
}
// When the alt attribute is set to two double quotes, transform it to the
// empty string: two double quotes signify "empty alt attribute". See above.
if (trim($form_state->getValue(array('attributes', 'alt'))) === '""') {
$form_state->setValue(array('attributes', 'alt'), '');
if (trim($form_state->getValue(['attributes', 'alt'])) === '""') {
$form_state->setValue(['attributes', 'alt'], '');
}
if ($form_state->getErrors()) {

View file

@ -32,7 +32,7 @@ class EditorLinkDialog extends FormBase {
// The default values are set directly from \Drupal::request()->request,
// provided by the editor plugin opening the dialog.
$user_input = $form_state->getUserInput();
$input = isset($user_input['editor_object']) ? $user_input['editor_object'] : array();
$input = isset($user_input['editor_object']) ? $user_input['editor_object'] : [];
$form['#tree'] = TRUE;
$form['#attached']['library'][] = 'editor/drupal.editor.dialog';
@ -41,26 +41,26 @@ class EditorLinkDialog extends FormBase {
// Everything under the "attributes" key is merged directly into the
// generated link tag's attributes.
$form['attributes']['href'] = array(
$form['attributes']['href'] = [
'#title' => $this->t('URL'),
'#type' => 'textfield',
'#default_value' => isset($input['href']) ? $input['href'] : '',
'#maxlength' => 2048,
);
];
$form['actions'] = array(
$form['actions'] = [
'#type' => 'actions',
);
$form['actions']['save_modal'] = array(
];
$form['actions']['save_modal'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
// No regular submit-handler. This form only works via JavaScript.
'#submit' => array(),
'#ajax' => array(
'#submit' => [],
'#ajax' => [
'callback' => '::submitForm',
'event' => 'click',
),
);
],
];
return $form;
}

View file

@ -26,26 +26,56 @@ abstract class EditorBase extends PluginBase implements EditorPluginInterface {
* {@inheritdoc}
*/
public function getDefaultSettings() {
return array();
return [];
}
/**
* {@inheritdoc}
*
* @todo Remove in Drupal 9.0.0.
*/
public function settingsForm(array $form, FormStateInterface $form_state, Editor $editor) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.3.x and will be removed in 9.0.0.', E_USER_DEPRECATED);
return $form;
}
/**
* {@inheritdoc}
*
* @todo Remove in Drupal 9.0.0.
*/
public function settingsFormValidate(array $form, FormStateInterface $form_state) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.3.x and will be removed in 9.0.0.', E_USER_DEPRECATED);
}
/**
* {@inheritdoc}
*
* @todo Remove in Drupal 9.0.0.
*/
public function settingsFormSubmit(array $form, FormStateInterface $form_state) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.3.x and will be removed in 9.0.0.', E_USER_DEPRECATED);
}
/**
* {@inheritdoc}
*/
public function settingsFormSubmit(array $form, FormStateInterface $form_state) {
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
return $this->settingsForm($form, $form_state, $form_state->get('editor'));
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
return $this->settingsFormValidate($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
return $this->settingsFormSubmit($form, $form_state);
}
}

View file

@ -40,7 +40,7 @@ class EditorManager extends DefaultPluginManager {
* An array of translated text editor labels, keyed by ID.
*/
public function listOptions() {
$options = array();
$options = [];
foreach ($this->getDefinitions() as $key => $definition) {
$options[$key] = $definition['label'];
}
@ -59,9 +59,9 @@ class EditorManager extends DefaultPluginManager {
* @see \Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments()
*/
public function getAttachments(array $format_ids) {
$attachments = array('library' => array());
$attachments = ['library' => []];
$settings = array();
$settings = [];
foreach ($format_ids as $format_id) {
$editor = editor_load($format_id);
if (!$editor) {
@ -75,20 +75,20 @@ class EditorManager extends DefaultPluginManager {
$attachments['library'] = array_merge($attachments['library'], $plugin->getLibraries($editor));
// Format-specific JavaScript settings.
$settings['editor']['formats'][$format_id] = array(
$settings['editor']['formats'][$format_id] = [
'format' => $format_id,
'editor' => $editor->getEditor(),
'editorSettings' => $plugin->getJSSettings($editor),
'editorSupportsContentFiltering' => $plugin_definition['supports_content_filtering'],
'isXssSafe' => $plugin_definition['is_xss_safe'],
);
];
}
// Allow other modules to alter all JavaScript settings.
$this->moduleHandler->alter('editor_js_settings', $settings);
if (empty($attachments['library']) && empty($settings)) {
return array();
return [];
}
$attachments['drupalSettings'] = $settings;

View file

@ -3,7 +3,7 @@
namespace Drupal\editor\Plugin;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\editor\Entity\Editor;
/**
@ -12,12 +12,17 @@ use Drupal\editor\Entity\Editor;
* Modules implementing this interface may want to extend the EditorBase class,
* which provides default implementations of each method where appropriate.
*
* If the editor's behavior depends on extensive options and/or external data,
* then the implementing module can choose to provide a separate, global
* configuration page rather than per-text-format settings. In that case, this
* form should provide a link to the separate settings page.
*
* @see \Drupal\editor\Annotation\Editor
* @see \Drupal\editor\Plugin\EditorBase
* @see \Drupal\editor\Plugin\EditorManager
* @see plugin_api
*/
interface EditorPluginInterface extends PluginInspectionInterface {
interface EditorPluginInterface extends PluginInspectionInterface, PluginFormInterface {
/**
* Returns the default settings for this configurable text editor.
@ -28,53 +33,6 @@ interface EditorPluginInterface extends PluginInspectionInterface {
*/
public function getDefaultSettings();
/**
* Returns a settings form to configure this text editor.
*
* If the editor's behavior depends on extensive options and/or external data,
* then the implementing module can choose to provide a separate, global
* configuration page rather than per-text-format settings. In that case, this
* form should provide a link to the separate settings page.
*
* @param array $form
* An empty form array to be populated with a configuration form, if any.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The state of the entire filter administration form.
* @param \Drupal\editor\Entity\Editor $editor
* A configured text editor object.
*
* @return array
* A render array for the settings form.
*/
public function settingsForm(array $form, FormStateInterface $form_state, Editor $editor);
/**
* Validates the settings form for an editor.
*
* The contents of the editor settings are located in
* $form_state->getValue(array('editor', 'settings')). Calls to $form_state->setError()
* should reflect this location in the settings form.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function settingsFormValidate(array $form, FormStateInterface $form_state);
/**
* Modifies any values in the form state to prepare them for saving.
*
* Values in $form_state->getValue(array('editor', 'settings')) are saved by
* Editor module in editor_form_filter_admin_format_submit().
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function settingsFormSubmit(array $form, FormStateInterface $form_state);
/**
* Returns JavaScript settings to be attached.
*

View file

@ -68,7 +68,7 @@ class EditorFileReference extends FilterBase implements ContainerFactoryPluginIn
if (stristr($text, 'data-entity-type="file"') !== FALSE) {
$dom = Html::load($text);
$xpath = new \DOMXPath($dom);
$processed_uuids = array();
$processed_uuids = [];
foreach ($xpath->query('//*[@data-entity-type="file" and @data-entity-uuid]') as $node) {
$uuid = $node->getAttribute('data-entity-uuid');

View file

@ -43,7 +43,7 @@ class Editor extends PluginBase implements InPlaceEditorInterface {
/**
* {@inheritdoc}
*/
function getMetadata(FieldItemListInterface $items) {
public function getMetadata(FieldItemListInterface $items) {
$format_id = $items[0]->format;
$metadata['format'] = $format_id;
$metadata['formatHasTransformations'] = $this->textFormatHasTransformationFilters($format_id);
@ -60,7 +60,7 @@ class Editor extends PluginBase implements InPlaceEditorInterface {
*/
protected function textFormatHasTransformationFilters($format_id) {
$format = FilterFormat::load($format_id);
return (bool) count(array_intersect(array(FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE), $format->getFiltertypes()));
return (bool) count(array_intersect([FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE], $format->getFiltertypes()));
}
/**
@ -74,7 +74,7 @@ class Editor extends PluginBase implements InPlaceEditorInterface {
$definitions = $manager->getDefinitions();
// Filter the current user's formats to those that support inline editing.
$formats = array();
$formats = [];
foreach ($user_format_ids as $format_id) {
if ($editor = editor_load($format_id)) {
$editor_id = $editor->getEditor();

View file

@ -20,7 +20,7 @@ class EditorAdminTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('filter', 'editor');
public static $modules = ['filter', 'editor'];
/**
* A user with the 'administer filters' permission.
@ -33,16 +33,16 @@ class EditorAdminTest extends WebTestBase {
parent::setUp();
// Add text format.
$filtered_html_format = FilterFormat::create(array(
$filtered_html_format = FilterFormat::create([
'format' => 'filtered_html',
'name' => 'Filtered HTML',
'weight' => 0,
'filters' => array(),
));
'filters' => [],
]);
$filtered_html_format->save();
// Create admin user.
$this->adminUser = $this->drupalCreateUser(array('administer filters'));
$this->adminUser = $this->drupalCreateUser(['administer filters']);
}
/**
@ -83,9 +83,9 @@ class EditorAdminTest extends WebTestBase {
$this->verifyUnicornEditorConfiguration('filtered_html', FALSE);
// Switch back to 'None' and check the Unicorn Editor's settings are gone.
$edit = array(
$edit = [
'editor[editor]' => '',
);
];
$this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
$unicorn_setting = $this->xpath('//input[@name="editor[settings][ponies_too]" and @type="checkbox" and @checked]');
$this->assertTrue(count($unicorn_setting) === 0, "Unicorn Editor's settings form is no longer present.");
@ -135,7 +135,7 @@ class EditorAdminTest extends WebTestBase {
$this->drupalLogin($account);
// The node edit page header.
$text = t('<em>Edit @type</em> @title', array('@type' => $node_type->label(), '@title' => $node->label()));
$text = t('<em>Edit @type</em> @title', ['@type' => $node_type->label(), '@title' => $node->label()]);
// Go to node edit form.
$this->drupalGet('node/' . $node->id() . '/edit');
@ -162,10 +162,10 @@ class EditorAdminTest extends WebTestBase {
$this->drupalLogin($this->adminUser);
$this->drupalGet('admin/config/content/formats/add');
// Configure the text format name.
$edit = array(
$edit = [
'name' => $format_name,
'format' => $format_id,
);
];
$edit += $this->selectUnicornEditor();
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
}
@ -175,7 +175,7 @@ class EditorAdminTest extends WebTestBase {
*/
protected function enableUnicornEditor() {
if (!$this->container->get('module_handler')->moduleExists('editor_test')) {
$this->container->get('module_installer')->install(array('editor_test'));
$this->container->get('module_installer')->install(['editor_test']);
}
}
@ -200,9 +200,9 @@ class EditorAdminTest extends WebTestBase {
$this->assertNoRaw(t('This option is disabled because no modules that provide a text editor are currently enabled.'), 'Description for select absent that tells users to install a text editor module.');
// Select the "Unicorn Editor" editor and click the "Configure" button.
$edit = array(
$edit = [
'editor[editor]' => 'unicorn',
);
];
$this->drupalPostAjaxForm(NULL, $edit, 'editor_configure');
$unicorn_setting = $this->xpath('//input[@name="editor[settings][ponies_too]" and @type="checkbox" and @checked]');
$this->assertTrue(count($unicorn_setting), "Unicorn Editor's settings form is present.");

View file

@ -1,83 +0,0 @@
<?php
namespace Drupal\editor\Tests;
use Drupal\Core\Url;
use Drupal\editor\Entity\Editor;
use Drupal\Tests\BrowserTestBase;
/**
* Test access to the editor dialog forms.
*
* @group editor
*/
class EditorDialogAccessTest extends BrowserTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = ['editor', 'filter', 'ckeditor'];
/**
* Test access to the editor image dialog.
*/
public function testEditorImageDialogAccess() {
$url = Url::fromRoute('editor.image_dialog', ['editor' => 'plain_text']);
$session = $this->assertSession();
// With no text editor, expect a 404.
$this->drupalGet($url);
$session->statusCodeEquals(404);
// With a text editor but without image upload settings, expect a 200, but
// there should not be an input[type=file].
$editor = Editor::create([
'editor' => 'ckeditor',
'format' => 'plain_text',
'settings' => [
'toolbar' => [
'rows' => [
[
[
'name' => 'Media',
'items' => [
'DrupalImage',
],
],
],
],
],
'plugins' => [],
],
'image_upload' => [
'status' => FALSE,
'scheme' => 'public',
'directory' => 'inline-images',
'max_size' => '',
'max_dimensions' => [
'width' => 0,
'height' => 0,
],
],
]);
$editor->save();
$this->resetAll();
$this->drupalGet($url);
$this->assertTrue($this->cssSelect('input[type=text][name="attributes[src]"]'), 'Image uploads disabled: input[type=text][name="attributes[src]"] is present.');
$this->assertFalse($this->cssSelect('input[type=file]'), 'Image uploads disabled: input[type=file] is absent.');
$session->statusCodeEquals(200);
// With image upload settings, expect a 200, and now there should be an
// input[type=file].
$editor->setImageUploadSettings(['status' => TRUE] + $editor->getImageUploadSettings())
->save();
$this->resetAll();
$this->drupalGet($url);
$this->assertFalse($this->cssSelect('input[type=text][name="attributes[src]"]'), 'Image uploads enabled: input[type=text][name="attributes[src]"] is absent.');
$this->assertTrue($this->cssSelect('input[type=file]'), 'Image uploads enabled: input[type=file] is present.');
$session->statusCodeEquals(200);
}
}

View file

@ -20,7 +20,7 @@ class EditorLoadingTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('filter', 'editor', 'editor_test', 'node');
public static $modules = ['filter', 'editor', 'editor_test', 'node'];
/**
* An untrusted user, with access to the 'plain_text' format.
@ -51,57 +51,57 @@ class EditorLoadingTest extends WebTestBase {
\Drupal::service('plugin.manager.editor')->clearCachedDefinitions();
// Add text formats.
$filtered_html_format = FilterFormat::create(array(
$filtered_html_format = FilterFormat::create([
'format' => 'filtered_html',
'name' => 'Filtered HTML',
'weight' => 0,
'filters' => array(),
));
'filters' => [],
]);
$filtered_html_format->save();
$full_html_format = FilterFormat::create(array(
$full_html_format = FilterFormat::create([
'format' => 'full_html',
'name' => 'Full HTML',
'weight' => 1,
'filters' => array(),
));
'filters' => [],
]);
$full_html_format->save();
// Create article node type.
$this->drupalCreateContentType(array(
$this->drupalCreateContentType([
'type' => 'article',
'name' => 'Article',
));
]);
// Create page node type, but remove the body.
$this->drupalCreateContentType(array(
$this->drupalCreateContentType([
'type' => 'page',
'name' => 'Page',
));
]);
$body = FieldConfig::loadByName('node', 'page', 'body');
$body->delete();
// Create a formatted text field, which uses an <input type="text">.
FieldStorageConfig::create(array(
FieldStorageConfig::create([
'field_name' => 'field_text',
'entity_type' => 'node',
'type' => 'text',
))->save();
])->save();
FieldConfig::create(array(
FieldConfig::create([
'field_name' => 'field_text',
'entity_type' => 'node',
'label' => 'Textfield',
'bundle' => 'page',
))->save();
])->save();
entity_get_form_display('node', 'page', 'default')
->setComponent('field_text')
->save();
// Create 3 users, each with access to different text formats.
$this->untrustedUser = $this->drupalCreateUser(array('create article content', 'edit any article content'));
$this->normalUser = $this->drupalCreateUser(array('create article content', 'edit any article content', 'use text format filtered_html'));
$this->privilegedUser = $this->drupalCreateUser(array('create article content', 'edit any article content', 'create page content', 'edit any page content', 'use text format filtered_html', 'use text format full_html'));
$this->untrustedUser = $this->drupalCreateUser(['create article content', 'edit any article content']);
$this->normalUser = $this->drupalCreateUser(['create article content', 'edit any article content', 'use text format filtered_html']);
$this->privilegedUser = $this->drupalCreateUser(['create article content', 'edit any article content', 'create page content', 'edit any page content', 'use text format filtered_html', 'use text format full_html']);
}
/**
@ -112,13 +112,13 @@ class EditorLoadingTest extends WebTestBase {
$editor = Editor::create([
'format' => 'full_html',
'editor' => 'unicorn',
'image_upload' => array(
'image_upload' => [
'status' => FALSE,
'scheme' => file_default_scheme(),
'directory' => 'inline-images',
'max_size' => '',
'max_dimensions' => array('width' => '', 'height' => ''),
)
'max_dimensions' => ['width' => '', 'height' => ''],
]
]);
$editor->save();
@ -140,13 +140,13 @@ class EditorLoadingTest extends WebTestBase {
$this->drupalLogin($this->privilegedUser);
$this->drupalGet('node/add/article');
list($settings, $editor_settings_present, $editor_js_present, $body, $format_selector) = $this->getThingsToCheck('body');
$expected = array('formats' => array('full_html' => array(
$expected = ['formats' => ['full_html' => [
'format' => 'full_html',
'editor' => 'unicorn',
'editorSettings' => array('ponyModeEnabled' => TRUE),
'editorSettings' => ['ponyModeEnabled' => TRUE],
'editorSupportsContentFiltering' => TRUE,
'isXssSafe' => FALSE,
)));
]]];
$this->assertTrue($editor_settings_present, "Text Editor module's JavaScript settings are on the page.");
$this->assertIdentical($expected, $settings['editor'], "Text Editor module's JavaScript settings on the page are correct.");
$this->assertTrue($editor_js_present, 'Text Editor JavaScript is present.');
@ -174,13 +174,13 @@ class EditorLoadingTest extends WebTestBase {
$this->drupalLogin($this->untrustedUser);
$this->drupalGet('node/add/article');
list($settings, $editor_settings_present, $editor_js_present, $body, $format_selector) = $this->getThingsToCheck('body');
$expected = array('formats' => array('plain_text' => array(
$expected = ['formats' => ['plain_text' => [
'format' => 'plain_text',
'editor' => 'unicorn',
'editorSettings' => array('ponyModeEnabled' => TRUE),
'editorSettings' => ['ponyModeEnabled' => TRUE],
'editorSupportsContentFiltering' => TRUE,
'isXssSafe' => FALSE,
)));
]]];
$this->assertTrue($editor_settings_present, "Text Editor module's JavaScript settings are on the page.");
$this->assertIdentical($expected, $settings['editor'], "Text Editor module's JavaScript settings on the page are correct.");
$this->assertTrue($editor_js_present, 'Text Editor JavaScript is present.');
@ -191,12 +191,12 @@ class EditorLoadingTest extends WebTestBase {
// Create an "article" node that uses the full_html text format, then try
// to let the untrusted user edit it.
$this->drupalCreateNode(array(
$this->drupalCreateNode([
'type' => 'article',
'body' => array(
array('value' => $this->randomMachineName(32), 'format' => 'full_html')
),
));
'body' => [
['value' => $this->randomMachineName(32), 'format' => 'full_html']
],
]);
// The untrusted user tries to edit content that is written in a text format
// that (s)he is not allowed to use. The editor is still loaded. CKEditor,
@ -220,23 +220,23 @@ class EditorLoadingTest extends WebTestBase {
$editor = Editor::create([
'format' => 'full_html',
'editor' => 'unicorn',
'image_upload' => array(
'image_upload' => [
'status' => FALSE,
'scheme' => file_default_scheme(),
'directory' => 'inline-images',
'max_size' => '',
'max_dimensions' => array('width' => '', 'height' => ''),
)
'max_dimensions' => ['width' => '', 'height' => ''],
]
]);
$editor->save();
// Create an "page" node that uses the full_html text format.
$this->drupalCreateNode(array(
$this->drupalCreateNode([
'type' => 'page',
'field_text' => array(
array('value' => $this->randomMachineName(32), 'format' => 'full_html')
),
));
'field_text' => [
['value' => $this->randomMachineName(32), 'format' => 'full_html']
],
]);
// Assert the unicorn editor works with textfields.
$this->drupalLogin($this->privilegedUser);
@ -268,7 +268,7 @@ class EditorLoadingTest extends WebTestBase {
protected function getThingsToCheck($field_name, $type = 'textarea') {
$settings = $this->getDrupalSettings();
return array(
return [
// JavaScript settings.
$settings,
// Editor.module's JS settings present.
@ -279,7 +279,7 @@ class EditorLoadingTest extends WebTestBase {
$this->xpath('//' . $type . '[@id="edit-' . $field_name . '-0-value"]'),
// Format selector.
$this->xpath('//select[contains(@class, "filter-list")]'),
);
];
}
}

View file

@ -1,134 +0,0 @@
<?php
namespace Drupal\editor\Tests;
use Drupal\file\Entity\File;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
/**
* Tests Editor module's file reference filter with private files.
*
* @group editor
*/
class EditorPrivateFileReferenceFilterTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
// Needed for the config: this is the only module in core that utilizes the
// functionality in editor.module to be tested, and depends on that.
'ckeditor',
// Depends on filter.module (indirectly).
'node',
// Pulls in the config we're using during testing which create a text format
// - with the filter_html_image_secure filter DISABLED,
// - with the editor set to CKEditor,
// - with drupalimage.image_upload.scheme set to 'private',
// - with drupalimage.image_upload.directory set to ''.
'editor_private_test',
];
/**
* Tests the editor file reference filter with private files.
*/
function testEditorPrivateFileReferenceFilter() {
$author = $this->drupalCreateUser();
$this->drupalLogin($author);
// Create a content type with a body field.
$this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
// Create a file in the 'private:// ' stream.
$filename = 'test.png';
$src = '/system/files/' . $filename;
/** @var \Drupal\file\FileInterface $file */
$file = File::create([
'uri' => 'private://' . $filename,
]);
$file->setTemporary();
$file->setOwner($author);
// Create the file itself.
file_put_contents($file->getFileUri(), $this->randomString());
$file->save();
// The image should be visible for its author.
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(200);
// The not-yet-permanent image should NOT be visible for anonymous.
$this->drupalLogout();
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(403);
// Resave the file to be permanent.
$file->setPermanent();
$file->save();
// Create some nodes to ensure file usage count does not match the ID's
// of the nodes we are going to check.
for ($i = 0; $i < 5; $i++) {
$this->drupalCreateNode([
'type' => 'page',
'uid' => $author->id(),
]);
}
// Create a node with its body field properly pointing to the just-created
// file.
$published_node = $this->drupalCreateNode([
'type' => 'page',
'body' => [
'value' => '<img alt="alt" data-entity-type="file" data-entity-uuid="' . $file->uuid() . '" src="' . $src . '" />',
'format' => 'private_images',
],
'uid' => $author->id(),
]);
// Create an unpublished node with its body field properly pointing to the
// just-created file.
$unpublished_node = $this->drupalCreateNode([
'type' => 'page',
'status' => NODE_NOT_PUBLISHED,
'body' => [
'value' => '<img alt="alt" data-entity-type="file" data-entity-uuid="' . $file->uuid() . '" src="' . $src . '" />',
'format' => 'private_images',
],
'uid' => $author->id(),
]);
// Do the actual test. The image should be visible for anonymous users,
// because they can view the published node. Even though they can't view
// the unpublished node.
$this->drupalGet($published_node->toUrl());
$this->assertSession()->statusCodeEquals(200);
$this->drupalGet($unpublished_node->toUrl());
$this->assertSession()->statusCodeEquals(403);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(200);
// When the published node is also unpublished, the image should also
// become inaccessible to anonymous users.
$published_node->setPublished(FALSE)->save();
$this->drupalGet($published_node->toUrl());
$this->assertSession()->statusCodeEquals(403);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(403);
// Disallow anonymous users to view the entity, which then should also
// disallow them to view the image.
$published_node->setPublished(TRUE)->save();
Role::load(RoleInterface::ANONYMOUS_ID)
->revokePermission('access content')
->save();
$this->drupalGet($published_node->toUrl());
$this->assertSession()->statusCodeEquals(403);
$this->drupalGet($src);
$this->assertSession()->statusCodeEquals(403);
}
}

View file

@ -40,7 +40,7 @@ class EditorSecurityTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('filter', 'editor', 'editor_test', 'node');
public static $modules = ['filter', 'editor', 'editor_test', 'node'];
/**
* User with access to Restricted HTML text format without text editor.
@ -83,74 +83,74 @@ class EditorSecurityTest extends WebTestBase {
// With text formats 2, 3 and 5, we also associate a text editor that does
// not guarantee XSS safety. "restricted" means the text format has XSS
// filters on output, "unrestricted" means the opposite.
$format = FilterFormat::create(array(
$format = FilterFormat::create([
'format' => 'restricted_without_editor',
'name' => 'Restricted HTML, without text editor',
'weight' => 0,
'filters' => array(
'filters' => [
// A filter of the FilterInterface::TYPE_HTML_RESTRICTOR type.
'filter_html' => array(
'filter_html' => [
'status' => 1,
'settings' => array(
'settings' => [
'allowed_html' => '<h2> <h3> <h4> <h5> <h6> <p> <br> <strong> <a>',
)
),
),
));
]
],
],
]);
$format->save();
$format = FilterFormat::create(array(
$format = FilterFormat::create([
'format' => 'restricted_with_editor',
'name' => 'Restricted HTML, with text editor',
'weight' => 1,
'filters' => array(
'filters' => [
// A filter of the FilterInterface::TYPE_HTML_RESTRICTOR type.
'filter_html' => array(
'filter_html' => [
'status' => 1,
'settings' => array(
'settings' => [
'allowed_html' => '<h2> <h3> <h4> <h5> <h6> <p> <br> <strong> <a>',
)
),
),
));
]
],
],
]);
$format->save();
$editor = Editor::create([
'format' => 'restricted_with_editor',
'editor' => 'unicorn',
]);
$editor->save();
$format = FilterFormat::create(array(
$format = FilterFormat::create([
'format' => 'restricted_plus_dangerous_tag_with_editor',
'name' => 'Restricted HTML, dangerous tag allowed, with text editor',
'weight' => 1,
'filters' => array(
'filters' => [
// A filter of the FilterInterface::TYPE_HTML_RESTRICTOR type.
'filter_html' => array(
'filter_html' => [
'status' => 1,
'settings' => array(
'settings' => [
'allowed_html' => '<h2> <h3> <h4> <h5> <h6> <p> <br> <strong> <a> <embed>',
)
),
),
));
]
],
],
]);
$format->save();
$editor = Editor::create([
'format' => 'restricted_plus_dangerous_tag_with_editor',
'editor' => 'unicorn',
]);
$editor->save();
$format = FilterFormat::create(array(
$format = FilterFormat::create([
'format' => 'unrestricted_without_editor',
'name' => 'Unrestricted HTML, without text editor',
'weight' => 0,
'filters' => array(),
));
'filters' => [],
]);
$format->save();
$format = FilterFormat::create(array(
$format = FilterFormat::create([
'format' => 'unrestricted_with_editor',
'name' => 'Unrestricted HTML, with text editor',
'weight' => 1,
'filters' => array(),
));
'filters' => [],
]);
$format->save();
$editor = Editor::create([
'format' => 'unrestricted_with_editor',
@ -160,10 +160,10 @@ class EditorSecurityTest extends WebTestBase {
// Create node type.
$this->drupalCreateContentType(array(
$this->drupalCreateContentType([
'type' => 'article',
'name' => 'Article',
));
]);
// Create 4 users, each with access to different text formats/editors:
// - "untrusted": restricted_without_editor
@ -172,22 +172,22 @@ class EditorSecurityTest extends WebTestBase {
// - "privileged": restricted_without_editor, restricted_with_editor,
// restricted_plus_dangerous_tag_with_editor,
// unrestricted_without_editor and unrestricted_with_editor
$this->untrustedUser = $this->drupalCreateUser(array(
$this->untrustedUser = $this->drupalCreateUser([
'create article content',
'edit any article content',
'use text format restricted_without_editor',
));
$this->normalUser = $this->drupalCreateUser(array(
]);
$this->normalUser = $this->drupalCreateUser([
'create article content',
'edit any article content',
'use text format restricted_with_editor',
));
$this->trustedUser = $this->drupalCreateUser(array(
]);
$this->trustedUser = $this->drupalCreateUser([
'create article content',
'edit any article content',
'use text format restricted_plus_dangerous_tag_with_editor',
));
$this->privilegedUser = $this->drupalCreateUser(array(
]);
$this->privilegedUser = $this->drupalCreateUser([
'create article content',
'edit any article content',
'use text format restricted_without_editor',
@ -195,25 +195,25 @@ class EditorSecurityTest extends WebTestBase {
'use text format restricted_plus_dangerous_tag_with_editor',
'use text format unrestricted_without_editor',
'use text format unrestricted_with_editor',
));
]);
// Create an "article" node for each possible text format, with the same
// sample content, to do our tests on.
$samples = array(
array('author' => $this->untrustedUser->id(), 'format' => 'restricted_without_editor'),
array('author' => $this->normalUser->id(), 'format' => 'restricted_with_editor'),
array('author' => $this->trustedUser->id(), 'format' => 'restricted_plus_dangerous_tag_with_editor'),
array('author' => $this->privilegedUser->id(), 'format' => 'unrestricted_without_editor'),
array('author' => $this->privilegedUser->id(), 'format' => 'unrestricted_with_editor'),
);
$samples = [
['author' => $this->untrustedUser->id(), 'format' => 'restricted_without_editor'],
['author' => $this->normalUser->id(), 'format' => 'restricted_with_editor'],
['author' => $this->trustedUser->id(), 'format' => 'restricted_plus_dangerous_tag_with_editor'],
['author' => $this->privilegedUser->id(), 'format' => 'unrestricted_without_editor'],
['author' => $this->privilegedUser->id(), 'format' => 'unrestricted_with_editor'],
];
foreach ($samples as $sample) {
$this->drupalCreateNode(array(
$this->drupalCreateNode([
'type' => 'article',
'body' => array(
array('value' => self::$sampleContent, 'format' => $sample['format'])
),
'body' => [
['value' => self::$sampleContent, 'format' => $sample['format']]
],
'uid' => $sample['author']
));
]);
}
}
@ -222,65 +222,65 @@ class EditorSecurityTest extends WebTestBase {
*
* Tests 8 scenarios. Tests only with a text editor that is not XSS-safe.
*/
function testInitialSecurity() {
$expected = array(
array(
public function testInitialSecurity() {
$expected = [
[
'node_id' => 1,
'format' => 'restricted_without_editor',
// No text editor => no XSS filtering.
'value' => self::$sampleContent,
'users' => array(
'users' => [
$this->untrustedUser,
$this->privilegedUser,
),
),
array(
],
],
[
'node_id' => 2,
'format' => 'restricted_with_editor',
// Text editor => XSS filtering.
'value' => self::$sampleContentSecured,
'users' => array(
'users' => [
$this->normalUser,
$this->privilegedUser,
),
),
array(
],
],
[
'node_id' => 3,
'format' => 'restricted_plus_dangerous_tag_with_editor',
// Text editor => XSS filtering.
'value' => self::$sampleContentSecuredEmbedAllowed,
'users' => array(
'users' => [
$this->trustedUser,
$this->privilegedUser,
),
),
array(
],
],
[
'node_id' => 4,
'format' => 'unrestricted_without_editor',
// No text editor => no XSS filtering.
'value' => self::$sampleContent,
'users' => array(
'users' => [
$this->privilegedUser,
),
),
array(
],
],
[
'node_id' => 5,
'format' => 'unrestricted_with_editor',
// Text editor, no security filter => no XSS filtering.
'value' => self::$sampleContent,
'users' => array(
'users' => [
$this->privilegedUser,
),
),
);
],
],
];
// Log in as each user that may edit the content, and assert the value.
foreach ($expected as $case) {
foreach ($case['users'] as $account) {
$this->pass(format_string('Scenario: sample %sample_id, %format.', array(
$this->pass(format_string('Scenario: sample %sample_id, %format.', [
'%sample_id' => $case['node_id'],
'%format' => $case['format'],
)));
]));
$this->drupalLogin($account);
$this->drupalGet('node/' . $case['node_id'] . '/edit');
$dom_node = $this->xpath('//textarea[@id="edit-body-0-value"]');
@ -302,26 +302,26 @@ class EditorSecurityTest extends WebTestBase {
* format and contains a <script> tag to the Full HTML text format, the
* <script> tag would be executed. Unless we apply appropriate filtering.
*/
function testSwitchingSecurity() {
$expected = array(
array(
public function testSwitchingSecurity() {
$expected = [
[
'node_id' => 1,
'value' => self::$sampleContent, // No text editor => no XSS filtering.
'format' => 'restricted_without_editor',
'switch_to' => array(
'switch_to' => [
'restricted_with_editor' => self::$sampleContentSecured,
// Intersection of restrictions => most strict XSS filtering.
'restricted_plus_dangerous_tag_with_editor' => self::$sampleContentSecured,
// No text editor => no XSS filtering.
'unrestricted_without_editor' => FALSE,
'unrestricted_with_editor' => self::$sampleContentSecured,
),
),
array(
],
],
[
'node_id' => 2,
'value' => self::$sampleContentSecured, // Text editor => XSS filtering.
'format' => 'restricted_with_editor',
'switch_to' => array(
'switch_to' => [
// No text editor => no XSS filtering.
'restricted_without_editor' => FALSE,
// Intersection of restrictions => most strict XSS filtering.
@ -329,13 +329,13 @@ class EditorSecurityTest extends WebTestBase {
// No text editor => no XSS filtering.
'unrestricted_without_editor' => FALSE,
'unrestricted_with_editor' => self::$sampleContentSecured,
),
),
array(
],
],
[
'node_id' => 3,
'value' => self::$sampleContentSecuredEmbedAllowed, // Text editor => XSS filtering.
'format' => 'restricted_plus_dangerous_tag_with_editor',
'switch_to' => array(
'switch_to' => [
// No text editor => no XSS filtering.
'restricted_without_editor' => FALSE,
// Intersection of restrictions => most strict XSS filtering.
@ -344,13 +344,13 @@ class EditorSecurityTest extends WebTestBase {
'unrestricted_without_editor' => FALSE,
// Intersection of restrictions => most strict XSS filtering.
'unrestricted_with_editor' => self::$sampleContentSecured,
),
),
array(
],
],
[
'node_id' => 4,
'value' => self::$sampleContent, // No text editor => no XSS filtering.
'format' => 'unrestricted_without_editor',
'switch_to' => array(
'switch_to' => [
// No text editor => no XSS filtering.
'restricted_without_editor' => FALSE,
'restricted_with_editor' => self::$sampleContentSecured,
@ -360,13 +360,13 @@ class EditorSecurityTest extends WebTestBase {
// filters: resulting content when viewed was already vulnerable, so
// it must be intentional.
'unrestricted_with_editor' => FALSE,
),
),
array(
],
],
[
'node_id' => 5,
'value' => self::$sampleContentSecured, // Text editor => XSS filtering.
'format' => 'unrestricted_with_editor',
'switch_to' => array(
'switch_to' => [
// From editor, no security filters to security filters, no editor: no
// risk.
'restricted_without_editor' => FALSE,
@ -377,9 +377,9 @@ class EditorSecurityTest extends WebTestBase {
// filters: resulting content when viewed was already vulnerable, so
// it must be intentional.
'unrestricted_without_editor' => FALSE,
),
),
);
],
],
];
// Log in as the privileged user, and for every sample, do the following:
// - switch to every other text format/editor
@ -395,15 +395,15 @@ class EditorSecurityTest extends WebTestBase {
// Switch to every other text format/editor and verify the results.
foreach ($case['switch_to'] as $format => $expected_filtered_value) {
$this->pass(format_string('Scenario: sample %sample_id, switch from %original_format to %format.', array(
$this->pass(format_string('Scenario: sample %sample_id, switch from %original_format to %format.', [
'%sample_id' => $case['node_id'],
'%original_format' => $case['format'],
'%format' => $format,
)));
$post = array(
]));
$post = [
'value' => self::$sampleContent,
'original_format_id' => $case['format'],
);
];
$response = $this->drupalPostWithFormat('editor/filter_xss/' . $format, 'json', $post);
$this->assertResponse(200);
$json = Json::decode($response);
@ -415,7 +415,7 @@ class EditorSecurityTest extends WebTestBase {
/**
* Tests the standard text editor XSS filter being overridden.
*/
function testEditorXssFilterOverride() {
public function testEditorXssFilterOverride() {
// First: the Standard text editor XSS filter.
$this->drupalLogin($this->normalUser);
$this->drupalGet('node/2/edit');

View file

@ -19,47 +19,47 @@ class QuickEditIntegrationLoadingTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('quickedit', 'filter', 'node', 'editor');
public static $modules = ['quickedit', 'filter', 'node', 'editor'];
/**
* The basic permissions necessary to view content and use in-place editing.
*
* @var array
*/
protected static $basicPermissions = array('access content', 'create article content', 'use text format filtered_html', 'access contextual links');
protected static $basicPermissions = ['access content', 'create article content', 'use text format filtered_html', 'access contextual links'];
protected function setUp() {
parent::setUp();
// Create a text format.
$filtered_html_format = FilterFormat::create(array(
$filtered_html_format = FilterFormat::create([
'format' => 'filtered_html',
'name' => 'Filtered HTML',
'weight' => 0,
'filters' => array(
'filter_caption' => array(
'filters' => [
'filter_caption' => [
'status' => 1,
),
),
));
],
],
]);
$filtered_html_format->save();
// Create a node type.
$this->drupalCreateContentType(array(
$this->drupalCreateContentType([
'type' => 'article',
'name' => 'Article',
));
]);
// Create one node of the above node type using the above text format.
$this->drupalCreateNode(array(
$this->drupalCreateNode([
'type' => 'article',
'body' => array(
0 => array(
'body' => [
0 => [
'value' => '<p>Do you also love Drupal?</p><img src="druplicon.png" data-caption="Druplicon" />',
'format' => 'filtered_html',
)
)
));
]
]
]);
}
/**
@ -70,11 +70,11 @@ class QuickEditIntegrationLoadingTest extends WebTestBase {
// or both of the following permissions:
// - the 'access in-place editing' permission
// - the 'edit any article content' permission (necessary to edit node 1)
$users = array(
$users = [
$this->drupalCreateUser(static::$basicPermissions),
$this->drupalCreateUser(array_merge(static::$basicPermissions, array('edit any article content'))),
$this->drupalCreateUser(array_merge(static::$basicPermissions, array('access in-place editing')))
);
$this->drupalCreateUser(array_merge(static::$basicPermissions, ['edit any article content'])),
$this->drupalCreateUser(array_merge(static::$basicPermissions, ['access in-place editing']))
];
// Now test with each of the 3 users with insufficient permissions.
foreach ($users as $user) {
@ -84,10 +84,17 @@ class QuickEditIntegrationLoadingTest extends WebTestBase {
// Ensure the text is transformed.
$this->assertRaw('<p>Do you also love Drupal?</p><figure role="group" class="caption caption-img"><img src="druplicon.png" /><figcaption>Druplicon</figcaption></figure>');
// Retrieving the untransformed text should result in an empty 403 response.
$response = $this->drupalPost('editor/' . 'node/1/body/en/full', '', array(), array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax')));
// Retrieving the untransformed text should result in an 403 response and
// return a different error message depending of the missing permission.
$response = $this->drupalPost('editor/' . 'node/1/body/en/full', '', [], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
$this->assertResponse(403);
$this->assertIdentical('{}', $response);
if (!$user->hasPermission('access in-place editing')) {
$message = "A fatal error occurred: The 'access in-place editing' permission is required.";
$this->assertIdentical(Json::encode(['message' => $message]), $response);
}
else {
$this->assertIdentical('{}', $response);
}
}
}
@ -95,7 +102,7 @@ class QuickEditIntegrationLoadingTest extends WebTestBase {
* Test loading of untransformed text when a user does have access to it.
*/
public function testUserWithPermission() {
$user = $this->drupalCreateUser(array_merge(static::$basicPermissions, array('edit any article content', 'access in-place editing')));
$user = $this->drupalCreateUser(array_merge(static::$basicPermissions, ['edit any article content', 'access in-place editing']));
$this->drupalLogin($user);
$this->drupalGet('node/1');