updated core and modules

This commit is contained in:
Bachir Soussi Chiadmi
2017-09-09 16:27:51 +02:00
parent 027aa99b32
commit 41863f872c
7810 changed files with 318922 additions and 83631 deletions
@@ -7,10 +7,11 @@ package: Core
dependencies:
- block
- text
- user
configure: entity.block_content.collection
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233791
datestamp: 1502903957
@@ -39,3 +39,36 @@ function block_content_update_8002() {
// are stable.
// @see https://www.drupal.org/node/2569469
}
/**
* Add 'revision_created' and 'revision_user' fields to 'block_content' entities.
*/
function block_content_update_8003() {
$revision_created = BaseFieldDefinition::create('created')
->setLabel(t('Revision create time'))
->setDescription(t('The time that the current revision was created.'))
->setRevisionable(TRUE);
\Drupal::entityDefinitionUpdateManager()
->installFieldStorageDefinition('revision_created', 'block_content', 'block_content', $revision_created);
$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);
\Drupal::entityDefinitionUpdateManager()
->installFieldStorageDefinition('revision_user', 'block_content', 'block_content', $revision_user);
}
/**
* Fix the block_content entity type to specify its revision data table.
*/
function block_content_update_8300() {
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$entity_type = $definition_update_manager->getEntityType('block_content');
$entity_type->set('revision_data_table', 'block_content_field_revision');
$definition_update_manager->updateEntityType($entity_type);
}
@@ -1,8 +1,7 @@
# Deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
# This is just for BC and not used anymore. See https://www.drupal.org/node/2669802
drupal.block_content:
version: VERSION
js:
js/block_content.js: {}
js: {}
dependencies:
- core/jquery
- core/drupal
- core/drupal.form
- core/drupal.entity-form
@@ -2,9 +2,3 @@ block_content.block_edit:
title: 'Edit'
group: block_content
route_name: 'entity.block_content.canonical'
block_content.block_delete:
title: 'Delete'
group: block_content
route_name: 'entity.block_content.delete_form'
weight: 1
+16 -16
View File
@@ -15,25 +15,25 @@ use Drupal\field\Entity\FieldStorageConfig;
function block_content_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.block_content':
$field_ui = \Drupal::moduleHandler()->moduleExists('field_ui') ? \Drupal::url('help.page', array('name' => 'field_ui')) : '#';
$field_ui = \Drupal::moduleHandler()->moduleExists('field_ui') ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#';
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Custom Block module allows you to create and manage custom <em>block types</em> and <em>content-containing blocks</em> from the <a href = ":block-library" >Custom block library<a/> page. Custom block types have fields; see the <a href=":field-help">Field module help</a> for more information. Once created, custom blocks can be placed in regions just like blocks provided by other modules; see the <a href=":blocks">Block module help</a> page for details. For more information, see the <a href=":online-help">online documentation for the Custom Block module</a>.', array(':block-library' => \Drupal::url('entity.block_content.collection'), ':block-content' => \Drupal::url('entity.block_content.collection'), ':field-help' => \Drupal::url('help.page', array('name' => 'field')), ':blocks' => \Drupal::url('help.page', array('name' => 'block')), ':online-help' => 'https://www.drupal.org/documentation/modules/block_content')) . '</p>';
$output .= '<p>' . t('The Custom Block module allows you to create and manage custom <em>block types</em> and <em>content-containing blocks</em> from the <a href = ":block-library" >Custom block library</a> page. Custom block types have fields; see the <a href=":field-help">Field module help</a> for more information. Once created, custom blocks can be placed in regions just like blocks provided by other modules; see the <a href=":blocks">Block module help</a> page for details. For more information, see the <a href=":online-help">online documentation for the Custom Block module</a>.', [':block-library' => \Drupal::url('entity.block_content.collection'), ':block-content' => \Drupal::url('entity.block_content.collection'), ':field-help' => \Drupal::url('help.page', ['name' => 'field']), ':blocks' => \Drupal::url('help.page', ['name' => 'block']), ':online-help' => 'https://www.drupal.org/documentation/modules/block_content']) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Creating and managing custom block types') . '</dt>';
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can create and edit custom block types with fields and display settings, from the <a href=":types">Block types</a> page in the Custom block library. For more information about managing fields and display settings, see the <a href=":field-ui">Field UI module help</a>.', array(':types' => \Drupal::url('entity.block_content_type.collection'), ':field-ui' => $field_ui)) . '</dd>';
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can create and edit custom block types with fields and display settings, from the <a href=":types">Block types</a> page in the Custom block library. For more information about managing fields and display settings, see the <a href=":field-ui">Field UI module help</a>.', [':types' => \Drupal::url('entity.block_content_type.collection'), ':field-ui' => $field_ui]) . '</dd>';
$output .= '<dt>' . t('Creating custom blocks') . '</dt>';
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can create, edit, and delete custom blocks of each defined custom block type, from the <a href=":block-library">Blocks</a> page in the Custom block library. After creating a block, place it in a region from the <a href=":blocks">Block layout</a> page; see the <a href=":block_help">Block module help</a> for more information about placing blocks.', array(':blocks' => \Drupal::url('block.admin_display'), ':block-library' => \Drupal::url('entity.block_content.collection'), ':block_help' => \Drupal::url('help.page', array('name' => 'block')))) . '</dd>';
$output .= '<dd>' . t('Users with the <em>Administer blocks</em> permission can create, edit, and delete custom blocks of each defined custom block type, from the <a href=":block-library">Blocks</a> page in the Custom block library. After creating a block, place it in a region from the <a href=":blocks">Block layout</a> page; see the <a href=":block_help">Block module help</a> for more information about placing blocks.', [':blocks' => \Drupal::url('block.admin_display'), ':block-library' => \Drupal::url('entity.block_content.collection'), ':block_help' => \Drupal::url('help.page', ['name' => 'block'])]) . '</dd>';
$output .= '</dl>';
return $output;
case 'entity.block_content.collection':
$output = '<p>' . t('Blocks in the block library belong to <a href=":types">Custom block types</a>, each with its own fields and display settings. After creating a block, place it in a region from the <a href=":blocks">Block layout</a> page.', array(':types' => \Drupal::url('entity.block_content_type.collection'), ':blocks' => \Drupal::url('block.admin_display'))) . '</p>';
$output = '<p>' . t('Blocks in the block library belong to <a href=":types">Custom block types</a>, each with its own fields and display settings. After creating a block, place it in a region from the <a href=":blocks">Block layout</a> page.', [':types' => \Drupal::url('entity.block_content_type.collection'), ':blocks' => \Drupal::url('block.admin_display')]) . '</p>';
return $output;
case 'entity.block_content_type.collection':
$output = '<p>' . t('Each block type has its own fields and display settings. Create blocks of each type on the <a href=":block-library">Blocks</a> page in the custom block library.', array(':block-library' => \Drupal::url('entity.block_content.collection'))) . '</p>';
$output = '<p>' . t('Each block type has its own fields and display settings. Create blocks of each type on the <a href=":block-library">Blocks</a> page in the custom block library.', [':block-library' => \Drupal::url('entity.block_content.collection')]) . '</p>';
return $output;
}
@@ -43,12 +43,12 @@ function block_content_help($route_name, RouteMatchInterface $route_match) {
* Implements hook_theme().
*/
function block_content_theme($existing, $type, $theme, $path) {
return array(
'block_content_add_list' => array(
'variables' => array('content' => NULL),
return [
'block_content_add_list' => [
'variables' => ['content' => NULL],
'file' => 'block_content.pages.inc',
),
);
],
];
}
/**
@@ -83,23 +83,23 @@ function block_content_add_body_field($block_type_id, $label = 'Body') {
'field_storage' => FieldStorageConfig::loadByName('block_content', 'body'),
'bundle' => $block_type_id,
'label' => $label,
'settings' => array('display_summary' => FALSE),
'settings' => ['display_summary' => FALSE],
]);
$field->save();
// Assign widget settings for the 'default' form mode.
entity_get_form_display('block_content', $block_type_id, 'default')
->setComponent('body', array(
->setComponent('body', [
'type' => 'text_textarea_with_summary',
))
])
->save();
// Assign display settings for 'default' view mode.
entity_get_display('block_content', $block_type_id, 'default')
->setComponent('body', array(
->setComponent('body', [
'label' => 'hidden',
'type' => 'text_default',
))
])
->save();
}
@@ -19,18 +19,18 @@ use Drupal\Core\Url;
* @see block_content_add_page()
*/
function template_preprocess_block_content_add_list(&$variables) {
$variables['types'] = array();
$variables['types'] = [];
$query = \Drupal::request()->query->all();
foreach ($variables['content'] as $type) {
$variables['types'][$type->id()] = array(
'link' => \Drupal::l($type->label(), new Url('block_content.add_form', array('block_content_type' => $type->id()), array('query' => $query))),
'description' => array(
$variables['types'][$type->id()] = [
'link' => \Drupal::l($type->label(), new Url('block_content.add_form', ['block_content_type' => $type->id()], ['query' => $query])),
'description' => [
'#markup' => $type->getDescription(),
),
],
'title' => $type->label(),
'localized_options' => array(
'localized_options' => [
'query' => $query,
),
);
],
];
}
}
@@ -79,6 +79,7 @@ entity.block_content_type.edit_form:
path: '/admin/structure/block/block-content/manage/{block_content_type}'
defaults:
_entity_form: 'block_content_type.edit'
_title_callback: '\Drupal\Core\Entity\Controller\EntityController::title'
requirements:
_entity_access: 'block_content_type.update'
@@ -30,3 +30,6 @@ destination:
migration_dependencies:
required:
- block_content_type
provider:
- block_content
- migrate_drupal
@@ -0,0 +1,39 @@
id: block_content_entity_display
label: Body field display configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: embedded_data
data_rows:
-
entity_type: block_content
bundle: basic
view_mode: default
field_name: body
options:
label: hidden
ids:
entity_type:
type: string
bundle:
type: string
view_mode:
type: string
field_name:
type: string
process:
entity_type: entity_type
bundle: bundle
view_mode: view_mode
field_name: field_name
options: options
destination:
plugin: component_entity_display
migration_dependencies:
required:
- block_content_body_field
provider:
- block_content
- migrate_drupal
@@ -0,0 +1,36 @@
id: block_content_entity_form_display
label: Body field form display configuration
migration_tags:
- Drupal 6
- Drupal 7
source:
plugin: embedded_data
data_rows:
-
entity_type: block_content
bundle: basic
form_mode: default
field_name: body
ids:
entity_type:
type: string
bundle:
type: string
form_mode:
type: string
field_name:
type: string
process:
entity_type: entity_type
bundle: bundle
form_mode: form_mode
field_name: field_name
destination:
plugin: component_entity_form_display
migration_dependencies:
required:
- block_content_body_field
provider:
- block_content
- migrate_drupal
@@ -17,3 +17,6 @@ process:
label: label
destination:
plugin: entity:block_content_type
provider:
- block_content
- migrate_drupal
@@ -8,7 +8,7 @@ process:
id: bid
info: info
'body/format':
plugin: migration
plugin: migration_lookup
migration: d6_filter_format
source: format
'body/value': body
@@ -8,7 +8,7 @@ process:
id: bid
info: info
'body/format':
plugin: migration
plugin: migration_lookup
migration: d7_filter_format
source: format
'body/value': body
@@ -4,38 +4,13 @@ namespace Drupal\block_content;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form handler for the custom block edit forms.
*/
class BlockContentForm extends ContentEntityForm {
/**
* The custom block storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $blockContentStorage;
/**
* The custom block type storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $blockContentTypeStorage;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The block content entity.
*
@@ -43,122 +18,23 @@ class BlockContentForm extends ContentEntityForm {
*/
protected $entity;
/**
* Constructs a BlockContentForm object.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
* @param \Drupal\Core\Entity\EntityStorageInterface $block_content_storage
* The custom block storage.
* @param \Drupal\Core\Entity\EntityStorageInterface $block_content_type_storage
* The custom block type storage.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
*/
public function __construct(EntityManagerInterface $entity_manager, EntityStorageInterface $block_content_storage, EntityStorageInterface $block_content_type_storage, LanguageManagerInterface $language_manager) {
parent::__construct($entity_manager);
$this->blockContentStorage = $block_content_storage;
$this->blockContentTypeStorage = $block_content_type_storage;
$this->languageManager = $language_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$entity_manager = $container->get('entity.manager');
return new static(
$entity_manager,
$entity_manager->getStorage('block_content'),
$entity_manager->getStorage('block_content_type'),
$container->get('language_manager')
);
}
/**
* Overrides \Drupal\Core\Entity\EntityForm::prepareEntity().
*
* Prepares the custom block object.
*
* Fills in a few default values, and then invokes
* hook_block_content_prepare() on all modules.
*/
protected function prepareEntity() {
$block = $this->entity;
// Set up default values, if required.
$block_type = $this->blockContentTypeStorage->load($block->bundle());
if (!$block->isNew()) {
$block->setRevisionLog(NULL);
}
// Always use the default revision setting.
$block->setNewRevision($block_type->shouldCreateNewRevision());
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$block = $this->entity;
$account = $this->currentUser();
$form = parent::form($form, $form_state);
if ($this->operation == 'edit') {
$form['#title'] = $this->t('Edit custom block %label', array('%label' => $block->label()));
$form['#title'] = $this->t('Edit custom block %label', ['%label' => $block->label()]);
}
// Override the default CSS class name, since the user-defined custom block
// type name in 'TYPE-block-form' potentially clashes with third-party class
// names.
$form['#attributes']['class'][0] = 'block-' . Html::getClass($block->bundle()) . '-form';
$form['advanced'] = array(
'#type' => 'vertical_tabs',
'#weight' => 99,
);
// Add a log field if the "Create new revision" option is checked, or if the
// current user has the ability to check that option.
$form['revision_information'] = array(
'#type' => 'details',
'#title' => $this->t('Revision information'),
// Open by default when "Create new revision" is checked.
'#open' => $block->isNewRevision(),
'#group' => 'advanced',
'#attributes' => array(
'class' => array('block-content-form-revision-information'),
),
'#attached' => array(
'library' => array('block_content/drupal.block_content'),
),
'#weight' => 20,
'#access' => $block->isNewRevision() || $account->hasPermission('administer blocks'),
);
$form['revision_information']['revision'] = array(
'#type' => 'checkbox',
'#title' => $this->t('Create new revision'),
'#default_value' => $block->isNewRevision(),
'#access' => $account->hasPermission('administer blocks'),
);
// Check the revision log checkbox when the log textarea is filled in.
// This must not happen if "Create new revision" is enabled by default,
// since the state would auto-disable the checkbox otherwise.
if (!$block->isNewRevision()) {
$form['revision_information']['revision']['#states'] = array(
'checked' => array(
'textarea[name="revision_log"]' => array('empty' => FALSE),
),
);
}
$form['revision_information']['revision_log'] = array(
'#type' => 'textarea',
'#title' => $this->t('Revision log message'),
'#rows' => 4,
'#default_value' => $block->getRevisionLog(),
'#description' => $this->t('Briefly describe the changes you have made.'),
);
return parent::form($form, $form_state, $block);
return $form;
}
/**
@@ -167,17 +43,12 @@ class BlockContentForm extends ContentEntityForm {
public function save(array $form, FormStateInterface $form_state) {
$block = $this->entity;
// Save as a new revision if requested to do so.
if (!$form_state->isValueEmpty('revision')) {
$block->setNewRevision();
}
$insert = $block->isNew();
$block->save();
$context = array('@type' => $block->bundle(), '%info' => $block->label());
$context = ['@type' => $block->bundle(), '%info' => $block->label()];
$logger = $this->logger('block_content');
$block_type = $this->blockContentTypeStorage->load($block->bundle());
$t_args = array('@type' => $block_type->label(), '%info' => $block->label());
$block_type = $this->getBundleEntity();
$t_args = ['@type' => $block_type->label(), '%info' => $block->label()];
if ($insert) {
$logger->notice('@type: added %info.', $context);
@@ -197,10 +68,10 @@ class BlockContentForm extends ContentEntityForm {
}
$form_state->setRedirect(
'block.admin_add',
array(
[
'plugin_id' => 'block_content:' . $block->uuid(),
'theme' => $theme,
)
]
);
}
else {
@@ -4,17 +4,21 @@ namespace Drupal\block_content;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\RevisionLogInterface;
/**
* Provides an interface defining a custom block entity.
*/
interface BlockContentInterface extends ContentEntityInterface, EntityChangedInterface {
interface BlockContentInterface extends ContentEntityInterface, EntityChangedInterface, RevisionLogInterface {
/**
* Returns the block revision log message.
*
* @return string
* The revision log message.
*
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
* \Drupal\Core\Entity\RevisionLogInterface::getRevisionLogMessage() instead.
*/
public function getRevisionLog();
@@ -37,6 +41,9 @@ interface BlockContentInterface extends ContentEntityInterface, EntityChangedInt
*
* @return \Drupal\block_content\BlockContentInterface
* The class instance that this method is called on.
*
* @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0. Use
* \Drupal\Core\Entity\RevisionLogInterface::setRevisionLogMessage() instead.
*/
public function setRevisionLog($revision_log);
@@ -4,6 +4,7 @@ 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.
@@ -12,6 +13,8 @@ use Drupal\Core\Entity\EntityListBuilder;
*/
class BlockContentListBuilder extends EntityListBuilder {
use RedirectDestinationTrait;
/**
* {@inheritdoc}
*/
@@ -34,7 +37,7 @@ class BlockContentListBuilder extends EntityListBuilder {
public function getDefaultOperations(EntityInterface $entity) {
$operations = parent::getDefaultOperations($entity);
if (isset($operations['edit'])) {
$operations['edit']['query']['destination'] = $entity->url('collection');
$operations['edit']['query']['destination'] = $this->getRedirectDestination()->get();
}
return $operations;
}
@@ -5,36 +5,18 @@ namespace Drupal\block_content;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Core\Entity\EntityInterface;
use Drupal\content_translation\ContentTranslationHandler;
use Drupal\Core\Form\FormStateInterface;
/**
* Defines the translation handler for custom blocks.
*/
class BlockContentTranslationHandler extends ContentTranslationHandler {
/**
* {@inheritdoc}
*/
public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) {
parent::entityFormAlter($form, $form_state, $entity);
// Move the translation fieldset to a vertical tab.
if (isset($form['translation'])) {
$form['translation'] += array(
'#group' => 'additional_settings',
'#weight' => 100,
'#attributes' => array(
'class' => array('block-content-translation-options'),
),
);
}
}
/**
* {@inheritdoc}
*/
protected function entityFormTitle(EntityInterface $entity) {
$block_type = BlockContentType::load($entity->bundle());
return t('<em>Edit @type</em> @title', array('@type' => $block_type->label(), '@title' => $entity->label()));
return t('<em>Edit @type</em> @title', ['@type' => $block_type->label(), '@title' => $entity->label()]);
}
}
@@ -25,65 +25,65 @@ class BlockContentTypeForm extends BundleEntityFormBase {
$form['#title'] = $this->t('Add custom block type');
}
else {
$form['#title'] = $this->t('Edit %label custom block type', array('%label' => $block_type->label()));
$form['#title'] = $this->t('Edit %label custom block type', ['%label' => $block_type->label()]);
}
$form['label'] = array(
$form['label'] = [
'#type' => 'textfield',
'#title' => t('Label'),
'#maxlength' => 255,
'#default_value' => $block_type->label(),
'#description' => t("Provide a label for this block type to help identify it in the administration pages."),
'#required' => TRUE,
);
$form['id'] = array(
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $block_type->id(),
'#machine_name' => array(
'#machine_name' => [
'exists' => '\Drupal\block_content\Entity\BlockContentType::load',
),
],
'#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
);
];
$form['description'] = array(
$form['description'] = [
'#type' => 'textarea',
'#default_value' => $block_type->getDescription(),
'#description' => t('Enter a description for this block type.'),
'#title' => t('Description'),
);
];
$form['revision'] = array(
$form['revision'] = [
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $block_type->shouldCreateNewRevision(),
'#description' => t('Create a new revision by default for this block type.'),
);
];
if ($this->moduleHandler->moduleExists('language')) {
$form['language'] = array(
$form['language'] = [
'#type' => 'details',
'#title' => t('Language settings'),
'#group' => 'additional_settings',
);
];
$language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('block_content', $block_type->id());
$form['language']['language_configuration'] = array(
$form['language']['language_configuration'] = [
'#type' => 'language_configuration',
'#entity_information' => array(
'#entity_information' => [
'entity_type' => 'block_content',
'bundle' => $block_type->id(),
),
],
'#default_value' => $language_configuration,
);
];
$form['#submit'][] = 'language_configuration_element_submit';
}
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
$form['actions'] = ['#type' => 'actions'];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => t('Save'),
);
];
return $this->protectBundleIdElement($form);
}
@@ -98,13 +98,13 @@ class BlockContentTypeForm extends BundleEntityFormBase {
$edit_link = $this->entity->link($this->t('Edit'));
$logger = $this->logger('block_content');
if ($status == SAVED_UPDATED) {
drupal_set_message(t('Custom block type %label has been updated.', array('%label' => $block_type->label())));
$logger->notice('Custom block type %label has been updated.', array('%label' => $block_type->label(), 'link' => $edit_link));
drupal_set_message(t('Custom block type %label has been updated.', ['%label' => $block_type->label()]));
$logger->notice('Custom block type %label has been updated.', ['%label' => $block_type->label(), 'link' => $edit_link]);
}
else {
block_content_add_body_field($block_type->id());
drupal_set_message(t('Custom block type %label has been added.', array('%label' => $block_type->label())));
$logger->notice('Custom block type %label has been added.', array('%label' => $block_type->label(), 'link' => $edit_link));
drupal_set_message(t('Custom block type %label has been added.', ['%label' => $block_type->label()]));
$logger->notice('Custom block type %label has been added.', ['%label' => $block_type->label(), 'link' => $edit_link]);
}
$form_state->setRedirectUrl($this->entity->urlInfo('collection'));
@@ -3,11 +3,12 @@
namespace Drupal\block_content;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\RevisionableEntityBundleInterface;
/**
* Provides an interface defining a custom block type entity.
*/
interface BlockContentTypeInterface extends ConfigEntityInterface {
interface BlockContentTypeInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface {
/**
* Returns the description of the block type.
@@ -17,12 +18,4 @@ interface BlockContentTypeInterface extends ConfigEntityInterface {
*/
public function getDescription();
/**
* Returns whether a new revision should be created by default.
*
* @return bool
* TRUE if a new revision should be created by default.
*/
public function shouldCreateNewRevision();
}
@@ -15,13 +15,13 @@ class BlockContentViewBuilder extends EntityViewBuilder {
* {@inheritdoc}
*/
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
return $this->viewMultiple(array($entity), $view_mode, $langcode)[0];
return $this->viewMultiple([$entity], $view_mode, $langcode)[0];
}
/**
* {@inheritdoc}
*/
public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
public function viewMultiple(array $entities = [], $view_mode = 'full', $langcode = NULL) {
$build_list = parent::viewMultiple($entities, $view_mode, $langcode);
// Apply the buildMultiple() #pre_render callback immediately, to make
// bubbling of attributes and contextual links to the actual block work.
@@ -48,10 +48,10 @@ class BlockContentViewBuilder extends EntityViewBuilder {
parent::alterBuild($build, $entity, $display, $view_mode);
// Add contextual links for this custom block.
if (!$entity->isNew()) {
$build['#contextual_links']['block_content'] = array(
'route_parameters' => array('block_content' => $entity->id()),
'metadata' => array('changed' => $entity->getChangedTime()),
);
$build['#contextual_links']['block_content'] = [
'route_parameters' => ['block_content' => $entity->id()],
'metadata' => ['changed' => $entity->getChangedTime()],
];
}
}
@@ -23,13 +23,13 @@ class BlockContentViewsData extends EntityViewsData {
$data['block_content_field_data']['type']['field']['id'] = 'field';
$data['block_content']['block_content_listing_empty'] = array(
$data['block_content']['block_content_listing_empty'] = [
'title' => $this->t('Empty block library behavior'),
'help' => $this->t('Provides a link to add a new block.'),
'area' => array(
'area' => [
'id' => 'block_content_listing_empty',
),
);
],
];
// Advertise this table as a possible base table.
$data['block_content_field_revision']['table']['base']['help'] = $this->t('Block Content revision is a history of changes to block content.');
$data['block_content_field_revision']['table']['base']['defaults']['title'] = 'info';
@@ -79,14 +79,14 @@ class BlockContentController extends ControllerBase {
return $this->addForm($type, $request);
}
if (count($types) === 0) {
return array(
return [
'#markup' => $this->t('You have not created any block types yet. Go to the <a href=":url">block type creation page</a> to add a new block type.', [
':url' => Url::fromRoute('block_content.type_add')->toString(),
]),
);
];
}
return array('#theme' => 'block_content_add_list', '#content' => $types);
return ['#theme' => 'block_content_add_list', '#content' => $types];
}
/**
@@ -101,9 +101,9 @@ class BlockContentController extends ControllerBase {
* A form array as expected by drupal_render().
*/
public function addForm(BlockContentTypeInterface $block_content_type, Request $request) {
$block = $this->blockContentStorage->create(array(
$block = $this->blockContentStorage->create([
'type' => $block_content_type->id()
));
]);
if (($theme = $request->query->get('theme')) && in_array($theme, array_keys($this->themeHandler->listInfo()))) {
// We have navigated to this page from the block library and will keep track
// of the theme for redirecting the user to the configuration page for the
@@ -123,7 +123,7 @@ class BlockContentController extends ControllerBase {
* The page title.
*/
public function getAddFormTitle(BlockContentTypeInterface $block_content_type) {
return $this->t('Add %type custom block', array('%type' => $block_content_type->label()));
return $this->t('Add %type custom block', ['%type' => $block_content_type->label()]);
}
}
@@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\block_content\BlockContentInterface;
use Drupal\user\UserInterface;
/**
* Defines the custom block entity class.
@@ -34,6 +35,8 @@ use Drupal\block_content\BlockContentInterface;
* base_table = "block_content",
* revision_table = "block_content_revision",
* data_table = "block_content_field_data",
* revision_data_table = "block_content_field_revision",
* show_revision_ui = TRUE,
* links = {
* "canonical" = "/block/{block_content}",
* "delete-form" = "/block/{block_content}/delete",
@@ -104,16 +107,22 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
static::invalidateBlockPluginCache();
}
// Invalidate the block cache to update custom block-based derivatives.
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
/**
* {@inheritdoc}
*/
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
static::invalidateBlockPluginCache();
}
/**
* {@inheritdoc}
*/
public function getInstances() {
return entity_load_multiple_by_properties('block', array('plugin' => 'block_content:' . $this->uuid()));
return \Drupal::entityTypeManager()->getStorage('block')->loadByProperties(['plugin' => 'block_content:' . $this->uuid()]);
}
/**
@@ -126,7 +135,7 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
// If we are updating an existing block_content without adding a new
// revision and the user did not supply a revision log, keep the existing
// one.
$record->revision_log = $this->original->getRevisionLog();
$record->revision_log = $this->original->getRevisionLogMessage();
}
}
@@ -144,35 +153,20 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields['id'] = BaseFieldDefinition::create('integer')
->setLabel(t('Custom block ID'))
->setDescription(t('The custom block ID.'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
$fields = parent::baseFieldDefinitions($entity_type);
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The custom block UUID.'))
->setReadOnly(TRUE);
$fields['id']->setLabel(t('Custom block ID'))
->setDescription(t('The custom block ID.'));
$fields['revision_id'] = BaseFieldDefinition::create('integer')
->setLabel(t('Revision ID'))
->setDescription(t('The revision ID.'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
$fields['uuid']->setDescription(t('The custom block UUID.'));
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language'))
->setDescription(t('The custom block language code.'))
->setTranslatable(TRUE)
->setRevisionable(TRUE)
->setDisplayOptions('view', array(
'type' => 'hidden',
))
->setDisplayOptions('form', array(
'type' => 'language_select',
'weight' => 2,
));
$fields['revision_id']->setDescription(t('The revision ID.'));
$fields['langcode']->setDescription(t('The custom block language code.'));
$fields['type']->setLabel(t('Block type'))
->setDescription(t('The block type.'));
$fields['info'] = BaseFieldDefinition::create('string')
->setLabel(t('Block description'))
@@ -180,23 +174,24 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
->setRevisionable(TRUE)
->setTranslatable(TRUE)
->setRequired(TRUE)
->setDisplayOptions('form', array(
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -5,
))
])
->setDisplayConfigurable('form', TRUE)
->addConstraint('UniqueField', []);
$fields['type'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Block type'))
->setDescription(t('The block type.'))
->setSetting('target_type', 'block_content_type');
$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);
->setRevisionable(TRUE)
->setDisplayOptions('form', [
'type' => 'string_textarea',
'weight' => 25,
'settings' => [
'rows' => 4,
],
]);
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
@@ -204,6 +199,17 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
->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);
$fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Revision translation affected'))
->setDescription(t('Indicates if the last edit of a translation belongs to current revision.'))
@@ -218,7 +224,7 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
* {@inheritdoc}
*/
public function getRevisionLog() {
return $this->get('revision_log')->value;
return $this->getRevisionLogMessage();
}
/**
@@ -233,8 +239,72 @@ class BlockContent extends ContentEntityBase implements BlockContentInterface {
* {@inheritdoc}
*/
public function setRevisionLog($revision_log) {
$this->set('revision_log', $revision_log);
return $this->setRevisionLogMessage($revision_log);
}
/**
* {@inheritdoc}
*/
public function getRevisionCreationTime() {
return $this->get('revision_created')->value;
}
/**
* {@inheritdoc}
*/
public function setRevisionCreationTime($timestamp) {
$this->set('revision_created', $timestamp);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionUser() {
return $this->get('revision_user')->entity;
}
public function setRevisionUser(UserInterface $account) {
$this->set('revision_user', $account);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionUserId() {
return $this->get('revision_user')->entity->id();
}
/**
* {@inheritdoc}
*/
public function setRevisionUserId($user_id) {
$this->set('revision_user', $user_id);
return $this;
}
/**
* {@inheritdoc}
*/
public function getRevisionLogMessage() {
return $this->get('revision_log')->value;
}
/**
* {@inheritdoc}
*/
public function setRevisionLogMessage($revision_log_message) {
$this->set('revision_log', $revision_log_message);
return $this;
}
/**
* Invalidates the block plugin cache after changes and deletions.
*/
protected static function invalidateBlockPluginCache() {
// Invalidate the block cache to update custom block-based derivatives.
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
}
}
@@ -16,10 +16,10 @@ class BlockContentDeleteForm extends ContentEntityDeleteForm {
public function buildForm(array $form, FormStateInterface $form_state) {
$instances = $this->entity->getInstances();
$form['message'] = array(
$form['message'] = [
'#markup' => $this->formatPlural(count($instances), 'This will also remove 1 placed block instance.', 'This will also remove @count placed block instances.'),
'#access' => !empty($instances),
);
];
return parent::buildForm($form, $form_state);
}
@@ -3,49 +3,23 @@
namespace Drupal\block_content\Form;
use Drupal\Core\Entity\EntityDeleteForm;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a confirmation form for deleting a custom block type entity.
*/
class BlockContentTypeDeleteForm extends EntityDeleteForm {
/**
* The query factory to create entity queries.
*
* @var \Drupal\Core\Entity\Query\QueryFactory
*/
public $queryFactory;
/**
* Constructs a query factory object.
*
* @param \Drupal\Core\Entity\Query\QueryFactory $query_factory
* The entity query object.
*/
public function __construct(QueryFactory $query_factory) {
$this->queryFactory = $query_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.query')
);
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$blocks = $this->queryFactory->get('block_content')->condition('type', $this->entity->id())->execute();
$blocks = $this->entityTypeManager->getStorage('block_content')->getQuery()
->condition('type', $this->entity->id())
->execute();
if (!empty($blocks)) {
$caption = '<p>' . $this->formatPlural(count($blocks), '%label is used by 1 custom block on your site. You can not remove this block type until you have removed all of the %label blocks.', '%label is used by @count custom blocks on your site. You may not remove %label until you have removed all of the %label custom blocks.', array('%label' => $this->entity->label())) . '</p>';
$form['description'] = array('#markup' => $caption);
$caption = '<p>' . $this->formatPlural(count($blocks), '%label is used by 1 custom block on your site. You can not remove this block type until you have removed all of the %label blocks.', '%label is used by @count custom blocks on your site. You may not remove %label until you have removed all of the %label custom blocks.', ['%label' => $this->entity->label()]) . '</p>';
$form['description'] = ['#markup' => $caption];
return $form;
}
else {
@@ -105,11 +105,11 @@ class BlockContentBlock extends BlockBase implements ContainerFactoryPluginInter
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array(
return [
'status' => TRUE,
'info' => '',
'view_mode' => 'full',
);
];
}
/**
@@ -122,14 +122,14 @@ class BlockContentBlock extends BlockBase implements ContainerFactoryPluginInter
$block = $this->entityManager->loadEntityByUuid('block_content', $uuid);
$options = $this->entityManager->getViewModeOptionsByBundle('block_content', $block->bundle());
$form['view_mode'] = array(
$form['view_mode'] = [
'#type' => 'select',
'#options' => $options,
'#title' => $this->t('View mode'),
'#description' => $this->t('Output the block in this view mode.'),
'#default_value' => $this->configuration['view_mode'],
'#access' => (count($options) > 1),
);
];
$form['title']['#description'] = $this->t('The title of the block as shown to the user.');
return $form;
}
@@ -161,13 +161,13 @@ class BlockContentBlock extends BlockBase implements ContainerFactoryPluginInter
return $this->entityManager->getViewBuilder($block->getEntityTypeId())->view($block, $this->configuration['view_mode']);
}
else {
return array(
'#markup' => $this->t('Block with uuid %uuid does not exist. <a href=":url">Add custom block</a>.', array(
return [
'#markup' => $this->t('Block with uuid %uuid does not exist. <a href=":url">Add custom block</a>.', [
'%uuid' => $this->getDerivativeId(),
':url' => $this->urlGenerator->generate('block_content.add_page')
)),
]),
'#access' => $this->account->hasPermission('administer blocks')
);
];
}
}
@@ -178,8 +178,8 @@ class BlockContentBlock extends BlockBase implements ContainerFactoryPluginInter
* The block content entity.
*/
protected function getEntity() {
$uuid = $this->getDerivativeId();
if (!isset($this->blockContent)) {
$uuid = $this->getDerivativeId();
$this->blockContent = $this->entityManager->loadEntityByUuid('block_content', $uuid);
}
return $this->blockContent;
@@ -44,13 +44,15 @@ class BlockContent extends DeriverBase implements ContainerDeriverInterface {
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$block_contents = $this->blockContentStorage->loadMultiple();
// Reset the discovered definitions.
$this->derivatives = [];
/** @var $block_content \Drupal\block_content\Entity\BlockContent */
foreach ($block_contents as $block_content) {
$this->derivatives[$block_content->uuid()] = $base_plugin_definition;
$this->derivatives[$block_content->uuid()]['admin_label'] = $block_content->label();
$this->derivatives[$block_content->uuid()]['config_dependencies']['content'] = array(
$this->derivatives[$block_content->uuid()]['config_dependencies']['content'] = [
$block_content->getConfigDependencyName()
);
];
}
return parent::getDerivativeDefinitions($base_plugin_definition);
}
@@ -18,7 +18,7 @@ class Box extends DrupalSqlBase {
*/
public function query() {
$query = $this->select('boxes', 'b')
->fields('b', array('bid', 'body', 'info', 'format'));
->fields('b', ['bid', 'body', 'info', 'format']);
$query->orderBy('b.bid');
return $query;
@@ -28,12 +28,12 @@ class Box extends DrupalSqlBase {
* {@inheritdoc}
*/
public function fields() {
return array(
return [
'bid' => $this->t('The numeric identifier of the block/box'),
'body' => $this->t('The block/box content'),
'info' => $this->t('Admin title of the block/box.'),
'format' => $this->t('Input format of the custom block/box content.'),
);
];
}
/**
@@ -24,12 +24,12 @@ class BlockCustom extends DrupalSqlBase {
* {@inheritdoc}
*/
public function fields() {
return array(
return [
'bid' => $this->t('The numeric identifier of the block/box'),
'body' => $this->t('The block/box content'),
'info' => $this->t('Admin title of the block/box.'),
'format' => $this->t('Input format of the custom block/box content.'),
);
];
}
/**
@@ -71,19 +71,19 @@ class ListingEmpty extends AreaPluginBase {
public function render($empty = FALSE) {
if (!$empty || !empty($this->options['empty'])) {
/** @var \Drupal\Core\Access\AccessResultInterface|\Drupal\Core\Cache\CacheableDependencyInterface $access_result */
$access_result = $this->accessManager->checkNamedRoute('block_content.add_page', array(), $this->currentUser, TRUE);
$element = array(
'#markup' => $this->t('Add a <a href=":url">custom block</a>.', array(':url' => Url::fromRoute('block_content.add_page')->toString())),
$access_result = $this->accessManager->checkNamedRoute('block_content.add_page', [], $this->currentUser, TRUE);
$element = [
'#markup' => $this->t('Add a <a href=":url">custom block</a>.', [':url' => Url::fromRoute('block_content.add_page')->toString()]),
'#access' => $access_result->isAllowed(),
'#cache' => [
'contexts' => $access_result->getCacheContexts(),
'tags' => $access_result->getCacheTags(),
'max-age' => $access_result->getCacheMaxAge(),
],
);
];
return $element;
}
return array();
return [];
}
}
@@ -8,6 +8,9 @@ use Drupal\simpletest\WebTestBase;
/**
* Sets up block content types.
*
* @deprecated Scheduled for removal in Drupal 9.0.0.
* Use \Drupal\Tests\block_content\Functional\BlockContentTestBase instead.
*/
abstract class BlockContentTestBase extends WebTestBase {
@@ -19,7 +22,7 @@ abstract class BlockContentTestBase extends WebTestBase {
/**
* Admin user
*
* @var object
* @var \Drupal\user\UserInterface
*/
protected $adminUser;
@@ -28,16 +31,16 @@ abstract class BlockContentTestBase extends WebTestBase {
*
* @var array
*/
protected $permissions = array(
protected $permissions = [
'administer blocks'
);
];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('block', 'block_content');
public static $modules = ['block', 'block_content'];
/**
* Whether or not to auto-create the basic block type during setup.
@@ -75,11 +78,11 @@ abstract class BlockContentTestBase extends WebTestBase {
*/
protected function createBlockContent($title = FALSE, $bundle = 'basic', $save = TRUE) {
$title = $title ?: $this->randomMachineName();
$block_content = BlockContent::create(array(
$block_content = BlockContent::create([
'info' => $title,
'type' => $bundle,
'langcode' => 'en'
));
]);
if ($block_content && $save === TRUE) {
$block_content->save();
}
@@ -98,11 +101,11 @@ abstract class BlockContentTestBase extends WebTestBase {
* Created custom block type.
*/
protected function createBlockContentType($label, $create_body = FALSE) {
$bundle = BlockContentType::create(array(
$bundle = BlockContentType::create([
'id' => $label,
'label' => $label,
'revision' => FALSE,
));
]);
$bundle->save();
if ($create_body) {
block_content_add_body_field($bundle->id());
@@ -4,6 +4,8 @@ namespace Drupal\block_content\Tests;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\system\Tests\Menu\AssertBreadcrumbTrait;
/**
* Ensures that custom block type functions work correctly.
@@ -12,22 +14,23 @@ use Drupal\Component\Utility\Html;
*/
class BlockContentTypeTest extends BlockContentTestBase {
use AssertBreadcrumbTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('field_ui');
public static $modules = ['field_ui'];
/**
* Permissions to grant admin user.
*
* @var array
*/
protected $permissions = array(
protected $permissions = [
'administer blocks',
'administer block_content fields'
);
];
/**
* Whether or not to create an initial block type.
@@ -56,10 +59,10 @@ class BlockContentTypeTest extends BlockContentTestBase {
$this->clickLink('block type creation page');
// Create a block type via the user interface.
$edit = array(
$edit = [
'id' => 'foo',
'label' => 'title for foo',
);
];
$this->drupalPostForm(NULL, $edit, t('Save'));
$block_type = BlockContentType::load('foo');
$this->assertTrue($block_type, 'The new block type has been created.');
@@ -91,6 +94,7 @@ class BlockContentTypeTest extends BlockContentTestBase {
* Tests editing a block type using the UI.
*/
public function testBlockContentTypeEditing() {
$this->drupalPlaceBlock('system_breadcrumb_block');
// Now create an initial block-type.
$this->createBlockContentType('basic', TRUE);
@@ -107,12 +111,19 @@ class BlockContentTypeTest extends BlockContentTestBase {
$this->assertRaw('Body', 'Body field was found.');
// Change the block type name.
$edit = array(
$edit = [
'label' => 'Bar',
);
];
$this->drupalGet('admin/structure/block/block-content/manage/basic');
$this->assertTitle(format_string('Edit @type custom block type | Drupal', ['@type' => 'basic']));
$this->drupalPostForm(NULL, $edit, t('Save'));
$front_page_path = Url::fromRoute('<front>')->toString();
$this->assertBreadcrumb('admin/structure/block/block-content/manage/basic/fields', [
$front_page_path => 'Home',
'admin/structure/block' => 'Block layout',
'admin/structure/block/block-content' => 'Custom block library',
'admin/structure/block/block-content/manage/basic' => 'Bar',
]);
\Drupal::entityManager()->clearCachedFieldDefinitions();
$this->drupalGet('block/add');
@@ -121,9 +132,9 @@ class BlockContentTypeTest extends BlockContentTestBase {
$this->assertUrl(\Drupal::url('block_content.add_form', ['block_content_type' => 'basic'], ['absolute' => TRUE]), [], 'Original machine name was used in URL.');
// Remove the body field.
$this->drupalPostForm('admin/structure/block/block-content/manage/basic/fields/block_content.basic.body/delete', array(), t('Delete'));
$this->drupalPostForm('admin/structure/block/block-content/manage/basic/fields/block_content.basic.body/delete', [], t('Delete'));
// Resave the settings for this type.
$this->drupalPostForm('admin/structure/block/block-content/manage/basic', array(), t('Save'));
$this->drupalPostForm('admin/structure/block/block-content/manage/basic', [], t('Save'));
// Check that the body field doesn't exist.
$this->drupalGet('block/add/basic');
$this->assertNoRaw('Body', 'Body field was not found.');
@@ -146,7 +157,7 @@ class BlockContentTypeTest extends BlockContentTestBase {
// Attempt to delete the block type, which should not be allowed.
$this->drupalGet('admin/structure/block/block-content/manage/' . $type->id() . '/delete');
$this->assertRaw(
t('%label is used by 1 custom block on your site. You can not remove this block type until you have removed all of the %label blocks.', array('%label' => $type->label())),
t('%label is used by 1 custom block on your site. You can not remove this block type until you have removed all of the %label blocks.', ['%label' => $type->label()]),
'The block type will not be deleted until all blocks of that type are removed.'
);
$this->assertNoText(t('This action cannot be undone.'), 'The block type deletion confirmation form is not available.');
@@ -156,7 +167,7 @@ class BlockContentTypeTest extends BlockContentTestBase {
// Attempt to delete the block type, which should now be allowed.
$this->drupalGet('admin/structure/block/block-content/manage/' . $type->id() . '/delete');
$this->assertRaw(
t('Are you sure you want to delete the custom block type %type?', array('%type' => $type->id())),
t('Are you sure you want to delete the custom block type %type?', ['%type' => $type->id()]),
'The block type is available for deletion.'
);
$this->assertText(t('This action cannot be undone.'), 'The custom block type deletion confirmation form is available.');
@@ -197,22 +208,22 @@ class BlockContentTypeTest extends BlockContentTestBase {
$this->clickLink(t('Add custom block'));
// The seven theme has markup inside the link, we cannot use clickLink().
if ($default_theme == 'seven') {
$options = $theme != $default_theme ? array('query' => array('theme' => $theme)) : array();
$this->assertLinkByHref(\Drupal::url('block_content.add_form', array('block_content_type' => 'foo'), $options));
$options = $theme != $default_theme ? ['query' => ['theme' => $theme]] : [];
$this->assertLinkByHref(\Drupal::url('block_content.add_form', ['block_content_type' => 'foo'], $options));
$this->drupalGet('block/add/foo', $options);
}
else {
$this->clickLink('foo');
}
// Create a new block.
$edit = array('info[0][value]' => $this->randomMachineName(8));
$edit = ['info[0][value]' => $this->randomMachineName(8)];
$this->drupalPostForm(NULL, $edit, t('Save'));
$blocks = $storage->loadByProperties(array('info' => $edit['info[0][value]']));
$blocks = $storage->loadByProperties(['info' => $edit['info[0][value]']]);
if (!empty($blocks)) {
$block = reset($blocks);
$this->assertUrl(\Drupal::url('block.admin_add', array('plugin_id' => 'block_content:' . $block->uuid(), 'theme' => $theme), array('absolute' => TRUE)));
$this->drupalPostForm(NULL, array(), t('Save block'));
$this->assertUrl(\Drupal::url('block.admin_display_theme', array('theme' => $theme), array('absolute' => TRUE, 'query' => array('block-placement' => Html::getClass($edit['info[0][value]'])))));
$this->assertUrl(\Drupal::url('block.admin_add', ['plugin_id' => 'block_content:' . $block->uuid(), 'theme' => $theme], ['absolute' => TRUE]));
$this->drupalPostForm(NULL, ['region' => 'content'], t('Save block'));
$this->assertUrl(\Drupal::url('block.admin_display_theme', ['theme' => $theme], ['absolute' => TRUE, 'query' => ['block-placement' => Html::getClass($edit['info[0][value]'])]]));
}
else {
$this->fail('Could not load created block.');
@@ -225,11 +236,11 @@ class BlockContentTypeTest extends BlockContentTestBase {
$this->drupalGet('admin/structure/block/block-content');
$this->clickLink(t('Add custom block'));
$this->clickLink('foo');
$edit = array('info[0][value]' => $this->randomMachineName(8));
$edit = ['info[0][value]' => $this->randomMachineName(8)];
$this->drupalPostForm(NULL, $edit, t('Save'));
$blocks = $storage->loadByProperties(array('info' => $edit['info[0][value]']));
$blocks = $storage->loadByProperties(['info' => $edit['info[0][value]']]);
if (!empty($blocks)) {
$this->assertUrl(\Drupal::url('entity.block_content.collection', array(), array('absolute' => TRUE)));
$this->assertUrl(\Drupal::url('entity.block_content.collection', [], ['absolute' => TRUE]));
}
else {
$this->fail('Could not load created block.');
@@ -0,0 +1,46 @@
<?php
namespace Drupal\block_content\Tests;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\system\Tests\Update\UpdatePathTestBase;
/**
* Tests update functions for the Block Content module.
*
* @group Update
*/
class BlockContentUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
];
}
/**
* Tests the revision metadata fields and revision data table additions.
*/
public function testSimpleUpdates() {
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$entity_type = $entity_definition_update_manager->getEntityType('block_content');
$this->assertNull($entity_type->getRevisionDataTable());
$this->runUpdates();
$post_revision_created = $entity_definition_update_manager->getFieldStorageDefinition('revision_created', 'block_content');
$post_revision_user = $entity_definition_update_manager->getFieldStorageDefinition('revision_user', 'block_content');
$this->assertTrue($post_revision_created instanceof BaseFieldDefinition, "Revision created field found");
$this->assertTrue($post_revision_user instanceof BaseFieldDefinition, "Revision user field found");
$this->assertEqual('created', $post_revision_created->getType(), "Field is type created");
$this->assertEqual('entity_reference', $post_revision_user->getType(), "Field is type entity_reference");
$entity_type = $entity_definition_update_manager->getEntityType('block_content');
$this->assertEqual('block_content_field_revision', $entity_type->getRevisionDataTable());
}
}
@@ -2,6 +2,8 @@
namespace Drupal\block_content\Tests\Views;
@trigger_error('\Drupal\block_content\Tests\Views\BlockContentTestBase is deprecated in 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\block_content\Functional\Views\BlockContentTestBase.', E_USER_DEPRECATED);
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Utility\SafeMarkup;
@@ -10,6 +12,9 @@ use Drupal\views\Tests\ViewTestData;
/**
* Base class for all block_content tests.
*
* @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
* Use \Drupal\Tests\block_content\Functional\Views\BlockContentTestBase.
*/
abstract class BlockContentTestBase extends ViewTestBase {
@@ -25,26 +30,26 @@ abstract class BlockContentTestBase extends ViewTestBase {
*
* @var array
*/
protected $permissions = array(
protected $permissions = [
'administer blocks',
);
];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('block', 'block_content', 'block_content_test_views');
public static $modules = ['block', 'block_content', 'block_content_test_views'];
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
// Ensure the basic bundle exists. This is provided by the standard profile.
$this->createBlockContentType(array('id' => 'basic'));
$this->createBlockContentType(['id' => 'basic']);
$this->adminUser = $this->drupalCreateUser($this->permissions);
if ($import_test_views) {
ViewTestData::createTestViews(get_class($this), array('block_content_test_views'));
ViewTestData::createTestViews(get_class($this), ['block_content_test_views']);
}
}
@@ -58,17 +63,17 @@ abstract class BlockContentTestBase extends ViewTestBase {
* @return \Drupal\block_content\Entity\BlockContent
* Created custom block.
*/
protected function createBlockContent(array $settings = array()) {
protected function createBlockContent(array $settings = []) {
$status = 0;
$settings += array(
$settings += [
'info' => $this->randomMachineName(),
'type' => 'basic',
'langcode' => 'en',
);
];
if ($block_content = BlockContent::create($settings)) {
$status = $block_content->save();
}
$this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content %info.', array('%info' => $block_content->label())));
$this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content %info.', ['%info' => $block_content->label()]));
return $block_content;
}
@@ -81,7 +86,7 @@ abstract class BlockContentTestBase extends ViewTestBase {
* @return \Drupal\block_content\Entity\BlockContentType
* Created custom block type.
*/
protected function createBlockContentType(array $values = array()) {
protected function createBlockContentType(array $values = []) {
// Find a non-existent random type name.
if (!isset($values['id'])) {
do {
@@ -91,16 +96,16 @@ abstract class BlockContentTestBase extends ViewTestBase {
else {
$id = $values['id'];
}
$values += array(
$values += [
'id' => $id,
'label' => $id,
'revision' => FALSE
);
];
$bundle = BlockContentType::create($values);
$status = $bundle->save();
block_content_add_body_field($bundle->id());
$this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content type %bundle.', array('%bundle' => $bundle->id())));
$this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content type %bundle.', ['%bundle' => $bundle->id()]));
return $bundle;
}
@@ -7,8 +7,8 @@ package: Testing
dependencies:
- block_content
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233791
datestamp: 1502903957
@@ -15,9 +15,9 @@ use Drupal\block_content\Entity\BlockContent;
*/
function block_content_test_block_content_view(array &$build, BlockContent $block_content, $view_mode) {
// Add extra content.
$build['extra_content'] = array(
$build['extra_content'] = [
'#markup' => '<blink>Yowser</blink>',
);
];
}
/**
@@ -8,8 +8,8 @@ dependencies:
- block_content
- views
# Information added by Drupal.org packaging script on 2016-08-03
version: '8.1.8'
# Information added by Drupal.org packaging script on 2017-08-16
version: '8.3.7'
core: '8.x'
project: 'drupal'
datestamp: 1470233791
datestamp: 1502903957
@@ -0,0 +1,234 @@
langcode: en
status: true
dependencies:
module:
- block_content
id: test_block_content_redirect_destination
label: 'Redirect destination'
module: views
description: ''
tag: ''
base_table: block_content_field_data
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: mini
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ‹‹
next: ››
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: false
caption: ''
summary: ''
description: ''
columns:
info: info
info:
info:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: false
row:
type: 'entity:block_content'
fields:
info:
table: block_content_field_data
field: info
id: info
entity_type: null
entity_field: info
plugin_id: field
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: string
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
operations:
id: operations
table: block_content
field: operations
relationship: none
group_type: group
admin_label: ''
label: 'Operations links'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
destination: true
entity_type: block_content
plugin_id: entity_operations
filters: { }
sorts: { }
title: 'Redirect destination'
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
tags: { }
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: /admin/content/redirect_destination
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
tags: { }
@@ -0,0 +1,105 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\system\Tests\Entity\EntityCacheTagsTestBase;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests the Custom Block entity's cache tags.
*
* @group block_content
*/
class BlockContentCacheTagsTest extends EntityCacheTagsTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block_content'];
/**
* {@inheritdoc}
*/
protected function createEntity() {
$block_content_type = BlockContentType::create([
'id' => 'basic',
'label' => 'basic',
'revision' => FALSE
]);
$block_content_type->save();
block_content_add_body_field($block_content_type->id());
// Create a "Llama" custom block.
$block_content = BlockContent::create([
'info' => 'Llama',
'type' => 'basic',
'body' => [
'value' => 'The name "llama" was adopted by European settlers from native Peruvians.',
'format' => 'plain_text',
],
]);
$block_content->save();
return $block_content;
}
/**
* {@inheritdoc}
*
* @see \Drupal\block_content\BlockContentAccessControlHandler::checkAccess()
*/
protected function getAccessCacheContextsForEntity(EntityInterface $entity) {
return [];
}
/**
* {@inheritdoc}
*
* Each comment must have a comment body, which always has a text format.
*/
protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) {
return ['config:filter.format.plain_text'];
}
/**
* Tests that the block is cached with the correct contexts and tags.
*/
public function testBlock() {
$block = $this->drupalPlaceBlock('block_content:' . $this->entity->uuid());
$build = $this->container->get('entity.manager')->getViewBuilder('block')->view($block, 'block');
// Render the block.
// @todo The request stack manipulation won't be necessary once
// https://www.drupal.org/node/2367555 is fixed and the
// corresponding $request->isMethodSafe() checks are removed from
// Drupal\Core\Render\Renderer.
$request_stack = $this->container->get('request_stack');
$request_stack->push(new Request());
$this->container->get('renderer')->renderRoot($build);
$request_stack->pop();
// Expected keys, contexts, and tags for the block.
// @see \Drupal\block\BlockViewBuilder::viewMultiple()
$expected_block_cache_keys = ['entity_view', 'block', $block->id()];
$expected_block_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
$expected_block_cache_tags = Cache::mergeTags(['block_view', 'rendered'], $block->getCacheTags());
$expected_block_cache_tags = Cache::mergeTags($expected_block_cache_tags, $block->getPlugin()->getCacheTags());
// Expected contexts and tags for the BlockContent entity.
// @see \Drupal\Core\Entity\EntityViewBuilder::getBuildDefaults().
$expected_entity_cache_contexts = ['theme'];
$expected_entity_cache_tags = Cache::mergeTags(['block_content_view'], $this->entity->getCacheTags());
$expected_entity_cache_tags = Cache::mergeTags($expected_entity_cache_tags, $this->getAdditionalCacheTagsForEntity($this->entity));
// Verify that what was render cached matches the above expectations.
$cid = $this->createCacheId($expected_block_cache_keys, $expected_block_cache_contexts);
$redirected_cid = $this->createCacheId($expected_block_cache_keys, Cache::mergeContexts($expected_block_cache_contexts, $expected_entity_cache_contexts));
$this->verifyRenderCache($cid, Cache::mergeTags($expected_block_cache_tags, $expected_entity_cache_tags), ($cid !== $redirected_cid) ? $redirected_cid : NULL);
}
}
@@ -0,0 +1,303 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Database\Database;
/**
* Create a block and test saving it.
*
* @group block_content
*/
class BlockContentCreationTest extends BlockContentTestBase {
/**
* Modules to enable.
*
* Enable dummy module that implements hook_block_insert() for exceptions and
* field_ui to edit display settings.
*
* @var array
*/
public static $modules = ['block_content_test', 'dblog', 'field_ui'];
/**
* Permissions to grant admin user.
*
* @var array
*/
protected $permissions = [
'administer blocks',
'administer block_content display'
];
/**
* Sets the test up.
*/
protected function setUp() {
parent::setUp();
$this->drupalLogin($this->adminUser);
}
/**
* Creates a "Basic page" block and verifies its consistency in the database.
*/
public function testBlockContentCreation() {
$this->drupalLogin($this->adminUser);
// Create a block.
$edit = [];
$edit['info[0][value]'] = 'Test Block';
$edit['body[0][value]'] = $this->randomMachineName(16);
$this->drupalPostForm('block/add/basic', $edit, t('Save'));
// Check that the Basic block has been created.
$this->assertRaw(format_string('@block %name has been created.', [
'@block' => 'basic',
'%name' => $edit['info[0][value]']
]), 'Basic block created.');
// Check that the view mode setting is hidden because only one exists.
$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]']]);
$block = reset($blocks);
$this->assertTrue($block, 'Custom Block found in database.');
// Check that attempting to create another block with the same value for
// 'info' returns an error.
$this->drupalPostForm('block/add/basic', $edit, t('Save'));
// Check that the Basic block has been created.
$this->assertRaw(format_string('A custom block with block description %value already exists.', [
'%value' => $edit['info[0][value]']
]));
$this->assertResponse(200);
}
/**
* Creates a "Basic page" block with multiple view modes.
*/
public function testBlockContentCreationMultipleViewModes() {
// Add a new view mode and verify if it is selected as expected.
$this->drupalLogin($this->drupalCreateUser(['administer display modes']));
$this->drupalGet('admin/structure/display-modes/view/add/block_content');
$edit = [
'id' => 'test_view_mode',
'label' => 'Test View Mode',
];
$this->drupalPostForm(NULL, $edit, t('Save'));
$this->assertRaw(t('Saved the %label view mode.', ['%label' => $edit['label']]));
$this->drupalLogin($this->adminUser);
// Create a block.
$edit = [];
$edit['info[0][value]'] = 'Test Block';
$edit['body[0][value]'] = $this->randomMachineName(16);
$this->drupalPostForm('block/add/basic', $edit, t('Save'));
// Check that the Basic block has been created.
$this->assertRaw(format_string('@block %name has been created.', [
'@block' => 'basic',
'%name' => $edit['info[0][value]']
]), 'Basic block created.');
// Save our block permanently
$this->drupalPostForm(NULL, ['region' => 'content'], t('Save block'));
// Set test_view_mode as a custom display to be available on the list.
$this->drupalGet('admin/structure/block/block-content');
$this->drupalGet('admin/structure/block/block-content/types');
$this->clickLink(t('Manage display'));
$this->drupalGet('admin/structure/block/block-content/manage/basic/display');
$custom_view_mode = [
'display_modes_custom[test_view_mode]' => 1,
];
$this->drupalPostForm(NULL, $custom_view_mode, t('Save'));
// Go to the configure page and change the view mode.
$this->drupalGet('admin/structure/block/manage/testblock');
// Test the available view mode options.
$this->assertOption('edit-settings-view-mode', 'default', 'The default view mode is available.');
$this->assertOption('edit-settings-view-mode', 'test_view_mode', 'The test view mode is available.');
$view_mode['settings[view_mode]'] = 'test_view_mode';
$this->drupalPostForm(NULL, $view_mode, t('Save block'));
// Check that the view mode setting is shown because more than one exists.
$this->drupalGet('admin/structure/block/manage/testblock');
$this->assertFieldByXPath('//select[@name="settings[view_mode]"]', NULL, 'View mode setting shown because multiple exist');
// Change the view mode.
$view_mode['region'] = 'content';
$view_mode['settings[view_mode]'] = 'test_view_mode';
$this->drupalPostForm(NULL, $view_mode, t('Save block'));
// Go to the configure page and verify the view mode has changed.
$this->drupalGet('admin/structure/block/manage/testblock');
$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]']]);
$block = reset($blocks);
$this->assertTrue($block, 'Custom Block found in database.');
// Check that attempting to create another block with the same value for
// 'info' returns an error.
$this->drupalPostForm('block/add/basic', $edit, t('Save'));
// Check that the Basic block has been created.
$this->assertRaw(format_string('A custom block with block description %value already exists.', [
'%value' => $edit['info[0][value]']
]));
$this->assertResponse(200);
}
/**
* Create a default custom block.
*
* Creates a custom block from defaults and ensures that the 'basic block'
* type is being used.
*/
public function testDefaultBlockContentCreation() {
$edit = [];
$edit['info[0][value]'] = $this->randomMachineName(8);
$edit['body[0][value]'] = $this->randomMachineName(16);
// Don't pass the custom block type in the url so the default is forced.
$this->drupalPostForm('block/add', $edit, t('Save'));
// Check that the block has been created and that it is a basic block.
$this->assertRaw(format_string('@block %name has been created.', [
'@block' => 'basic',
'%name' => $edit['info[0][value]'],
]), 'Basic block created.');
// Check that the block exists in the database.
$blocks = entity_load_multiple_by_properties('block_content', ['info' => $edit['info[0][value]']]);
$block = reset($blocks);
$this->assertTrue($block, 'Default Custom Block found in database.');
}
/**
* Verifies that a transaction rolls back the failed creation.
*/
public function testFailedBlockCreation() {
// Create a block.
try {
$this->createBlockContent('fail_creation');
$this->fail('Expected exception has not been thrown.');
}
catch (\Exception $e) {
$this->pass('Expected exception has been thrown.');
}
if (Database::getConnection()->supportsTransactions()) {
// Check that the block does not exist in the database.
$id = db_select('block_content_field_data', 'b')
->fields('b', ['id'])
->condition('info', 'fail_creation')
->execute()
->fetchField();
$this->assertFalse($id, 'Transactions supported, and block not found in database.');
}
else {
// Check that the block exists in the database.
$id = db_select('block_content_field_data', 'b')
->fields('b', ['id'])
->condition('info', 'fail_creation')
->execute()
->fetchField();
$this->assertTrue($id, 'Transactions not supported, and block found in database.');
// Check that the failed rollback was logged.
$records = db_query("SELECT wid FROM {watchdog} WHERE message LIKE 'Explicit rollback failed%'")->fetchAll();
$this->assertTrue(count($records) > 0, 'Transactions not supported, and rollback error logged to watchdog.');
}
}
/**
* Test deleting a block.
*/
public function testBlockDelete() {
// Create a block.
$edit = [];
$edit['info[0][value]'] = $this->randomMachineName(8);
$body = $this->randomMachineName(16);
$edit['body[0][value]'] = $body;
$this->drupalPostForm('block/add/basic', $edit, t('Save'));
// Place the block.
$instance = [
'id' => Unicode::strtolower($edit['info[0][value]']),
'settings[label]' => $edit['info[0][value]'],
'region' => 'sidebar_first',
];
$block = BlockContent::load(1);
$url = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . $this->config('system.theme')->get('default');
$this->drupalPostForm($url, $instance, t('Save block'));
$block = BlockContent::load(1);
// Test getInstances method.
$this->assertEqual(1, count($block->getInstances()));
// Navigate to home page.
$this->drupalGet('');
$this->assertText($body);
// Delete the block.
$this->drupalGet('block/1/delete');
$this->assertText(\Drupal::translation()->formatPlural(1, 'This will also remove 1 placed block instance.', 'This will also remove @count placed block instance.'));
$this->drupalPostForm(NULL, [], 'Delete');
$this->assertRaw(t('The custom block %name has been deleted.', ['%name' => $edit['info[0][value]']]));
// Create another block and force the plugin cache to flush.
$edit2 = [];
$edit2['info[0][value]'] = $this->randomMachineName(8);
$body2 = $this->randomMachineName(16);
$edit2['body[0][value]'] = $body2;
$this->drupalPostForm('block/add/basic', $edit2, t('Save'));
$this->assertNoRaw('Error message');
// Create another block with no instances, and test we don't get a
// confirmation message about deleting instances.
$edit3 = [];
$edit3['info[0][value]'] = $this->randomMachineName(8);
$body = $this->randomMachineName(16);
$edit3['body[0][value]'] = $body;
$this->drupalPostForm('block/add/basic', $edit3, t('Save'));
// Show the delete confirm form.
$this->drupalGet('block/3/delete');
$this->assertNoText('This will also remove');
}
/**
* Test that placed content blocks create a dependency in the block placement.
*/
public function testConfigDependencies() {
$block = $this->createBlockContent();
// Place the block.
$block_placement_id = Unicode::strtolower($block->label());
$instance = [
'id' => $block_placement_id,
'settings[label]' => $block->label(),
'region' => 'sidebar_first',
];
$block = BlockContent::load(1);
$url = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . $this->config('system.theme')->get('default');
$this->drupalPostForm($url, $instance, t('Save block'));
$dependencies = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('content', [$block->getConfigDependencyName()]);
$block_placement = reset($dependencies);
$this->assertEqual($block_placement_id, $block_placement->id(), "The block placement config entity has a dependency on the block content entity.");
}
}
@@ -0,0 +1,109 @@
<?php
namespace Drupal\Tests\block_content\Functional;
/**
* Tests the listing of custom blocks.
*
* Tests the fallback block content list when Views is disabled.
*
* @group block_content
* @see \Drupal\block\BlockContentListBuilder
* @see \Drupal\block_content\Tests\BlockContentListViewsTest
*/
class BlockContentListTest extends BlockContentTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block', 'block_content', 'config_translation'];
/**
* Tests the custom block listing page.
*/
public function testListing() {
$this->drupalLogin($this->drupalCreateUser(['administer blocks', 'translate configuration']));
$this->drupalGet('admin/structure/block/block-content');
// Test for the page title.
$this->assertTitle(t('Custom block library') . ' | Drupal');
// Test for the table.
$element = $this->xpath('//div[@class="layout-content"]//table');
$this->assertTrue($element, 'Configuration entity list table found.');
// Test the table header.
$elements = $this->xpath('//div[@class="layout-content"]//table/thead/tr/th');
$this->assertEqual(count($elements), 2, 'Correct number of table header cells found.');
// Test the contents of each th cell.
$expected_items = [t('Block description'), t('Operations')];
foreach ($elements as $key => $element) {
$this->assertEqual($element->getText(), $expected_items[$key]);
}
$label = 'Antelope';
$new_label = 'Albatross';
// Add a new entity using the operations link.
$link_text = t('Add custom block');
$this->assertLink($link_text);
$this->clickLink($link_text);
$this->assertResponse(200);
$edit = [];
$edit['info[0][value]'] = $label;
$edit['body[0][value]'] = $this->randomMachineName(16);
$this->drupalPostForm(NULL, $edit, t('Save'));
// Confirm that once the user returns to the listing, the text of the label
// (versus elsewhere on the page).
$this->assertFieldByXpath('//td', $label, 'Label found for added block.');
// Check the number of table row cells.
$elements = $this->xpath('//div[@class="layout-content"]//table/tbody/tr[@class="odd"]/td');
$this->assertEqual(count($elements), 2, 'Correct number of table row cells found.');
// Check the contents of each row cell. The first cell contains the label,
// the second contains the machine name, and the third contains the
// operations list.
$this->assertIdentical($elements[0]->getText(), $label);
// Edit the entity using the operations link.
$blocks = $this->container
->get('entity.manager')
->getStorage('block_content')
->loadByProperties(['info' => $label]);
$block = reset($blocks);
if (!empty($block)) {
$this->assertLinkByHref('block/' . $block->id());
$this->clickLink(t('Edit'));
$this->assertResponse(200);
$this->assertTitle(strip_tags(t('Edit custom block %label', ['%label' => $label]) . ' | Drupal'));
$edit = ['info[0][value]' => $new_label];
$this->drupalPostForm(NULL, $edit, t('Save'));
}
else {
$this->fail('Did not find Albatross block in the database.');
}
// Confirm that once the user returns to the listing, the text of the label
// (versus elsewhere on the page).
$this->assertFieldByXpath('//td', $new_label, 'Label found for updated custom block.');
// Delete the added entity using the operations link.
$this->assertLinkByHref('block/' . $block->id() . '/delete');
$delete_text = t('Delete');
$this->clickLink($delete_text);
$this->assertResponse(200);
$this->assertTitle(strip_tags(t('Are you sure you want to delete the custom block %label?', ['%label' => $new_label]) . ' | Drupal'));
$this->drupalPostForm(NULL, [], $delete_text);
// Verify that the text of the label and machine name does not appear in
// the list (though it may appear elsewhere on the page).
$this->assertNoFieldByXpath('//td', $new_label, 'No label found for deleted custom block.');
// Confirm that the empty text is displayed.
$this->assertText(t('There is no Custom block yet.'));
}
}
@@ -0,0 +1,117 @@
<?php
namespace Drupal\Tests\block_content\Functional;
/**
* Tests the Views-powered listing of custom blocks.
*
* @group block_content
* @see \Drupal\block\BlockContentListBuilder
* @see \Drupal\block_content\Tests\BlockContentListTest
*/
class BlockContentListViewsTest extends BlockContentTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block', 'block_content', 'config_translation', 'views'];
/**
* Tests the custom block listing page.
*/
public function testListing() {
$this->drupalLogin($this->drupalCreateUser(['administer blocks', 'translate configuration']));
$this->drupalGet('admin/structure/block/block-content');
// Test for the page title.
$this->assertTitle(t('Custom block library') . ' | Drupal');
// Test for the exposed filters.
$this->assertFieldByName('info');
$this->assertFieldByName('type');
// Test for the table.
$element = $this->xpath('//div[@class="layout-content"]//table');
$this->assertTrue($element, 'Views table found.');
// Test the table header.
$elements = $this->xpath('//div[@class="layout-content"]//table/thead/tr/th');
$this->assertEqual(count($elements), 4, 'Correct number of table header cells found.');
// Test the contents of each th cell.
$expected_items = ['Block description', 'Block type', 'Updated Sort ascending', 'Operations'];
foreach ($elements as $key => $element) {
if ($element->find('xpath', 'a')) {
$this->assertIdentical(trim($element->find('xpath', 'a')->getText()), $expected_items[$key]);
}
else {
$this->assertIdentical(trim($element->getText()), $expected_items[$key]);
}
}
$label = 'Antelope';
$new_label = 'Albatross';
// Add a new entity using the operations link.
$link_text = t('Add custom block');
$this->assertLink($link_text);
$this->clickLink($link_text);
$this->assertResponse(200);
$edit = [];
$edit['info[0][value]'] = $label;
$edit['body[0][value]'] = $this->randomMachineName(16);
$this->drupalPostForm(NULL, $edit, t('Save'));
// Confirm that once the user returns to the listing, the text of the label
// (versus elsewhere on the page).
$this->assertFieldByXpath('//td/a', $label, 'Label found for added block.');
// Check the number of table row cells.
$elements = $this->xpath('//div[@class="layout-content"]//table/tbody/tr/td');
$this->assertEqual(count($elements), 4, 'Correct number of table row cells found.');
// Check the contents of each row cell. The first cell contains the label,
// the second contains the machine name, and the third contains the
// operations list.
$this->assertIdentical($elements[0]->find('xpath', 'a')->getText(), $label);
// Edit the entity using the operations link.
$blocks = $this->container
->get('entity.manager')
->getStorage('block_content')
->loadByProperties(['info' => $label]);
$block = reset($blocks);
if (!empty($block)) {
$this->assertLinkByHref('block/' . $block->id());
$this->clickLink(t('Edit'));
$this->assertResponse(200);
$this->assertTitle(strip_tags(t('Edit custom block %label', ['%label' => $label]) . ' | Drupal'));
$edit = ['info[0][value]' => $new_label];
$this->drupalPostForm(NULL, $edit, t('Save'));
}
else {
$this->fail('Did not find Albatross block in the database.');
}
// Confirm that once the user returns to the listing, the text of the label
// (versus elsewhere on the page).
$this->assertFieldByXpath('//td/a', $new_label, 'Label found for updated custom block.');
// Delete the added entity using the operations link.
$this->assertLinkByHref('block/' . $block->id() . '/delete');
$delete_text = t('Delete');
$this->clickLink($delete_text);
$this->assertResponse(200);
$this->assertTitle(strip_tags(t('Are you sure you want to delete the custom block %label?', ['%label' => $new_label]) . ' | Drupal'));
$this->drupalPostForm(NULL, [], $delete_text);
// Verify that the text of the label and machine name does not appear in
// the list (though it may appear elsewhere on the page).
$this->assertNoFieldByXpath('//td', $new_label, 'No label found for deleted custom block.');
// Confirm that the empty text is displayed.
$this->assertText('There are no custom blocks available.');
$this->assertLink('custom block');
}
}
@@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\block_content\Functional;
/**
* Create a block and test block access by attempting to view the block.
*
* @group block_content
*/
class BlockContentPageViewTest extends BlockContentTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block_content_test'];
/**
* Checks block edit and fallback functionality.
*/
public function testPageEdit() {
$this->drupalLogin($this->adminUser);
$block = $this->createBlockContent();
// Attempt to view the block.
$this->drupalGet('block-content/' . $block->id());
// Assert response was '200' and not '403 Access denied'.
$this->assertResponse('200', 'User was able the view the block');
$this->drupalGet('<front>');
$this->assertRaw(t('This block is broken or missing. You may be missing content or you might need to enable the original module.'));
}
}
@@ -0,0 +1,107 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
/**
* Create a block with revisions.
*
* @group block_content
*/
class BlockContentRevisionsTest extends BlockContentTestBase {
/**
* Stores blocks created during the test.
* @var array
*/
protected $blocks;
/**
* Stores log messages used during the test.
* @var array
*/
protected $revisionLogs;
/**
* Sets the test up.
*/
protected function setUp() {
parent::setUp();
/** @var UserInterface $user */
$user = User::load(1);
// Create initial block.
$block = $this->createBlockContent('initial');
$blocks = [];
$logs = [];
// Get original block.
$blocks[] = $block->getRevisionId();
$logs[] = '';
// Create three revisions.
$revision_count = 3;
for ($i = 0; $i < $revision_count; $i++) {
$block->setNewRevision(TRUE);
$block->setRevisionLogMessage($this->randomMachineName(32));
$block->setRevisionUser($this->adminUser);
$block->setRevisionCreationTime(REQUEST_TIME);
$logs[] = $block->getRevisionLogMessage();
$block->save();
$blocks[] = $block->getRevisionId();
}
$this->blocks = $blocks;
$this->revisionLogs = $logs;
}
/**
* Checks block revision related operations.
*/
public function testRevisions() {
$blocks = $this->blocks;
$logs = $this->revisionLogs;
foreach ($blocks as $delta => $revision_id) {
// Confirm the correct revision text appears.
/** @var \Drupal\block_content\BlockContentInterface $loaded */
$loaded = $this->container->get('entity_type.manager')
->getStorage('block_content')
->loadRevision($revision_id);
// Verify revision log is the same.
$this->assertEqual($loaded->getRevisionLogMessage(), $logs[$delta], format_string('Correct log message found for revision @revision', [
'@revision' => $loaded->getRevisionId(),
]));
if ($delta > 0) {
$this->assertTrue($loaded->getRevisionUser() instanceof UserInterface, 'Revision User found.');
$this->assertTrue(is_numeric($loaded->getRevisionUserId()), 'Revision User ID found.');
$this->assertTrue(is_numeric($loaded->getRevisionCreationTime()), 'Revision time found.');
}
}
// Confirm that this is the default revision.
$this->assertTrue($loaded->isDefaultRevision(), 'Third block revision is the default one.');
// Make a new revision and set it to not be default.
// This will create a new revision that is not "front facing".
// Save this as a non-default revision.
$loaded->setNewRevision();
$loaded->isDefaultRevision(FALSE);
$loaded->body = $this->randomMachineName(8);
$loaded->save();
$this->drupalGet('block/' . $loaded->id());
$this->assertNoText($loaded->body->value, 'Revision body text is not present on default version of block.');
// Verify that the non-default revision id is greater than the default
// revision id.
$default_revision = BlockContent::load($loaded->id());
$this->assertTrue($loaded->getRevisionId() > $default_revision->getRevisionId(), 'Revision id is greater than default revision id.');
}
}
@@ -0,0 +1,102 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
/**
* Tests $block_content->save() for saving content.
*
* @group block_content
*/
class BlockContentSaveTest extends BlockContentTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block_content_test'];
/**
* Sets the test up.
*/
protected function setUp() {
parent::setUp();
$this->drupalLogin($this->adminUser);
}
/**
* Checks whether custom block IDs are saved properly during an import.
*/
public function testImport() {
// Custom block ID must be a number that is not in the database.
$max_id = db_query('SELECT MAX(id) FROM {block_content}')->fetchField();
$test_id = $max_id + mt_rand(1000, 1000000);
$info = $this->randomMachineName(8);
$block_array = [
'info' => $info,
'body' => ['value' => $this->randomMachineName(32)],
'type' => 'basic',
'id' => $test_id
];
$block = BlockContent::create($block_array);
$block->enforceIsNew(TRUE);
$block->save();
// Verify that block_submit did not wipe the provided id.
$this->assertEqual($block->id(), $test_id, 'Block imported using provide id');
// Test the import saved.
$block_by_id = BlockContent::load($test_id);
$this->assertTrue($block_by_id, 'Custom block load by block ID.');
$this->assertIdentical($block_by_id->body->value, $block_array['body']['value']);
}
/**
* Tests determining changes in hook_block_presave().
*
* Verifies the static block load cache is cleared upon save.
*/
public function testDeterminingChanges() {
// Initial creation.
$block = $this->createBlockContent('test_changes');
$this->assertEqual($block->getChangedTime(), REQUEST_TIME, 'Creating a block sets default "changed" timestamp.');
// Update the block without applying changes.
$block->save();
$this->assertEqual($block->label(), 'test_changes', 'No changes have been determined.');
// Apply changes.
$block->setInfo('updated');
$block->save();
// The hook implementations block_content_test_block_content_presave() and
// block_content_test_block_content_update() determine changes and change
// the title as well as programmatically set the 'changed' timestamp.
$this->assertEqual($block->label(), 'updated_presave_update', 'Changes have been determined.');
$this->assertEqual($block->getChangedTime(), 979534800, 'Saving a custom block uses "changed" timestamp set in presave hook.');
// Test the static block load cache to be cleared.
$block = BlockContent::load($block->id());
$this->assertEqual($block->label(), 'updated_presave', 'Static cache has been cleared.');
}
/**
* Tests saving a block on block insert.
*
* This test ensures that a block has been fully saved when
* hook_block_content_insert() is invoked, so that the block can be saved again
* in a hook implementation without errors.
*
* @see block_test_block_insert()
*/
public function testBlockContentSaveOnInsert() {
// block_content_test_block_content_insert() triggers a save on insert if the
// title equals 'new'.
$block = $this->createBlockContent('new');
$this->assertEqual($block->label(), 'BlockContent ' . $block->id(), 'Custom block saved on block insert.');
}
}
@@ -0,0 +1,113 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Tests\BrowserTestBase;
/**
* Sets up block content types.
*/
abstract class BlockContentTestBase extends BrowserTestBase {
/**
* Profile to use.
*/
protected $profile = 'testing';
/**
* Admin user
*
* @var \Drupal\user\UserInterface
*/
protected $adminUser;
/**
* Permissions to grant admin user.
*
* @var array
*/
protected $permissions = [
'administer blocks'
];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block', 'block_content'];
/**
* Whether or not to auto-create the basic block type during setup.
*
* @var bool
*/
protected $autoCreateBasicBlockType = TRUE;
/**
* Sets the test up.
*/
protected function setUp() {
parent::setUp();
if ($this->autoCreateBasicBlockType) {
$this->createBlockContentType('basic', TRUE);
}
$this->adminUser = $this->drupalCreateUser($this->permissions);
$this->drupalPlaceBlock('local_actions_block');
}
/**
* Creates a custom block.
*
* @param bool|string $title
* (optional) Title of block. When no value is given uses a random name.
* Defaults to FALSE.
* @param string $bundle
* (optional) Bundle name. Defaults to 'basic'.
* @param bool $save
* (optional) Whether to save the block. Defaults to TRUE.
*
* @return \Drupal\block_content\Entity\BlockContent
* Created custom block.
*/
protected function createBlockContent($title = FALSE, $bundle = 'basic', $save = TRUE) {
$title = $title ?: $this->randomMachineName();
$block_content = BlockContent::create([
'info' => $title,
'type' => $bundle,
'langcode' => 'en'
]);
if ($block_content && $save === TRUE) {
$block_content->save();
}
return $block_content;
}
/**
* Creates a custom block type (bundle).
*
* @param string $label
* The block type label.
* @param bool $create_body
* Whether or not to create the body field
*
* @return \Drupal\block_content\Entity\BlockContentType
* Created custom block type.
*/
protected function createBlockContentType($label, $create_body = FALSE) {
$bundle = BlockContentType::create([
'id' => $label,
'label' => $label,
'revision' => FALSE,
]);
$bundle->save();
if ($create_body) {
block_content_add_body_field($bundle->id());
}
return $bundle;
}
}
@@ -0,0 +1,205 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Utility\Unicode;
use Drupal\content_translation\Tests\ContentTranslationUITestBase;
/**
* Tests the block content translation UI.
*
* @group block_content
*/
class BlockContentTranslationUITest extends ContentTranslationUITestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'language',
'content_translation',
'block',
'field_ui',
'block_content'
];
/**
* {@inheritdoc}
*/
protected $defaultCacheContexts = [
'languages:language_interface',
'session',
'theme',
'url.path',
'url.query_args',
'user.permissions',
'user.roles:authenticated',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->entityTypeId = 'block_content';
$this->bundle = 'basic';
$this->testLanguageSelector = FALSE;
parent::setUp();
$this->drupalPlaceBlock('page_title_block');
}
/**
* {@inheritdoc}
*/
protected function setupBundle() {
// Create the basic bundle since it is provided by standard.
$bundle = BlockContentType::create([
'id' => $this->bundle,
'label' => $this->bundle,
'revision' => FALSE
]);
$bundle->save();
}
/**
* {@inheritdoc}
*/
public function getTranslatorPermissions() {
return array_merge(parent::getTranslatorPermissions(), [
'translate any entity',
'access administration pages',
'administer blocks',
'administer block_content fields'
]);
}
/**
* Creates a custom block.
*
* @param bool|string $title
* (optional) Title of block. When no value is given uses a random name.
* Defaults to FALSE.
* @param bool|string $bundle
* (optional) Bundle name. When no value is given, defaults to
* $this->bundle. Defaults to FALSE.
*
* @return \Drupal\block_content\Entity\BlockContent
* Created custom block.
*/
protected function createBlockContent($title = FALSE, $bundle = FALSE) {
$title = $title ?: $this->randomMachineName();
$bundle = $bundle ?: $this->bundle;
$block_content = BlockContent::create([
'info' => $title,
'type' => $bundle,
'langcode' => 'en'
]);
$block_content->save();
return $block_content;
}
/**
* {@inheritdoc}
*/
protected function getNewEntityValues($langcode) {
return ['info' => Unicode::strtolower($this->randomMachineName())] + parent::getNewEntityValues($langcode);
}
/**
* Returns an edit array containing the values to be posted.
*/
protected function getEditValues($values, $langcode, $new = FALSE) {
$edit = parent::getEditValues($values, $langcode, $new);
foreach ($edit as $property => $value) {
if ($property == 'info') {
$edit['info[0][value]'] = $value;
unset($edit[$property]);
}
}
return $edit;
}
/**
* {@inheritdoc}
*/
protected function doTestBasicTranslation() {
parent::doTestBasicTranslation();
// Ensure that a block translation can be created using the same description
// as in the original language.
$default_langcode = $this->langcodes[0];
$values = $this->getNewEntityValues($default_langcode);
$storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $storage->create(['type' => 'basic'] + $values);
$entity->save();
$entity->addTranslation('it', $values);
try {
$message = 'Blocks can have translations with the same "info" value.';
$entity->save();
$this->pass($message);
}
catch (\Exception $e) {
$this->fail($message);
}
// Check that the translate operation link is shown.
$this->drupalGet('admin/structure/block/block-content');
$this->assertLinkByHref('block/' . $entity->id() . '/translations');
}
/**
* Test that no metadata is stored for a disabled bundle.
*/
public function testDisabledBundle() {
// Create a bundle that does not have translation enabled.
$disabled_bundle = $this->randomMachineName();
$bundle = BlockContentType::create([
'id' => $disabled_bundle,
'label' => $disabled_bundle,
'revision' => FALSE
]);
$bundle->save();
// Create a block content for each bundle.
$enabled_block_content = $this->createBlockContent();
$disabled_block_content = $this->createBlockContent(FALSE, $bundle->id());
// Make sure that only a single row was inserted into the block table.
$rows = db_query('SELECT * FROM {block_content_field_data} WHERE id = :id', [':id' => $enabled_block_content->id()])->fetchAll();
$this->assertEqual(1, count($rows));
}
/**
* {@inheritdoc}
*/
protected function doTestTranslationEdit() {
$storage = $this->container->get('entity_type.manager')
->getStorage($this->entityTypeId);
$storage->resetCache([$this->entityId]);
$entity = $storage->load($this->entityId);
$languages = $this->container->get('language_manager')->getLanguages();
foreach ($this->langcodes as $langcode) {
// We only want to test the title for non-english translations.
if ($langcode != 'en') {
$options = ['language' => $languages[$langcode]];
$url = $entity->urlInfo('edit-form', $options);
$this->drupalGet($url);
$title = t('<em>Edit @type</em> @title [%language translation]', [
'@type' => $entity->bundle(),
'@title' => $entity->getTranslation($langcode)->label(),
'%language' => $languages[$langcode]->getName(),
]);
$this->assertRaw($title);
}
}
}
}
@@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\block_content\Functional;
/**
* Tests block content validation constraints.
*
* @group block_content
*/
class BlockContentValidationTest extends BlockContentTestBase {
/**
* Tests the block content validation constraints.
*/
public function testValidation() {
// Add a block.
$description = $this->randomMachineName();
$block = $this->createBlockContent($description, 'basic');
// Validate the block.
$violations = $block->validate();
// Make sure we have no violations.
$this->assertEqual(count($violations), 0);
// Save the block.
$block->save();
// Add another block with the same description.
$block = $this->createBlockContent($description, 'basic');
// Validate this block.
$violations = $block->validate();
// Make sure we have 1 violation.
$this->assertEqual(count($violations), 1);
// Make sure the violation is on the info property
$this->assertEqual($violations[0]->getPropertyPath(), 'info');
// Make sure the message is correct.
$this->assertEqual($violations[0]->getMessage(), format_string('A custom block with block description %value already exists.', [
'%value' => $block->label(),
]));
}
}
@@ -0,0 +1,71 @@
<?php
namespace Drupal\Tests\block_content\Functional;
use Drupal\block_content\Entity\BlockContent;
use Drupal\Component\Utility\Unicode;
/**
* Create a block and test block edit functionality.
*
* @group block_content
*/
class PageEditTest extends BlockContentTestBase {
protected function setUp() {
parent::setUp();
$this->drupalPlaceBlock('page_title_block');
}
/**
* Checks block edit functionality.
*/
public function testPageEdit() {
$this->drupalLogin($this->adminUser);
$title_key = 'info[0][value]';
$body_key = 'body[0][value]';
// Create block to edit.
$edit = [];
$edit['info[0][value]'] = Unicode::strtolower($this->randomMachineName(8));
$edit[$body_key] = $this->randomMachineName(16);
$this->drupalPostForm('block/add/basic', $edit, t('Save'));
// Check that the block exists in the database.
$blocks = \Drupal::entityQuery('block_content')->condition('info', $edit['info[0][value]'])->execute();
$block = BlockContent::load(reset($blocks));
$this->assertTrue($block, 'Custom block found in database.');
// Load the edit page.
$this->drupalGet('block/' . $block->id());
$this->assertFieldByName($title_key, $edit[$title_key], 'Title field displayed.');
$this->assertFieldByName($body_key, $edit[$body_key], 'Body field displayed.');
// Edit the content of the block.
$edit = [];
$edit[$title_key] = $this->randomMachineName(8);
$edit[$body_key] = $this->randomMachineName(16);
// Stay on the current page, without reloading.
$this->drupalPostForm(NULL, $edit, t('Save'));
// Edit the same block, creating a new revision.
$this->drupalGet("block/" . $block->id());
$edit = [];
$edit['info[0][value]'] = $this->randomMachineName(8);
$edit[$body_key] = $this->randomMachineName(16);
$edit['revision'] = TRUE;
$this->drupalPostForm(NULL, $edit, t('Save'));
// Ensure that the block revision has been created.
\Drupal::entityManager()->getStorage('block_content')->resetCache([$block->id()]);
$revised_block = BlockContent::load($block->id());
$this->assertNotIdentical($block->getRevisionId(), $revised_block->getRevisionId(), 'A new revision has been created.');
// Test deleting the block.
$this->drupalGet("block/" . $revised_block->id());
$this->clickLink(t('Delete'));
$this->assertText(format_string('Are you sure you want to delete the custom block @label?', ['@label' => $revised_block->label()]));
}
}
@@ -0,0 +1,109 @@
<?php
namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\language\Entity\ConfigurableLanguage;
/**
* Tests block_content field filters with translations.
*
* @group block_content
*/
class BlockContentFieldFilterTest extends BlockContentTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['language'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_field_filters'];
/**
* List of block_content infos by language.
*
* @var array
*/
public $blockContentInfos = [];
/**
* {@inheritdoc}
*/
public function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
// Add two new languages.
ConfigurableLanguage::createFromLangcode('fr')->save();
ConfigurableLanguage::createFromLangcode('es')->save();
// Make the body field translatable. The info is already translatable by
// definition.
$field_storage = FieldStorageConfig::loadByName('block_content', 'body');
$field_storage->setTranslatable(TRUE);
$field_storage->save();
// Set up block_content infos.
$this->blockContentInfos = [
'en' => 'Food in Paris',
'es' => 'Comida en Paris',
'fr' => 'Nouriture en Paris',
];
// Create block_content with translations.
$block_content = $this->createBlockContent(['info' => $this->blockContentInfos['en'], 'langcode' => 'en', 'type' => 'basic', 'body' => [['value' => $this->blockContentInfos['en']]]]);
foreach (['es', 'fr'] as $langcode) {
$translation = $block_content->addTranslation($langcode, ['info' => $this->blockContentInfos[$langcode]]);
$translation->body->value = $this->blockContentInfos[$langcode];
}
$block_content->save();
}
/**
* Tests body and info filters.
*/
public function testFilters() {
// Test the info filter page, which filters for info contains 'Comida'.
// Should show just the Spanish translation, once.
$this->assertPageCounts('test-info-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida info filter');
// Test the body filter page, which filters for body contains 'Comida'.
// Should show just the Spanish translation, once.
$this->assertPageCounts('test-body-filter', ['es' => 1, 'fr' => 0, 'en' => 0], 'Comida body filter');
// Test the info Paris filter page, which filters for info contains
// 'Paris'. Should show each translation once.
$this->assertPageCounts('test-info-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris info filter');
// Test the body Paris filter page, which filters for body contains
// 'Paris'. Should show each translation once.
$this->assertPageCounts('test-body-paris', ['es' => 1, 'fr' => 1, 'en' => 1], 'Paris body filter');
}
/**
* Asserts that the given block_content translation counts are correct.
*
* @param string $path
* Path of the page to test.
* @param array $counts
* Array whose keys are languages, and values are the number of times
* that translation should be shown on the given page.
* @param string $message
* Message suffix to display.
*/
protected function assertPageCounts($path, $counts, $message) {
// Get the text of the page.
$this->drupalGet($path);
$text = $this->getTextContent();
foreach ($counts as $langcode => $count) {
$this->assertEqual(substr_count($text, $this->blockContentInfos[$langcode]), $count, 'Translation ' . $langcode . ' has count ' . $count . ' with ' . $message);
}
}
}
@@ -0,0 +1,67 @@
<?php
namespace Drupal\Tests\block_content\Functional\Views;
/**
* Tests the block_content integration into views.
*
* @group block_content
*/
class BlockContentIntegrationTest extends BlockContentTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_block_content_view'];
/**
* Tests basic block_content view with a block_content_type argument.
*/
public function testBlockContentViewTypeArgument() {
// Create two content types with three block_contents each.
$types = [];
$all_ids = [];
$block_contents = [];
for ($i = 0; $i < 2; $i++) {
$type = $this->createBlockContentType();
$types[] = $type;
for ($j = 0; $j < 5; $j++) {
// Ensure the right order of the block_contents.
$block_content = $this->createBlockContent(['type' => $type->id()]);
$block_contents[$type->id()][$block_content->id()] = $block_content;
$all_ids[] = $block_content->id();
}
}
$this->drupalGet('test-block_content-view');
$this->assertResponse(404);
$this->drupalGet('test-block_content-view/all');
$this->assertResponse(200);
$this->assertIds($all_ids);
/* @var \Drupal\block_content\Entity\BlockContentType[] $types*/
foreach ($types as $type) {
$this->drupalGet("test-block_content-view/{$type->id()}");
$this->assertIds(array_keys($block_contents[$type->id()]));
}
}
/**
* Ensures that a list of block_contents appear on the page.
*
* @param array $expected_ids
* An array of block_content IDs.
*/
protected function assertIds(array $expected_ids = []) {
$result = $this->xpath('//span[@class="field-content"]');
$ids = [];
foreach ($result as $element) {
$ids[] = $element->getText();
}
$this->assertEqual($ids, $expected_ids);
}
}
@@ -0,0 +1,50 @@
<?php
namespace Drupal\Tests\block_content\Functional\Views;
/**
* Tests the redirect destination on block content on entity operations.
*
* @group block_content
*/
class BlockContentRedirectTest extends BlockContentTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_block_content_redirect_destination'];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block', 'block_content', 'views'];
/**
* Tests the redirect destination when editing block content.
*/
public function testRedirectDestination() {
$this->drupalLogin($this->drupalCreateUser(['administer blocks']));
$this->drupalGet('admin/structure/block/block-content');
// Create a custom block.
$this->clickLink('custom block');
$edit = [];
$edit['info[0][value]'] = 'Test redirect destination';
$edit['body[0][value]'] = $this->randomMachineName(16);
$this->drupalPostForm(NULL, $edit, 'Save');
// Check the block content is present in the view redirect destination.
$this->drupalGet('admin/content/redirect_destination');
$this->assertText('Test redirect destination');
// Edit the created block and save.
$this->clickLink('Edit');
$this->drupalPostForm(NULL, [], 'Save');
$this->assertUrl('admin/content/redirect_destination');
}
}
@@ -0,0 +1,107 @@
<?php
namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Base class for all block_content tests.
*/
abstract class BlockContentTestBase extends ViewTestBase {
/**
* Admin user
*
* @var object
*/
protected $adminUser;
/**
* Permissions to grant admin user.
*
* @var array
*/
protected $permissions = [
'administer blocks',
];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block', 'block_content', 'block_content_test_views'];
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
// Ensure the basic bundle exists. This is provided by the standard profile.
$this->createBlockContentType(['id' => 'basic']);
$this->adminUser = $this->drupalCreateUser($this->permissions);
if ($import_test_views) {
ViewTestData::createTestViews(get_class($this), ['block_content_test_views']);
}
}
/**
* Creates a custom block.
*
* @param array $settings
* (optional) An associative array of settings for the block_content, as
* used in entity_create().
*
* @return \Drupal\block_content\Entity\BlockContent
* Created custom block.
*/
protected function createBlockContent(array $settings = []) {
$status = 0;
$settings += [
'info' => $this->randomMachineName(),
'type' => 'basic',
'langcode' => 'en',
];
if ($block_content = BlockContent::create($settings)) {
$status = $block_content->save();
}
$this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content %info.', ['%info' => $block_content->label()]));
return $block_content;
}
/**
* Creates a custom block type (bundle).
*
* @param array $values
* An array of settings to change from the defaults.
*
* @return \Drupal\block_content\Entity\BlockContentType
* Created custom block type.
*/
protected function createBlockContentType(array $values = []) {
// Find a non-existent random type name.
if (!isset($values['id'])) {
do {
$id = strtolower($this->randomMachineName(8));
} while (BlockContentType::load($id));
}
else {
$id = $values['id'];
}
$values += [
'id' => $id,
'label' => $id,
'revision' => FALSE
];
$bundle = BlockContentType::create($values);
$status = $bundle->save();
block_content_add_body_field($bundle->id());
$this->assertEqual($status, SAVED_NEW, SafeMarkup::format('Created block content type %bundle.', ['%bundle' => $bundle->id()]));
return $bundle;
}
}
@@ -0,0 +1,37 @@
<?php
namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\views\Views;
/**
* Tests the Drupal\block_content\Plugin\views\field\Type handler.
*
* @group block_content
*/
class FieldTypeTest extends BlockContentTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_field_type'];
public function testFieldType() {
$block_content = $this->createBlockContent();
$expected_result[] = [
'id' => $block_content->id(),
'type' => $block_content->bundle(),
];
$column_map = [
'id' => 'id',
'type:target_id' => 'type',
];
$view = Views::getView('test_field_type');
$this->executeView($view);
$this->assertIdenticalResultset($view, $expected_result, $column_map, 'The correct block_content type was displayed.');
}
}
@@ -0,0 +1,92 @@
<?php
namespace Drupal\Tests\block_content\Functional\Views;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\block_content\Entity\BlockContent;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Views;
use Drupal\views\Tests\ViewTestData;
/**
* Tests the integration of block_content_revision table of block_content module.
*
* @group block_content
*/
class RevisionRelationshipsTest extends ViewTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['block_content' , 'block_content_test_views'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_block_content_revision_id', 'test_block_content_revision_revision_id'];
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
BlockContentType::create([
'id' => 'basic',
'label' => 'basic',
'revision' => TRUE,
]);
ViewTestData::createTestViews(get_class($this), ['block_content_test_views']);
}
/**
* Create a block_content with revision and rest result count for both views.
*/
public function testBlockContentRevisionRelationship() {
$block_content = BlockContent::create([
'info' => $this->randomMachineName(),
'type' => 'basic',
'langcode' => 'en',
]);
$block_content->save();
// Create revision of the block_content.
$block_content_revision = clone $block_content;
$block_content_revision->setNewRevision();
$block_content_revision->save();
$column_map = [
'revision_id' => 'revision_id',
'id_1' => 'id_1',
'block_content_field_data_block_content_field_revision_id' => 'block_content_field_data_block_content_field_revision_id',
];
// Here should be two rows.
$view_id = Views::getView('test_block_content_revision_id');
$this->executeView($view_id, [$block_content->id()]);
$resultset_id = [
[
'revision_id' => '1',
'id_1' => '1',
'block_content_field_data_block_content_field_revision_id' => '1',
],
[
'revision_id' => '2',
'id_1' => '1',
'block_content_field_data_block_content_field_revision_id' => '1',
],
];
$this->assertIdenticalResultset($view_id, $resultset_id, $column_map);
// There should be only one row with active revision 2.
$view_revision_id = Views::getView('test_block_content_revision_revision_id');
$this->executeView($view_revision_id, [$block_content->id()]);
$resultset_revision_id = [
[
'revision_id' => '2',
'id_1' => '1',
'block_content_field_data_block_content_field_revision_id' => '1',
],
];
$this->assertIdenticalResultset($view_revision_id, $resultset_revision_id, $column_map);
}
}
@@ -0,0 +1,63 @@
<?php
namespace Drupal\Tests\block_content\Kernel;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Plugin\PluginBase;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests that deleting a block clears the cached definitions.
*
* @group block_content
*/
class BlockContentDeletionTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block', 'block_content', 'system', 'user'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installSchema('system', ['sequence']);
$this->installEntitySchema('user');
$this->installEntitySchema('block_content');
}
/**
* Tests deleting a block_content updates the discovered block plugin.
*/
public function testDeletingBlockContentShouldClearPluginCache() {
// Create a block content type.
$block_content_type = BlockContentType::create([
'id' => 'spiffy',
'label' => 'Mucho spiffy',
'description' => "Provides a block type that increases your site's spiffiness by upto 11%",
]);
$block_content_type->save();
// And a block content entity.
$block_content = BlockContent::create([
'info' => 'Spiffy prototype',
'type' => 'spiffy',
]);
$block_content->save();
// Make sure the block content provides a derivative block plugin in the
// block repository.
/** @var \Drupal\Core\Block\BlockManagerInterface $block_manager */
$block_manager = $this->container->get('plugin.manager.block');
$plugin_id = 'block_content' . PluginBase::DERIVATIVE_SEPARATOR . $block_content->uuid();
$this->assertTrue($block_manager->hasDefinition($plugin_id));
// Now delete the block content entity.
$block_content->delete();
// The plugin should no longer exist.
$this->assertFalse($block_manager->hasDefinition($plugin_id));
}
}
@@ -15,7 +15,7 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
*/
class MigrateBlockContentBodyFieldTest extends MigrateDrupal7TestBase {
public static $modules = array('block', 'block_content', 'filter', 'text');
public static $modules = ['block', 'block_content', 'filter', 'text'];
/**
* {@inheritdoc}
@@ -0,0 +1,54 @@
<?php
namespace Drupal\Tests\block_content\Kernel\Migrate;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
/**
* Tests migration of block content body field display configuration.
*
* @group block_content
*/
class MigrateBlockContentEntityDisplayTest extends MigrateDrupal7TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block', 'block_content', 'filter', 'text'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(static::$modules);
$this->executeMigrations([
'block_content_type',
'block_content_body_field',
'block_content_entity_display',
]);
}
/**
* Asserts a display entity.
*
* @param string $id
* The entity ID.
* @param string $component_id
* The ID of the display component.
*/
protected function assertDisplay($id, $component_id) {
$component = EntityViewDisplay::load($id)->getComponent($component_id);
$this->assertInternalType('array', $component);
$this->assertSame('hidden', $component['label']);
}
/**
* Tests the migrated display configuration.
*/
public function testMigration() {
$this->assertDisplay('block_content.basic.default', 'body');
}
}
@@ -0,0 +1,54 @@
<?php
namespace Drupal\Tests\block_content\Kernel\Migrate;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
/**
* Tests migration of block content body field form display configuration.
*
* @group block_content
*/
class MigrateBlockContentEntityFormDisplayTest extends MigrateDrupal7TestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block', 'block_content', 'filter', 'text'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(static::$modules);
$this->executeMigrations([
'block_content_type',
'block_content_body_field',
'block_content_entity_form_display',
]);
}
/**
* Asserts a display entity.
*
* @param string $id
* The entity ID.
* @param string $component
* The ID of the form component.
*/
protected function assertDisplay($id, $component_id) {
$component = EntityFormDisplay::load($id)->getComponent($component_id);
$this->assertInternalType('array', $component);
$this->assertSame('text_textarea_with_summary', $component['type']);
}
/**
* Tests the migrated display configuration.
*/
public function testMigration() {
$this->assertDisplay('block_content.basic.default', 'body');
}
}
@@ -13,7 +13,7 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
*/
class MigrateBlockContentTypeTest extends MigrateDrupal7TestBase {
public static $modules = array('block', 'block_content', 'filter', 'text');
public static $modules = ['block', 'block_content', 'filter', 'text'];
/**
* {@inheritdoc}
@@ -13,11 +13,11 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
*/
class MigrateCustomBlockTest extends MigrateDrupal7TestBase {
public static $modules = array(
public static $modules = [
'block_content',
'filter',
'text',
);
];
/**
* {@inheritdoc}
@@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\block_content\Kernel\Plugin\migrate\source\d6;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests D6 block boxes source plugin.
*
* @covers \Drupal\block_content\Plugin\migrate\source\d6\Box
* @group block_content
*/
class BoxTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block_content', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['boxes'] = [
[
'bid' => 1,
'body' => '<p>I made some custom content.</p>',
'info' => 'Static Block',
'format' => 1,
],
[
'bid' => 2,
'body' => '<p>I made some more custom content.</p>',
'info' => 'Test Content',
'format' => 1,
],
];
// The expected results are identical to the source data.
$tests[0]['expected_data'] = $tests[0]['source_data']['boxes'];
return $tests;
}
}
@@ -0,0 +1,40 @@
<?php
namespace Drupal\Tests\block_content\Kernel\Plugin\migrate\source\d7;
use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase;
/**
* Tests d7_block_custom source plugin.
*
* @covers \Drupal\block_content\Plugin\migrate\source\d7\BlockCustom
* @group block_content
*/
class BlockCustomTest extends MigrateSqlSourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block_content', 'migrate_drupal'];
/**
* {@inheritdoc}
*/
public function providerSource() {
$tests = [];
$tests[0]['source_data']['block_custom'] = [
[
'bid' => '1',
'body' => "I don't feel creative enough to write anything clever here.",
'info' => 'Meh',
'format' => 'filtered_html',
],
];
// The expected results are identical to the source data.
$tests[0]['expected_data'] = $tests[0]['source_data']['block_custom'];
return $tests;
}
}
@@ -13,32 +13,32 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
class BlockContentLocalTasksTest extends LocalTaskIntegrationTestBase {
protected function setUp() {
$this->directoryList = array(
$this->directoryList = [
'block' => 'core/modules/block',
'block_content' => 'core/modules/block_content',
);
];
parent::setUp();
$config_factory = $this->getConfigFactoryStub(array('system.theme' => array(
$config_factory = $this->getConfigFactoryStub(['system.theme' => [
'default' => 'test_c',
)));
]]);
$themes = array();
$themes['test_a'] = (object) array(
$themes = [];
$themes['test_a'] = (object) [
'status' => 0,
);
$themes['test_b'] = (object) array(
];
$themes['test_b'] = (object) [
'status' => 1,
'info' => array(
'info' => [
'name' => 'test_b',
),
);
$themes['test_c'] = (object) array(
],
];
$themes['test_c'] = (object) [
'status' => 1,
'info' => array(
'info' => [
'name' => 'test_c',
),
);
],
];
$theme_handler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
$theme_handler->expects($this->any())
->method('listInfo')
@@ -56,25 +56,25 @@ class BlockContentLocalTasksTest extends LocalTaskIntegrationTestBase {
* @dataProvider getBlockContentListingRoutes
*/
public function testBlockContentListLocalTasks($route) {
$this->assertLocalTasks($route, array(
0 => array(
$this->assertLocalTasks($route, [
0 => [
'block.admin_display',
'entity.block_content.collection',
),
1 => array(
],
1 => [
'block_content.list_sub',
'entity.block_content_type.collection',
),
));
],
]);
}
/**
* Provides a list of routes to test.
*/
public function getBlockContentListingRoutes() {
return array(
array('entity.block_content.collection', 'entity.block_content_type.collection'),
);
return [
['entity.block_content.collection', 'entity.block_content_type.collection'],
];
}
}