updated core from 8.4 to 8.5 : bug with login_destination
This commit is contained in:
@@ -6,8 +6,8 @@ package: Core
|
||||
# core: 8.x
|
||||
configure: entity.action.collection
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
+1
@@ -3,6 +3,7 @@ label: Action configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
+7
@@ -2,6 +2,7 @@ id: d6_action
|
||||
label: Actions
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
source:
|
||||
plugin: action
|
||||
process:
|
||||
@@ -23,6 +24,12 @@ process:
|
||||
imagecache_flush_action: 0
|
||||
imagecache_generate_all_action: 0
|
||||
imagecache_generate_action: 0
|
||||
comment_publish_action: entity:publish_action:comment
|
||||
comment_unpublish_action: entity:unpublish_action:comment
|
||||
comment_save_action: entity:save_action:comment
|
||||
node_publish_action: entity:publish_action:node
|
||||
node_unpublish_action: entity:unpublish_action:node
|
||||
node_save_action: entity:save_action:node
|
||||
bypass: true
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
+7
@@ -2,6 +2,7 @@ id: d7_action
|
||||
label: Actions
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: action
|
||||
process:
|
||||
@@ -20,6 +21,12 @@ process:
|
||||
system_send_email_action: action_send_email_action
|
||||
system_message_action: action_message_action
|
||||
system_block_ip_action: 0
|
||||
comment_publish_action: entity:publish_action:comment
|
||||
comment_unpublish_action: entity:unpublish_action:comment
|
||||
comment_save_action: entity:save_action:comment
|
||||
node_publish_action: entity:publish_action:node
|
||||
node_unpublish_action: entity:unpublish_action:node
|
||||
node_save_action: entity:save_action:node
|
||||
bypass: true
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
@@ -2,67 +2,28 @@
|
||||
|
||||
namespace Drupal\action;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Action\ActionManager;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a form for action add forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionAddForm extends ActionFormBase {
|
||||
|
||||
/**
|
||||
* The action manager.
|
||||
*
|
||||
* @var \Drupal\Core\Action\ActionManager
|
||||
*/
|
||||
protected $actionManager;
|
||||
|
||||
/**
|
||||
* Constructs a new ActionAddForm.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The action storage.
|
||||
* @param \Drupal\Core\Action\ActionManager $action_manager
|
||||
* The action plugin manager.
|
||||
*/
|
||||
public function __construct(EntityStorageInterface $storage, ActionManager $action_manager) {
|
||||
parent::__construct($storage);
|
||||
|
||||
$this->actionManager = $action_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('action'),
|
||||
$container->get('plugin.manager.action')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $action_id
|
||||
* The hashed version of the action ID.
|
||||
* The action ID.
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $action_id = NULL) {
|
||||
// In \Drupal\action\Form\ActionAdminManageForm::buildForm() the action
|
||||
// are hashed. Here we have to decrypt it to find the desired action ID.
|
||||
foreach ($this->actionManager->getDefinitions() as $id => $definition) {
|
||||
$key = Crypt::hashBase64($id);
|
||||
if ($key === $action_id) {
|
||||
$this->entity->setPlugin($id);
|
||||
// Derive the label and type from the action definition.
|
||||
$this->entity->set('label', $definition['label']);
|
||||
$this->entity->set('type', $definition['type']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->entity->setPlugin($action_id);
|
||||
|
||||
// Derive the label and type from the action definition.
|
||||
$definition = $this->entity->getPluginDefinition();
|
||||
$this->entity->set('label', $definition['label']);
|
||||
$this->entity->set('type', $definition['type']);
|
||||
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace Drupal\action;
|
||||
|
||||
/**
|
||||
* Provides a form for action edit forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionEditForm extends ActionFormBase {
|
||||
|
||||
|
||||
@@ -13,13 +13,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
abstract class ActionFormBase extends EntityForm {
|
||||
|
||||
/**
|
||||
* The action plugin being configured.
|
||||
*
|
||||
* @var \Drupal\Core\Action\ActionInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* The action storage.
|
||||
*
|
||||
@@ -27,6 +20,13 @@ abstract class ActionFormBase extends EntityForm {
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* The action entity.
|
||||
*
|
||||
* @var \Drupal\system\ActionConfigEntityInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* Constructs a new action form.
|
||||
*
|
||||
@@ -46,14 +46,6 @@ abstract class ActionFormBase extends EntityForm {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$this->plugin = $this->entity->getPlugin();
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -85,8 +77,8 @@ abstract class ActionFormBase extends EntityForm {
|
||||
'#value' => $this->entity->getType(),
|
||||
];
|
||||
|
||||
if ($this->plugin instanceof PluginFormInterface) {
|
||||
$form += $this->plugin->buildConfigurationForm($form, $form_state);
|
||||
if ($plugin = $this->getPlugin()) {
|
||||
$form += $plugin->buildConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
return parent::form($form, $form_state);
|
||||
@@ -96,7 +88,7 @@ abstract class ActionFormBase extends EntityForm {
|
||||
* Determines if the action already exists.
|
||||
*
|
||||
* @param string $id
|
||||
* The action ID
|
||||
* The action ID.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the action exists, FALSE otherwise.
|
||||
@@ -120,9 +112,8 @@ abstract class ActionFormBase extends EntityForm {
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::validateForm($form, $form_state);
|
||||
|
||||
if ($this->plugin instanceof PluginFormInterface) {
|
||||
$this->plugin->validateConfigurationForm($form, $form_state);
|
||||
if ($plugin = $this->getPlugin()) {
|
||||
$plugin->validateConfigurationForm($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,9 +122,8 @@ abstract class ActionFormBase extends EntityForm {
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::submitForm($form, $form_state);
|
||||
|
||||
if ($this->plugin instanceof PluginFormInterface) {
|
||||
$this->plugin->submitConfigurationForm($form, $form_state);
|
||||
if ($plugin = $this->getPlugin()) {
|
||||
$plugin->submitConfigurationForm($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,4 +137,17 @@ abstract class ActionFormBase extends EntityForm {
|
||||
$form_state->setRedirect('entity.action.collection');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action plugin while ensuring it implements configuration form.
|
||||
*
|
||||
* @return \Drupal\Core\Action\ActionInterface|\Drupal\Core\Plugin\PluginFormInterface|null
|
||||
* The action plugin, or NULL if it does not implement configuration forms.
|
||||
*/
|
||||
protected function getPlugin() {
|
||||
if ($this->entity->getPlugin() instanceof PluginFormInterface) {
|
||||
return $this->entity->getPlugin();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,12 +108,12 @@ class ActionListBuilder extends ConfigEntityListBuilder {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render() {
|
||||
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
|
||||
$build['action_header']['#markup'] = '<h3>' . $this->t('Available actions:') . '</h3>';
|
||||
$build['action_table'] = parent::render();
|
||||
if (!$this->hasConfigurableActions) {
|
||||
unset($build['action_table']['table']['#header']['operations']);
|
||||
}
|
||||
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
|
||||
return $build;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
namespace Drupal\action\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Action\ActionManager;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a configuration form for configurable actions.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionAdminManageForm extends FormBase {
|
||||
|
||||
@@ -53,10 +54,10 @@ class ActionAdminManageForm extends FormBase {
|
||||
$actions = [];
|
||||
foreach ($this->manager->getDefinitions() as $id => $definition) {
|
||||
if (is_subclass_of($definition['class'], '\Drupal\Core\Plugin\PluginFormInterface')) {
|
||||
$key = Crypt::hashBase64($id);
|
||||
$actions[$key] = $definition['label'] . '...';
|
||||
$actions[$id] = $definition['label'];
|
||||
}
|
||||
}
|
||||
asort($actions);
|
||||
$form['parent'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Create an advanced action'),
|
||||
@@ -68,7 +69,7 @@ class ActionAdminManageForm extends FormBase {
|
||||
'#title' => $this->t('Action'),
|
||||
'#title_display' => 'invisible',
|
||||
'#options' => $actions,
|
||||
'#empty_option' => $this->t('Choose an advanced action'),
|
||||
'#empty_option' => $this->t('- Select -'),
|
||||
];
|
||||
$form['parent']['actions'] = [
|
||||
'#type' => 'actions'
|
||||
|
||||
@@ -7,6 +7,8 @@ use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Builds a form to delete an action.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionDeleteForm extends EntityDeleteForm {
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ dependencies:
|
||||
- views
|
||||
- node
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
name: action_form_ajax_test
|
||||
type: module
|
||||
description: 'module used for testing ajax in action config entity forms.'
|
||||
package: Core
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1520457826
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
action.configuration.action_form_ajax_test:
|
||||
type: action_configuration_default
|
||||
label: 'action_form_ajax_test action'
|
||||
mapping:
|
||||
party_time:
|
||||
type: string
|
||||
label: 'The time of the party.'
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\action_form_ajax_test\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Action\ConfigurableActionBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Plugin used for testing AJAX in action config entity forms.
|
||||
*
|
||||
* @Action(
|
||||
* id = "action_form_ajax_test",
|
||||
* label = @Translation("action_form_ajax_test"),
|
||||
* type = "system"
|
||||
* )
|
||||
*/
|
||||
class ActionAjaxTest extends ConfigurableActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'party_time' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
$result = AccessResult::allowed();
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute() {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$having_a_party = $form_state->getValue('having_a_party', !empty($this->configuration['party_time']));
|
||||
$form['having_a_party'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Are we having a party?'),
|
||||
'#ajax' => [
|
||||
'wrapper' => 'party-container',
|
||||
'callback' => [$this, 'partyCallback'],
|
||||
],
|
||||
'#default_value' => $having_a_party,
|
||||
];
|
||||
$form['container'] = [
|
||||
'#type' => 'container',
|
||||
'#prefix' => '<div id="party-container">',
|
||||
'#suffix' => '</div>',
|
||||
];
|
||||
|
||||
if ($having_a_party) {
|
||||
$form['container']['party_time'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Party time'),
|
||||
'#default_value' => $this->configuration['party_time'],
|
||||
];
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for party checkbox.
|
||||
*/
|
||||
public function partyCallback(array $form, FormStateInterface $form_state) {
|
||||
return $form['container'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->configuration['party_time'] = $form_state->getValue('party_time');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\action\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\system\Entity\Action;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
@@ -31,7 +30,7 @@ class ConfigurationTest extends BrowserTestBase {
|
||||
|
||||
// Make a POST request to admin/config/system/actions.
|
||||
$edit = [];
|
||||
$edit['action'] = Crypt::hashBase64('action_goto_action');
|
||||
$edit['action'] = 'action_goto_action';
|
||||
$this->drupalPostForm('admin/config/system/actions', $edit, t('Create'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
@@ -41,17 +40,18 @@ class ConfigurationTest extends BrowserTestBase {
|
||||
$edit['label'] = $action_label;
|
||||
$edit['id'] = strtolower($action_label);
|
||||
$edit['url'] = 'admin';
|
||||
$this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('action_goto_action'), $edit, t('Save'));
|
||||
$this->drupalPostForm('admin/config/system/actions/add/action_goto_action', $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
$action_id = $edit['id'];
|
||||
|
||||
// Make sure that the new complex action was saved properly.
|
||||
$this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully saved the complex action.");
|
||||
$this->assertText($action_label, "Make sure the action label appears on the configuration page after we've saved the complex action.");
|
||||
|
||||
// Make another POST request to the action edit page.
|
||||
$this->clickLink(t('Configure'));
|
||||
preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
|
||||
$aid = $matches[1];
|
||||
|
||||
$edit = [];
|
||||
$new_action_label = $this->randomMachineName();
|
||||
$edit['label'] = $new_action_label;
|
||||
@@ -73,7 +73,7 @@ class ConfigurationTest extends BrowserTestBase {
|
||||
$this->clickLink(t('Delete'));
|
||||
$this->assertResponse(200);
|
||||
$edit = [];
|
||||
$this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Delete'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make sure that the action was actually deleted.
|
||||
@@ -82,7 +82,7 @@ class ConfigurationTest extends BrowserTestBase {
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoText($new_action_label, "Make sure the action label does not appear on the overview page after we've deleted the action.");
|
||||
|
||||
$action = Action::load($aid);
|
||||
$action = Action::load($action_id);
|
||||
$this->assertFalse($action, 'Make sure the action is gone after being deleted.');
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\action\FunctionalJavascript;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
|
||||
use Drupal\system\Entity\Action;
|
||||
|
||||
/**
|
||||
* Tests action plugins using Javascript.
|
||||
*
|
||||
* @group action
|
||||
*/
|
||||
class ActionFormAjaxTest extends JavascriptTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['action', 'action_form_ajax_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$user = $this->drupalCreateUser(['administer actions']);
|
||||
$this->drupalLogin($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests action plugins with AJAX save their configuration.
|
||||
*/
|
||||
public function testActionConfigurationWithAjax() {
|
||||
$url = Url::fromRoute('action.admin_add', ['action_id' => 'action_form_ajax_test']);
|
||||
$this->drupalGet($url);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$id = 'test_plugin';
|
||||
$page->find('css', '[name="id"]')
|
||||
->setValue($id);
|
||||
|
||||
$page->find('css', '[name="having_a_party"]')
|
||||
->check();
|
||||
$this->assertSession()->waitForElement('css', '[name="party_time"]');
|
||||
|
||||
$party_time = 'Evening';
|
||||
$page->find('css', '[name="party_time"]')
|
||||
->setValue($party_time);
|
||||
|
||||
$page->find('css', '[value="Save"]')
|
||||
->click();
|
||||
|
||||
$url = Url::fromRoute('entity.action.collection');
|
||||
$this->assertSession()->pageTextContains('The action has been successfully saved.');
|
||||
$this->assertSession()->addressEquals($url);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
|
||||
// Check storage.
|
||||
$instance = Action::load($id);
|
||||
$configuration = $instance->getPlugin()->getConfiguration();
|
||||
$this->assertEquals(['party_time' => $party_time], $configuration);
|
||||
|
||||
// Configuration should be shown in edit form.
|
||||
$this->drupalGet($instance->toUrl('edit-form'));
|
||||
$this->assertSession()->checkboxChecked('having_a_party');
|
||||
$this->assertSession()->fieldValueEquals('party_time', $party_time);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ class ActionTest extends MigrateSqlSourceTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['action', 'migrate_drupal'];
|
||||
public static $modules = ['action', 'migrate_drupal', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -9,8 +9,8 @@ dependencies:
|
||||
- file
|
||||
- options
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
id: d6_aggregator_feed
|
||||
label: Aggregator feeds
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_feed
|
||||
process:
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
id: d6_aggregator_item
|
||||
label: Aggregator items
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_item
|
||||
process:
|
||||
+1
@@ -2,6 +2,7 @@ id: d6_aggregator_settings
|
||||
label: Aggregator configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
id: d7_aggregator_feed
|
||||
label: Aggregator feeds
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_feed
|
||||
process:
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
id: d7_aggregator_item
|
||||
label: Aggregator items
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_item
|
||||
process:
|
||||
+1
@@ -2,6 +2,7 @@ id: d7_aggregator_settings
|
||||
label: Aggregator configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
@@ -93,7 +93,7 @@ class AggregatorController extends ControllerBase {
|
||||
$message = $aggregator_feed->refreshItems()
|
||||
? $this->t('There is new syndicated content from %site.', ['%site' => $aggregator_feed->label()])
|
||||
: $this->t('There is no new syndicated content from %site.', ['%site' => $aggregator_feed->label()]);
|
||||
drupal_set_message($message);
|
||||
$this->messenger()->addStatus($message);
|
||||
return $this->redirect('aggregator.admin_overview');
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Form handler for the aggregator feed edit forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FeedForm extends ContentEntityForm {
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Provides a form for deleting a feed.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FeedDeleteForm extends ContentEntityDeleteForm {
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Provides a deletion confirmation form for items that belong to a feed.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FeedItemsDeleteForm extends ContentEntityConfirmFormBase {
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ use GuzzleHttp\ClientInterface;
|
||||
|
||||
/**
|
||||
* Imports feeds from OPML.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class OpmlFeedAdd extends FormBase {
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Configures aggregator settings for this site.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class SettingsForm extends ConfigFormBase {
|
||||
|
||||
|
||||
@@ -167,8 +167,10 @@ class AggregatorFeedBlock extends BlockBase implements ContainerFactoryPluginInt
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
$cache_tags = parent::getCacheTags();
|
||||
$feed = $this->feedStorage->load($this->configuration['feed']);
|
||||
return Cache::mergeTags($cache_tags, $feed->getCacheTags());
|
||||
if ($feed = $this->feedStorage->load($this->configuration['feed'])) {
|
||||
$cache_tags = Cache::mergeTags($cache_tags, $feed->getCacheTags());
|
||||
}
|
||||
return $cache_tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@ dependencies:
|
||||
- aggregator
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\Tests\aggregator\Kernel\Migrate;
|
||||
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
|
||||
use Drupal\migrate_drupal\Tests\StubTestTrait;
|
||||
|
||||
@@ -40,18 +39,6 @@ class MigrateAggregatorStubTest extends MigrateDrupalTestBase {
|
||||
* Tests creation of aggregator feed items.
|
||||
*/
|
||||
public function testItemStub() {
|
||||
try {
|
||||
// We expect an exception, because there's no feed to reference.
|
||||
$this->performStubTest('aggregator_item');
|
||||
$this->fail('Expected exception has not been thrown.');
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
$this->assertIdentical($e->getMessage(),
|
||||
'Stubbing failed, unable to generate value for field fid');
|
||||
}
|
||||
|
||||
// The stub should pass when there's a feed to point to.
|
||||
$this->createStub('aggregator_feed');
|
||||
$this->performStubTest('aggregator_item');
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ package: Core
|
||||
# core: 8.x
|
||||
configure: system.cron_settings
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -6,8 +6,8 @@ package: Core
|
||||
# core: 8.x
|
||||
configure: ban.admin_page
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
+1
@@ -2,6 +2,7 @@ id: d7_blocked_ips
|
||||
label: Blocked IPs
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: d7_blocked_ips
|
||||
process:
|
||||
@@ -10,6 +10,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Displays banned IP addresses.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BanAdmin extends FormBase {
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Provides a form to unban IP addresses.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BanDelete extends ConfirmFormBase {
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ package: Web services
|
||||
dependencies:
|
||||
- user
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -5,12 +5,13 @@ namespace Drupal\basic_auth\Authentication\Provider;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Authentication\AuthenticationProviderInterface;
|
||||
use Drupal\Core\Authentication\AuthenticationProviderChallengeInterface;
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Flood\FloodInterface;
|
||||
use Drupal\Core\Http\Exception\CacheableUnauthorizedHttpException;
|
||||
use Drupal\user\UserAuthInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
|
||||
|
||||
/**
|
||||
* HTTP Basic authentication provider.
|
||||
@@ -126,11 +127,35 @@ class BasicAuth implements AuthenticationProviderInterface, AuthenticationProvid
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function challengeException(Request $request, \Exception $previous) {
|
||||
$site_name = $this->configFactory->get('system.site')->get('name');
|
||||
$site_config = $this->configFactory->get('system.site');
|
||||
$site_name = $site_config->get('name');
|
||||
$challenge = SafeMarkup::format('Basic realm="@realm"', [
|
||||
'@realm' => !empty($site_name) ? $site_name : 'Access restricted',
|
||||
]);
|
||||
return new UnauthorizedHttpException((string) $challenge, 'No authentication credentials provided.', $previous);
|
||||
|
||||
// A 403 is converted to a 401 here, but it doesn't matter what the
|
||||
// cacheability was of the 403 exception: what matters here is that
|
||||
// authentication credentials are missing, i.e. that this request was made
|
||||
// as the anonymous user.
|
||||
// Therefore, all we must do, is make this response:
|
||||
// 1. vary by whether the current user has the 'anonymous' role or not. This
|
||||
// works fine because:
|
||||
// - Thanks to \Drupal\basic_auth\PageCache\DisallowBasicAuthRequests,
|
||||
// Page Cache never caches a response whose request has Basic Auth
|
||||
// credentials.
|
||||
// - Dynamic Page Cache will cache a different result for when the
|
||||
// request is unauthenticated (this 401) versus authenticated (some
|
||||
// other response)
|
||||
// 2. have the 'config:user.role.anonymous' cache tag, because the only
|
||||
// reason this 401 would no longer be a 401 is if permissions for the
|
||||
// 'anonymous' role change, causing that cache tag to be invalidated.
|
||||
// @see \Drupal\Core\EventSubscriber\AuthenticationSubscriber::onExceptionSendChallenge()
|
||||
// @see \Drupal\Core\EventSubscriber\ClientErrorResponseSubscriber()
|
||||
// @see \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onAllResponds()
|
||||
$cacheability = CacheableMetadata::createFromObject($site_config)
|
||||
->addCacheTags(['config:user.role.anonymous'])
|
||||
->addCacheContexts(['user.roles:anonymous']);
|
||||
return new CacheableUnauthorizedHttpException($cacheability, (string) $challenge, 'No authentication credentials provided.', $previous);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\basic_auth\Tests;
|
||||
|
||||
@trigger_error(__FILE__ . ' is deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait instead. See https://www.drupal.org/node/2862800.', E_USER_DEPRECATED);
|
||||
@trigger_error(__NAMESPACE__ . '\BasicAuthTestTrait is deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait instead. See https://www.drupal.org/node/2862800.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Provides common functionality for Basic Authentication test classes.
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -7,6 +7,7 @@ use Drupal\Core\Url;
|
||||
use Drupal\Tests\basic_auth\Traits\BasicAuthTestTrait;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
|
||||
/**
|
||||
* Tests for BasicAuth authentication provider.
|
||||
@@ -180,6 +181,47 @@ class BasicAuthTest extends BrowserTestBase {
|
||||
$this->assertText('Access denied', "A user friendly access denied message is displayed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the cacheability of Basic Auth's 401 response.
|
||||
*
|
||||
* @see \Drupal\basic_auth\Authentication\Provider\BasicAuth::challengeException()
|
||||
*/
|
||||
public function testCacheabilityOf401Response() {
|
||||
$session = $this->getSession();
|
||||
$url = Url::fromRoute('router_test.11');
|
||||
|
||||
$assert_response_cacheability = function ($expected_page_cache_header_value, $expected_dynamic_page_cache_header_value) use ($session, $url) {
|
||||
$this->drupalGet($url);
|
||||
$this->assertSession()->statusCodeEquals(401);
|
||||
$this->assertSame($expected_page_cache_header_value, $session->getResponseHeader('X-Drupal-Cache'));
|
||||
$this->assertSame($expected_dynamic_page_cache_header_value, $session->getResponseHeader('X-Drupal-Dynamic-Cache'));
|
||||
};
|
||||
|
||||
// 1. First request: cold caches, both Page Cache and Dynamic Page Cache are
|
||||
// now primed.
|
||||
$assert_response_cacheability('MISS', 'MISS');
|
||||
// 2. Second request: Page Cache HIT, we don't even hit Dynamic Page Cache.
|
||||
// This is going to keep happening.
|
||||
$assert_response_cacheability('HIT', 'MISS');
|
||||
// 3. Third request: after clearing Page Cache, we now see that Dynamic Page
|
||||
// Cache is a HIT too.
|
||||
$this->container->get('cache.page')->deleteAll();
|
||||
$assert_response_cacheability('MISS', 'HIT');
|
||||
// 4. Fourth request: warm caches.
|
||||
$assert_response_cacheability('HIT', 'HIT');
|
||||
|
||||
// If the permissions of the 'anonymous' role change, it may no longer be
|
||||
// necessary to be authenticated to access this route. Therefore the cached
|
||||
// 401 responses should be invalidated.
|
||||
$this->grantPermissions(Role::load(Role::ANONYMOUS_ID), [$this->randomMachineName()]);
|
||||
$assert_response_cacheability('MISS', 'MISS');
|
||||
$assert_response_cacheability('HIT', 'MISS');
|
||||
// Idem for when the 'system.site' config changes.
|
||||
$this->config('system.site')->save();
|
||||
$assert_response_cacheability('MISS', 'MISS');
|
||||
$assert_response_cacheability('HIT', 'MISS');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the controller is called before authentication.
|
||||
*
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Core
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -20,16 +20,17 @@
|
||||
// Ignore any placeholders that are not in the known placeholder list. Used
|
||||
// to avoid someone trying to XSS the site via the placeholdering mechanism.
|
||||
if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') {
|
||||
const response = mapTextContentToAjaxResponse(content);
|
||||
// If we try to parse the content too early (when the JSON containing Ajax
|
||||
// commands is still arriving), textContent will be empty which will cause
|
||||
// JSON.parse() to fail. Remove once so that it can be processed again
|
||||
// later.
|
||||
// @see bigPipeProcessDocument()
|
||||
if (content === '') {
|
||||
// commands is still arriving), textContent will be empty or incomplete.
|
||||
if (response === false) {
|
||||
/**
|
||||
* Mark as unprocessed so this will be retried later.
|
||||
* @see bigPipeProcessDocument()
|
||||
*/
|
||||
$(this).removeOnce('big-pipe');
|
||||
}
|
||||
else {
|
||||
const response = JSON.parse(content);
|
||||
// Create a Drupal.Ajax object without associating an element, a
|
||||
// progress indicator or a URL.
|
||||
const ajaxObject = Drupal.ajax({
|
||||
@@ -45,6 +46,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps textContent of <script type="application/vnd.drupal-ajax"> to an AJAX response.
|
||||
*
|
||||
* @param {string} content
|
||||
* The text content of a <script type="application/vnd.drupal-ajax"> DOM node.
|
||||
* @return {Array|boolean}
|
||||
* The parsed Ajax response containing an array of Ajax commands, or false in
|
||||
* case the DOM node hasn't fully arrived yet.
|
||||
*/
|
||||
function mapTextContentToAjaxResponse(content) {
|
||||
if (content === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a streamed HTML document receiving placeholder replacements.
|
||||
*
|
||||
@@ -89,7 +112,7 @@
|
||||
// The frequency with which to check for newly arrived BigPipe placeholders.
|
||||
// Hence 50 ms means we check 20 times per second. Setting this to 100 ms or
|
||||
// more would cause the user to see content appear noticeably slower.
|
||||
var interval = drupalSettings.bigPipeInterval || 50;
|
||||
const interval = drupalSettings.bigPipeInterval || 50;
|
||||
// The internal ID to contain the watcher service.
|
||||
let timeoutID;
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
var content = this.textContent.trim();
|
||||
|
||||
if (typeof drupalSettings.bigPipePlaceholderIds[placeholderId] !== 'undefined') {
|
||||
if (content === '') {
|
||||
var response = mapTextContentToAjaxResponse(content);
|
||||
|
||||
if (response === false) {
|
||||
$(this).removeOnce('big-pipe');
|
||||
} else {
|
||||
var response = JSON.parse(content);
|
||||
|
||||
var ajaxObject = Drupal.ajax({
|
||||
url: '',
|
||||
base: false,
|
||||
@@ -28,6 +28,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
function mapTextContentToAjaxResponse(content) {
|
||||
if (content === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function bigPipeProcessDocument(context) {
|
||||
if (!context.querySelector('script[data-big-pipe-event="start"]')) {
|
||||
return false;
|
||||
|
||||
@@ -420,7 +420,7 @@ class BigPipe {
|
||||
}
|
||||
|
||||
$placeholder = $fragment;
|
||||
assert('isset($no_js_placeholders[$placeholder])');
|
||||
assert(isset($no_js_placeholders[$placeholder]));
|
||||
$token = Crypt::randomBytesBase64(55);
|
||||
|
||||
// Render the placeholder, but include the cumulative settings assets, so
|
||||
@@ -629,7 +629,7 @@ EOF;
|
||||
* AJAX page state.
|
||||
*/
|
||||
protected function filterEmbeddedResponse(Request $fake_request, Response $embedded_response) {
|
||||
assert('$embedded_response instanceof \Drupal\Core\Render\HtmlResponse || $embedded_response instanceof \Drupal\Core\Ajax\AjaxResponse');
|
||||
assert($embedded_response instanceof HtmlResponse || $embedded_response instanceof AjaxResponse);
|
||||
return $this->filterResponse($fake_request, HttpKernelInterface::SUB_REQUEST, $embedded_response);
|
||||
}
|
||||
|
||||
@@ -649,7 +649,7 @@ EOF;
|
||||
* The filtered response.
|
||||
*/
|
||||
protected function filterResponse(Request $request, $request_type, Response $response) {
|
||||
assert('$request_type === \Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST || $request_type === \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST');
|
||||
assert($request_type === HttpKernelInterface::MASTER_REQUEST || $request_type === HttpKernelInterface::SUB_REQUEST);
|
||||
$this->requestStack->push($request);
|
||||
$event = new FilterResponseEvent($this->httpKernel, $request, $request_type, $response);
|
||||
$this->eventDispatcher->dispatch(KernelEvents::RESPONSE, $event);
|
||||
|
||||
@@ -9,6 +9,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\EnforcedResponseException;
|
||||
use Drupal\Core\Render\AttachmentsInterface;
|
||||
use Drupal\Core\Render\AttachmentsResponseProcessorInterface;
|
||||
use Drupal\Core\Render\HtmlResponse;
|
||||
use Drupal\Core\Render\HtmlResponseAttachmentsProcessor;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
@@ -57,7 +58,7 @@ class BigPipeResponseAttachmentsProcessor extends HtmlResponseAttachmentsProcess
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processAttachments(AttachmentsInterface $response) {
|
||||
assert('$response instanceof \Drupal\Core\Render\HtmlResponse');
|
||||
assert($response instanceof HtmlResponse);
|
||||
|
||||
// First, render the actual placeholders; this will cause the BigPipe
|
||||
// placeholder strategy to generate BigPipe placeholders. We need those to
|
||||
|
||||
@@ -180,7 +180,7 @@ class BigPipeStrategy implements PlaceholderStrategyInterface {
|
||||
* a placeholder for a HTML attribute value or a subset of it).
|
||||
*/
|
||||
protected static function placeholderIsAttributeSafe($placeholder) {
|
||||
assert('is_string($placeholder)');
|
||||
assert(is_string($placeholder));
|
||||
return $placeholder[0] !== '<' || $placeholder !== Html::normalize($placeholder);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -5,6 +5,11 @@ namespace Drupal\big_pipe_test\Form;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form to test BigPipe.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BigPipeTestForm extends FormBase {
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,8 +4,8 @@ description: 'Theme for testing BigPipe edge cases.'
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -6,8 +6,8 @@ package: Core
|
||||
# core: 8.x
|
||||
configure: block.admin_display
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -30,6 +30,3 @@ block.block.*:
|
||||
sequence:
|
||||
type: condition.plugin.[id]
|
||||
label: 'Visibility Condition'
|
||||
|
||||
block.settings.*:
|
||||
type: block_settings
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
attach(context, settings) {
|
||||
const $input = $('input.block-filter-text').once('block-filter-text');
|
||||
const $table = $($input.attr('data-element'));
|
||||
let $filter_rows;
|
||||
let $filterRows;
|
||||
|
||||
/**
|
||||
* Filters the block list.
|
||||
@@ -52,24 +52,24 @@
|
||||
|
||||
// Filter if the length of the query is at least 2 characters.
|
||||
if (query.length >= 2) {
|
||||
$filter_rows.each(toggleBlockEntry);
|
||||
$filterRows.each(toggleBlockEntry);
|
||||
Drupal.announce(
|
||||
Drupal.formatPlural(
|
||||
$table.find('tr:visible').length - 1,
|
||||
'1 block is available in the modified list.',
|
||||
'@count blocks are available in the modified list.'
|
||||
)
|
||||
'@count blocks are available in the modified list.',
|
||||
),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$filter_rows.each(function (index) {
|
||||
$filterRows.each(function (index) {
|
||||
$(this).parent().parent().show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($table.length) {
|
||||
$filter_rows = $table.find('div.block-filter-text-source');
|
||||
$filterRows = $table.find('div.block-filter-text-source');
|
||||
$input.on('keyup', debounce(filterBlockList, 200));
|
||||
}
|
||||
},
|
||||
@@ -91,7 +91,7 @@
|
||||
// Just scrolling the document.body will not work in Firefox. The html
|
||||
// element is needed as well.
|
||||
$('html, body').animate({
|
||||
scrollTop: $('.js-block-placed').offset().top - $container.offset().top + $container.scrollTop(),
|
||||
scrollTop: ($('.js-block-placed').offset().top - $container.offset().top) + $container.scrollTop(),
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
attach: function attach(context, settings) {
|
||||
var $input = $('input.block-filter-text').once('block-filter-text');
|
||||
var $table = $($input.attr('data-element'));
|
||||
var $filter_rows = void 0;
|
||||
var $filterRows = void 0;
|
||||
|
||||
function filterBlockList(e) {
|
||||
var query = $(e.target).val().toLowerCase();
|
||||
@@ -23,17 +23,17 @@
|
||||
}
|
||||
|
||||
if (query.length >= 2) {
|
||||
$filter_rows.each(toggleBlockEntry);
|
||||
$filterRows.each(toggleBlockEntry);
|
||||
Drupal.announce(Drupal.formatPlural($table.find('tr:visible').length - 1, '1 block is available in the modified list.', '@count blocks are available in the modified list.'));
|
||||
} else {
|
||||
$filter_rows.each(function (index) {
|
||||
$filterRows.each(function (index) {
|
||||
$(this).parent().parent().show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($table.length) {
|
||||
$filter_rows = $table.find('div.block-filter-text-source');
|
||||
$filterRows = $table.find('div.block-filter-text-source');
|
||||
$input.on('keyup', debounce(filterBlockList, 200));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,14 +195,14 @@
|
||||
// Find the correct region and insert the row as the last in the
|
||||
// region.
|
||||
tableDrag.rowObject = new tableDrag.row(row[0]);
|
||||
const region_message = table.find(`.region-${select[0].value}-message`);
|
||||
const region_items = region_message.nextUntil('.region-message, .region-title');
|
||||
if (region_items.length) {
|
||||
region_items.last().after(row);
|
||||
const regionMessage = table.find(`.region-${select[0].value}-message`);
|
||||
const regionItems = regionMessage.nextUntil('.region-message, .region-title');
|
||||
if (regionItems.length) {
|
||||
regionItems.last().after(row);
|
||||
}
|
||||
// We found that region_message is the last row.
|
||||
// We found that regionMessage is the last row.
|
||||
else {
|
||||
region_message.after(row);
|
||||
regionMessage.after(row);
|
||||
}
|
||||
updateBlockWeights(table, select[0].value);
|
||||
// Modify empty regions with added or removed fields.
|
||||
|
||||
@@ -119,12 +119,12 @@
|
||||
var select = $(this);
|
||||
|
||||
tableDrag.rowObject = new tableDrag.row(row[0]);
|
||||
var region_message = table.find('.region-' + select[0].value + '-message');
|
||||
var region_items = region_message.nextUntil('.region-message, .region-title');
|
||||
if (region_items.length) {
|
||||
region_items.last().after(row);
|
||||
var regionMessage = table.find('.region-' + select[0].value + '-message');
|
||||
var regionItems = regionMessage.nextUntil('.region-message, .region-title');
|
||||
if (regionItems.length) {
|
||||
regionItems.last().after(row);
|
||||
} else {
|
||||
region_message.after(row);
|
||||
regionMessage.after(row);
|
||||
}
|
||||
updateBlockWeights(table, select[0].value);
|
||||
|
||||
|
||||
+1
@@ -2,6 +2,7 @@ id: d6_block
|
||||
label: Blocks
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
source:
|
||||
plugin: block
|
||||
process:
|
||||
+1
@@ -2,6 +2,7 @@ id: d7_block
|
||||
label: Blocks
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: block
|
||||
process:
|
||||
@@ -19,6 +19,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides form for block instance forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BlockForm extends EntityForm {
|
||||
|
||||
|
||||
@@ -105,6 +105,10 @@ class BlockLibraryController extends ControllerBase {
|
||||
$definitions = $this->blockManager->getDefinitionsForContexts($this->contextRepository->getAvailableContexts());
|
||||
// Order by category, and then by admin label.
|
||||
$definitions = $this->blockManager->getSortedDefinitions($definitions);
|
||||
// Filter out definitions that are not intended to be placed by the UI.
|
||||
$definitions = array_filter($definitions, function (array $definition) {
|
||||
return empty($definition['_block_ui_hidden']);
|
||||
});
|
||||
|
||||
$region = $request->query->get('region');
|
||||
$weight = $request->query->get('weight');
|
||||
|
||||
@@ -7,6 +7,8 @@ use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Provides a deletion confirmation form for the block instance deletion form.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BlockDeleteForm extends EntityDeleteForm {
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ package: Testing
|
||||
dependencies:
|
||||
- block
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -5,6 +5,11 @@ namespace Drupal\block_test\Form;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form that performs favorite animal test.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FavoriteAnimalTestForm extends FormBase {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,11 @@ namespace Drupal\block_test\Form;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form that performs base block form test.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TestForm extends FormBase {
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ regions:
|
||||
content: Content
|
||||
help: Help
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
+3
-3
@@ -15,8 +15,8 @@ regions_hidden:
|
||||
- sidebar_first
|
||||
- sidebar_second
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -8,8 +8,8 @@ dependencies:
|
||||
- block
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Drupal\Tests\block\Unit;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Tests\Core\Plugin\Fixtures\TestConfigurablePlugin;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
@@ -20,11 +21,11 @@ class BlockConfigEntityUnitTest extends UnitTestCase {
|
||||
protected $entityType;
|
||||
|
||||
/**
|
||||
* The entity manager used for testing.
|
||||
* The entity type manager used for testing.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $entityManager;
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* The ID of the type of the entity under test.
|
||||
@@ -51,8 +52,8 @@ class BlockConfigEntityUnitTest extends UnitTestCase {
|
||||
->method('getProvider')
|
||||
->will($this->returnValue('block'));
|
||||
|
||||
$this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
|
||||
$this->entityManager->expects($this->any())
|
||||
$this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
|
||||
$this->entityTypeManager->expects($this->any())
|
||||
->method('getDefinition')
|
||||
->with($this->entityTypeId)
|
||||
->will($this->returnValue($this->entityType));
|
||||
@@ -60,7 +61,7 @@ class BlockConfigEntityUnitTest extends UnitTestCase {
|
||||
$this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
$container->set('entity.manager', $this->entityManager);
|
||||
$container->set('entity_type.manager', $this->entityTypeManager);
|
||||
$container->set('uuid', $this->uuid);
|
||||
\Drupal::setContainer($container);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace Drupal\Tests\block\Unit;
|
||||
|
||||
use Drupal\block\BlockForm;
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
use Drupal\Core\Plugin\PluginFormFactoryInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
@@ -82,6 +84,32 @@ class BlockFormTest extends UnitTestCase {
|
||||
$this->pluginFormFactory = $this->prophesize(PluginFormFactoryInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks a block with a block plugin.
|
||||
*
|
||||
* @param string $machine_name
|
||||
* The machine name of the block plugin.
|
||||
*
|
||||
* @return \Drupal\block\BlockInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
* The mocked block.
|
||||
*/
|
||||
protected function getBlockMockWithMachineName($machine_name) {
|
||||
$plugin = $this->getMockBuilder(BlockBase::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$plugin->expects($this->any())
|
||||
->method('getMachineNameSuggestion')
|
||||
->will($this->returnValue($machine_name));
|
||||
|
||||
$block = $this->getMockBuilder(Block::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$block->expects($this->any())
|
||||
->method('getPlugin')
|
||||
->will($this->returnValue($plugin));
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the unique machine name generator.
|
||||
*
|
||||
|
||||
@@ -49,6 +49,7 @@ class BlockPageVariantTest extends UnitTestCase {
|
||||
$container = new Container();
|
||||
$cache_context_manager = $this->getMockBuilder('Drupal\Core\Cache\CacheContextsManager')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['assertValidTokens'])
|
||||
->getMock();
|
||||
$container->set('cache_contexts_manager', $cache_context_manager);
|
||||
$cache_context_manager->expects($this->any())
|
||||
@@ -209,9 +210,6 @@ class BlockPageVariantTest extends UnitTestCase {
|
||||
$title_block_plugin = $this->getMock('Drupal\Core\Block\TitleBlockPluginInterface');
|
||||
foreach ($blocks_config as $block_id => $block_config) {
|
||||
$block = $this->getMock('Drupal\block\BlockInterface');
|
||||
$block->expects($this->any())
|
||||
->method('getContexts')
|
||||
->willReturn([]);
|
||||
$block->expects($this->atLeastOnce())
|
||||
->method('getPlugin')
|
||||
->willReturn($block_config[1] ? $main_content_block_plugin : ($block_config[2] ? $messages_block_plugin : ($block_config[3] ? $title_block_plugin : $block_plugin)));
|
||||
|
||||
@@ -10,8 +10,8 @@ dependencies:
|
||||
- user
|
||||
configure: entity.block_content.collection
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -6,6 +6,23 @@
|
||||
*/
|
||||
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* Implements hook_update_dependencies().
|
||||
*/
|
||||
function block_content_update_dependencies() {
|
||||
// The update function that adds the status field must run after
|
||||
// content_translation_update_8400() which fixes NULL values for the
|
||||
// 'content_translation_status' field.
|
||||
if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
|
||||
$dependencies['block_content'][8400] = [
|
||||
'content_translation' => 8400,
|
||||
];
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'revision_translation_affected' field to 'block_content' entities.
|
||||
@@ -70,5 +87,54 @@ function block_content_update_8300() {
|
||||
$entity_type = $definition_update_manager->getEntityType('block_content');
|
||||
$entity_type->set('revision_data_table', 'block_content_field_revision');
|
||||
$definition_update_manager->updateEntityType($entity_type);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a publishing status field for block_content entities.
|
||||
*/
|
||||
function block_content_update_8400() {
|
||||
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
|
||||
|
||||
// Add the published entity key to the block_content entity type.
|
||||
$entity_type = $definition_update_manager->getEntityType('block_content');
|
||||
$entity_keys = $entity_type->getKeys();
|
||||
$entity_keys['published'] = 'status';
|
||||
$entity_type->set('entity_keys', $entity_keys);
|
||||
$definition_update_manager->updateEntityType($entity_type);
|
||||
|
||||
// Add the publishing status field to the block_content entity type.
|
||||
$status = BaseFieldDefinition::create('boolean')
|
||||
->setLabel(new TranslatableMarkup('Publishing status'))
|
||||
->setDescription(new TranslatableMarkup('A boolean indicating the published state.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setTranslatable(TRUE)
|
||||
->setDefaultValue(TRUE);
|
||||
|
||||
$has_content_translation_status_field = \Drupal::moduleHandler()->moduleExists('content_translation') && $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'block_content');
|
||||
if ($has_content_translation_status_field) {
|
||||
$status->setInitialValueFromField('content_translation_status');
|
||||
}
|
||||
else {
|
||||
$status->setInitialValue(TRUE);
|
||||
}
|
||||
$definition_update_manager->installFieldStorageDefinition('status', 'block_content', 'block_content', $status);
|
||||
|
||||
// Uninstall the 'content_translation_status' field if needed.
|
||||
$database = \Drupal::database();
|
||||
if ($has_content_translation_status_field) {
|
||||
// First we have to remove the field data.
|
||||
$database->update($entity_type->getDataTable())
|
||||
->fields(['content_translation_status' => NULL])
|
||||
->execute();
|
||||
|
||||
// A site may have disabled revisionability for this entity type.
|
||||
if ($entity_type->isRevisionable()) {
|
||||
$database->update($entity_type->getRevisionDataTable())
|
||||
->fields(['content_translation_status' => NULL])
|
||||
->execute();
|
||||
}
|
||||
|
||||
$content_translation_status = $definition_update_manager->getFieldStorageDefinition('content_translation_status', 'block_content');
|
||||
$definition_update_manager->uninstallFieldStorageDefinition($content_translation_status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ display:
|
||||
admin_label: ''
|
||||
empty: true
|
||||
tokenize: false
|
||||
content: 'There are no custom blocks available. '
|
||||
content: 'There are no custom blocks available.'
|
||||
plugin_id: text_custom
|
||||
block_content_listing_empty:
|
||||
admin_label: ''
|
||||
|
||||
+1
@@ -3,6 +3,7 @@ label: Block content body field configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: embedded_data
|
||||
data_rows:
|
||||
+1
@@ -3,6 +3,7 @@ label: Body field display configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: embedded_data
|
||||
data_rows:
|
||||
+1
@@ -3,6 +3,7 @@ label: Body field form display configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: embedded_data
|
||||
data_rows:
|
||||
+1
@@ -3,6 +3,7 @@ label: Block content type
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: embedded_data
|
||||
data_rows:
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
id: d6_custom_block
|
||||
label: Custom blocks
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Content
|
||||
source:
|
||||
plugin: d6_box
|
||||
process:
|
||||
+2
@@ -1,7 +1,9 @@
|
||||
id: d7_custom_block
|
||||
label: Custom blocks
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: d7_block_custom
|
||||
process:
|
||||
@@ -19,7 +19,8 @@ class BlockContentAccessControlHandler extends EntityAccessControlHandler {
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
if ($operation === 'view') {
|
||||
return AccessResult::allowed();
|
||||
return AccessResult::allowedIf($entity->isPublished())->addCacheableDependency($entity)
|
||||
->orIf(AccessResult::allowedIfHasPermission($account, 'administer blocks'));
|
||||
}
|
||||
return parent::checkAccess($entity, $operation, $account);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form handler for the custom block edit forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BlockContentForm extends ContentEntityForm {
|
||||
|
||||
|
||||
@@ -4,12 +4,13 @@ namespace Drupal\block_content;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityChangedInterface;
|
||||
use Drupal\Core\Entity\EntityPublishedInterface;
|
||||
use Drupal\Core\Entity\RevisionLogInterface;
|
||||
|
||||
/**
|
||||
* Provides an interface defining a custom block entity.
|
||||
*/
|
||||
interface BlockContentInterface extends ContentEntityInterface, EntityChangedInterface, RevisionLogInterface {
|
||||
interface BlockContentInterface extends ContentEntityInterface, EntityChangedInterface, RevisionLogInterface, EntityPublishedInterface {
|
||||
|
||||
/**
|
||||
* Returns the block revision log message.
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Drupal\block_content;
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityListBuilder;
|
||||
use Drupal\Core\Routing\RedirectDestinationTrait;
|
||||
|
||||
/**
|
||||
* Defines a class to build a listing of custom block entities.
|
||||
@@ -13,8 +12,6 @@ use Drupal\Core\Routing\RedirectDestinationTrait;
|
||||
*/
|
||||
class BlockContentListBuilder extends EntityListBuilder {
|
||||
|
||||
use RedirectDestinationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -31,15 +28,4 @@ class BlockContentListBuilder extends EntityListBuilder {
|
||||
return $row + parent::buildRow($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultOperations(EntityInterface $entity) {
|
||||
$operations = parent::getDefaultOperations($entity);
|
||||
if (isset($operations['edit'])) {
|
||||
$operations['edit']['query']['destination'] = $this->getRedirectDestination()->get();
|
||||
}
|
||||
return $operations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\language\Entity\ContentLanguageSettings;
|
||||
|
||||
/**
|
||||
* Base form for category edit forms.
|
||||
* The block content type entity form.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BlockContentTypeForm extends BundleEntityFormBase {
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\block_content;
|
||||
|
||||
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityViewBuilder;
|
||||
|
||||
@@ -41,18 +40,4 @@ class BlockContentViewBuilder extends EntityViewBuilder {
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function alterBuild(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
|
||||
parent::alterBuild($build, $entity, $display, $view_mode);
|
||||
// Add contextual links for this custom block.
|
||||
if (!$entity->isNew()) {
|
||||
$build['#contextual_links']['block_content'] = [
|
||||
'route_parameters' => ['block_content' => $entity->id()],
|
||||
'metadata' => ['changed' => $entity->getChangedTime()],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
namespace Drupal\block_content\Entity;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityChangedTrait;
|
||||
use Drupal\Core\Entity\EditorialContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
@@ -51,7 +50,8 @@ use Drupal\user\UserInterface;
|
||||
* "bundle" = "type",
|
||||
* "label" = "info",
|
||||
* "langcode" = "langcode",
|
||||
* "uuid" = "uuid"
|
||||
* "uuid" = "uuid",
|
||||
* "published" = "status",
|
||||
* },
|
||||
* revision_metadata_keys = {
|
||||
* "revision_user" = "revision_user",
|
||||
@@ -68,9 +68,7 @@ use Drupal\user\UserInterface;
|
||||
* caching.
|
||||
* See https://www.drupal.org/node/2284917#comment-9132521 for more information.
|
||||
*/
|
||||
class BlockContent extends ContentEntityBase implements BlockContentInterface {
|
||||
|
||||
use EntityChangedTrait;
|
||||
class BlockContent extends EditorialContentEntityBase implements BlockContentInterface {
|
||||
|
||||
/**
|
||||
* The theme the block is being created in.
|
||||
@@ -174,6 +172,8 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
|
||||
$fields['type']->setLabel(t('Block type'))
|
||||
->setDescription(t('The block type.'));
|
||||
|
||||
$fields['revision_log']->setDescription(t('The log entry explaining the changes in this revision.'));
|
||||
|
||||
$fields['info'] = BaseFieldDefinition::create('string')
|
||||
->setLabel(t('Block description'))
|
||||
->setDescription(t('A brief description of your block.'))
|
||||
@@ -187,35 +187,12 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
|
||||
->setDisplayConfigurable('form', TRUE)
|
||||
->addConstraint('UniqueField', []);
|
||||
|
||||
$fields['revision_log'] = BaseFieldDefinition::create('string_long')
|
||||
->setLabel(t('Revision log message'))
|
||||
->setDescription(t('The log entry explaining the changes in this revision.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setDisplayOptions('form', [
|
||||
'type' => 'string_textarea',
|
||||
'weight' => 25,
|
||||
'settings' => [
|
||||
'rows' => 4,
|
||||
],
|
||||
]);
|
||||
|
||||
$fields['changed'] = BaseFieldDefinition::create('changed')
|
||||
->setLabel(t('Changed'))
|
||||
->setDescription(t('The time that the custom block was last edited.'))
|
||||
->setTranslatable(TRUE)
|
||||
->setRevisionable(TRUE);
|
||||
|
||||
$fields['revision_created'] = BaseFieldDefinition::create('created')
|
||||
->setLabel(t('Revision create time'))
|
||||
->setDescription(t('The time that the current revision was created.'))
|
||||
->setRevisionable(TRUE);
|
||||
|
||||
$fields['revision_user'] = BaseFieldDefinition::create('entity_reference')
|
||||
->setLabel(t('Revision user'))
|
||||
->setDescription(t('The user ID of the author of the current revision.'))
|
||||
->setSetting('target_type', 'user')
|
||||
->setRevisionable(TRUE);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides a confirmation form for deleting a custom block entity.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BlockContentDeleteForm extends ContentEntityDeleteForm {
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides a confirmation form for deleting a custom block type entity.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BlockContentTypeDeleteForm extends EntityDeleteForm {
|
||||
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ package: Testing
|
||||
dependencies:
|
||||
- block_content
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@ dependencies:
|
||||
- block_content
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\block_content\Functional;
|
||||
|
||||
/**
|
||||
* Tests views contextual links on block content.
|
||||
*
|
||||
* @group block_content
|
||||
*/
|
||||
class BlockContentContextualLinksTest extends BlockContentTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'contextual',
|
||||
];
|
||||
|
||||
/**
|
||||
* Tests contextual links.
|
||||
*/
|
||||
public function testBlockContentContextualLinks() {
|
||||
$block_content = $this->createBlockContent();
|
||||
|
||||
$block = $this->placeBlock('block_content:' . $block_content->uuid());
|
||||
|
||||
$user = $this->drupalCreateUser([
|
||||
'administer blocks',
|
||||
'access contextual links',
|
||||
]);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertSession()->elementAttributeContains('css', 'div[data-contextual-id]', 'data-contextual-id', 'block:block=' . $block->id() . ':langcode=en|block_content:block_content=' . $block_content->id() . ':');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -63,7 +63,9 @@ class BlockContentCreationTest extends BlockContentTestBase {
|
||||
$this->assertNoFieldByXPath('//select[@name="settings[view_mode]"]', NULL, 'View mode setting hidden because only one exists');
|
||||
|
||||
// Check that the block exists in the database.
|
||||
$blocks = entity_load_multiple_by_properties('block_content', ['info' => $edit['info[0][value]']]);
|
||||
$blocks = \Drupal::entityTypeManager()
|
||||
->getStorage('block_content')
|
||||
->loadByProperties(['info' => $edit['info[0][value]']]);
|
||||
$block = reset($blocks);
|
||||
$this->assertTrue($block, 'Custom Block found in database.');
|
||||
|
||||
@@ -143,7 +145,9 @@ class BlockContentCreationTest extends BlockContentTestBase {
|
||||
$this->assertFieldByXPath('//select[@name="settings[view_mode]"]/option[@selected="selected"]', 'test_view_mode', 'View mode changed to Test View Mode');
|
||||
|
||||
// Check that the block exists in the database.
|
||||
$blocks = entity_load_multiple_by_properties('block_content', ['info' => $edit['info[0][value]']]);
|
||||
$blocks = \Drupal::entityTypeManager()
|
||||
->getStorage('block_content')
|
||||
->loadByProperties(['info' => $edit['info[0][value]']]);
|
||||
$block = reset($blocks);
|
||||
$this->assertTrue($block, 'Custom Block found in database.');
|
||||
|
||||
@@ -178,7 +182,9 @@ class BlockContentCreationTest extends BlockContentTestBase {
|
||||
]), 'Basic block created.');
|
||||
|
||||
// Check that the block exists in the database.
|
||||
$blocks = entity_load_multiple_by_properties('block_content', ['info' => $edit['info[0][value]']]);
|
||||
$blocks = \Drupal::entityTypeManager()
|
||||
->getStorage('block_content')
|
||||
->loadByProperties(['info' => $edit['info[0][value]']]);
|
||||
$block = reset($blocks);
|
||||
$this->assertTrue($block, 'Default Custom Block found in database.');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\block_content\Functional;
|
||||
|
||||
use Drupal\block_content\Entity\BlockContent;
|
||||
use Drupal\simpletest\BlockCreationTrait;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Tests unpublishing of block_content entities.
|
||||
*
|
||||
* @group block_content
|
||||
*/
|
||||
class UnpublishedBlockTest extends BrowserTestBase {
|
||||
|
||||
use BlockCreationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['block_content'];
|
||||
|
||||
/**
|
||||
* Tests unpublishing of block_content entities.
|
||||
*/
|
||||
public function testViewShowsCorrectStates() {
|
||||
$block_content = BlockContent::create([
|
||||
'info' => 'Test block',
|
||||
'type' => 'basic',
|
||||
]);
|
||||
$block_content->save();
|
||||
|
||||
$this->placeBlock('block_content:' . $block_content->uuid());
|
||||
|
||||
$this->drupalGet('<front>');
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertTrue($page->has('css', '.block-block-content' . $block_content->uuid()));
|
||||
|
||||
$block_content->setPublished(FALSE);
|
||||
$block_content->save();
|
||||
|
||||
$this->drupalGet('<front>');
|
||||
$page = $this->getSession()->getPage();
|
||||
$this->assertFalse($page->has('css', '.block-block-content' . $block_content->uuid()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,4 +43,27 @@ class BlockContentUpdateTest extends UpdatePathTestBase {
|
||||
$this->assertEqual('block_content_field_revision', $entity_type->getRevisionDataTable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests adding a status field to the block content entity type.
|
||||
*
|
||||
* @see block_content_update_8400()
|
||||
*/
|
||||
public function testStatusFieldAddition() {
|
||||
$schema = \Drupal::database()->schema();
|
||||
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Check that the field exists and has the correct label.
|
||||
$updated_field = $entity_definition_update_manager->getFieldStorageDefinition('status', 'block_content');
|
||||
$this->assertEqual('Publishing status', $updated_field->getLabel());
|
||||
|
||||
$content_translation_status = $entity_definition_update_manager->getFieldStorageDefinition('content_translation_status', 'block_content');
|
||||
$this->assertNull($content_translation_status);
|
||||
|
||||
$this->assertFalse($schema->fieldExists('block_content_field_revision', 'content_translation_status'));
|
||||
$this->assertFalse($schema->fieldExists('block_content_field_data', 'content_translation_status'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ hidden: true
|
||||
dependencies:
|
||||
- block
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-01-03
|
||||
version: '8.4.4'
|
||||
# Information added by Drupal.org packaging script on 2018-03-07
|
||||
version: '8.5.0'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1515021228
|
||||
datestamp: 1520457826
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
.block-place-region {
|
||||
outline: 1px dashed rgba(0,0,0,0.5);
|
||||
box-shadow: 0 0 0 1px rgba(255,255,255,0.7);
|
||||
outline: 1px dashed rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.7);
|
||||
margin: 1em 0;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
.block-place-region a.button {
|
||||
position: relative;
|
||||
background: url(../../../misc/icons/bebebe/plus.svg) #ffffff center center / 16px 16px no-repeat;
|
||||
border: 1px solid #cccccc;
|
||||
background: url(../../../misc/icons/bebebe/plus.svg) #fff center center / 16px 16px no-repeat;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user