diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 37b93bd..ceffa1f 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -49,7 +49,7 @@ function block_help($route_name, Request $request) { $output .= '
' . t('Controlling visibility') . '
'; $output .= '
' . t('You can control the visibility of a block by restricting it to specific pages, content types, and/or roles by setting the appropriate options under Visibility settings of the block configuration.') . '
'; $output .= '
' . t('Adding custom blocks') . '
'; - $output .= '
' . t('You can add custom blocks, if the the Custom Block module is enabled on the Extend page. For more information, see the Custom Block help page.', array('!extend' => \Drupal::url('system.modules_list'), '!customblock-help' => \Drupal::url('help.page', array('name' => 'custom_block')))) . '
'; + $output .= '
' . t('You can add custom blocks, if the the Custom Block module is enabled on the Extend page. For more information, see the Custom Block help page.', array('!extend' => \Drupal::url('system.modules_list'), '!blockcontent-help' => \Drupal::url('help.page', array('name' => 'block_content')))) . '
'; $output .= ''; return $output; } diff --git a/core/modules/block/custom_block/config/install/custom_block.type.basic.yml b/core/modules/block/custom_block/config/install/custom_block.type.basic.yml deleted file mode 100644 index 02982e4..0000000 --- a/core/modules/block/custom_block/config/install/custom_block.type.basic.yml +++ /dev/null @@ -1,5 +0,0 @@ -id: basic -label: 'Basic block' -revision: 0 -description: 'A basic block contains a title and a body.' -langcode: en diff --git a/core/modules/block/custom_block/config/install/entity.view_mode.custom_block.full.yml b/core/modules/block/custom_block/config/install/entity.view_mode.custom_block.full.yml deleted file mode 100644 index 2987629..0000000 --- a/core/modules/block/custom_block/config/install/entity.view_mode.custom_block.full.yml +++ /dev/null @@ -1,8 +0,0 @@ -id: custom_block.full -label: Full -status: false -cache: true -targetEntityType: custom_block -dependencies: - module: - - custom_block diff --git a/core/modules/block/custom_block/config/schema/custom_block.schema.yml b/core/modules/block/custom_block/config/schema/custom_block.schema.yml deleted file mode 100644 index 1a9c04d..0000000 --- a/core/modules/block/custom_block/config/schema/custom_block.schema.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Schema for the configuration files of the Custom Block module. - -custom_block.type.*: - type: mapping - label: 'Custom block type settings' - mapping: - id: - type: string - label: 'Machine-readable name' - uuid: - type: string - label: 'UUID' - label: - type: label - label: 'Label' - revision: - type: integer - label: 'Create new revision' - description: - type: text - label: 'Description' - status: - type: boolean - label: 'Status' - langcode: - type: string - label: 'Default language' diff --git a/core/modules/block/custom_block/custom_block.contextual_links.yml b/core/modules/block/custom_block/custom_block.contextual_links.yml deleted file mode 100644 index acd117f..0000000 --- a/core/modules/block/custom_block/custom_block.contextual_links.yml +++ /dev/null @@ -1,10 +0,0 @@ -custom_block.block_edit: - title: 'Edit' - group: custom_block - route_name: 'custom_block.edit' - -custom_block.block_delete: - title: 'Delete' - group: custom_block - route_name: 'custom_block.delete' - weight: 1 diff --git a/core/modules/block/custom_block/custom_block.info.yml b/core/modules/block/custom_block/custom_block.info.yml deleted file mode 100644 index 692648f..0000000 --- a/core/modules/block/custom_block/custom_block.info.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: 'Custom Block' -type: module -description: 'Allows the creation of custom blocks through the user interface.' -package: Core -version: VERSION -core: 8.x -dependencies: - - block - - text -configure: custom_block.list diff --git a/core/modules/block/custom_block/custom_block.install b/core/modules/block/custom_block/custom_block.install deleted file mode 100644 index 6f85a6a..0000000 --- a/core/modules/block/custom_block/custom_block.install +++ /dev/null @@ -1,125 +0,0 @@ - 'Stores contents of custom-made blocks.', - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'description' => "The block's {custom_block}.id.", - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'info' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Block description.', - ), - // Defaults to NULL in order to avoid a brief period of potential - // deadlocks on the index. - 'revision_id' => array( - 'description' => 'The current {block_custom_revision}.revision_id version identifier.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => FALSE, - 'default' => NULL, - ), - 'type' => array( - 'description' => 'The type of this custom block.', - 'type' => 'varchar', - 'length' => EntityTypeInterface::BUNDLE_MAX_LENGTH, - 'not null' => TRUE, - 'default' => '', - ), - 'changed' => array( - 'description' => 'The Unix timestamp when the custom block was most recently saved.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this node.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'primary key' => array('id'), - 'indexes' => array( - 'block_custom_type' => array('type'), - ), - 'unique keys' => array( - 'revision_id' => array('revision_id'), - 'uuid' => array('uuid'), - 'info' => array('info'), - ), - 'foreign keys' => array( - 'custom_block_revision' => array( - 'table' => 'custom_block_revision', - 'columns' => array('revision_id' => 'revision_id'), - ), - ), - ); - - $schema['custom_block_revision'] = array( - 'description' => 'Stores contents of custom-made blocks.', - 'fields' => array( - 'id' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => "The block's {custom_block}.id.", - ), - // Defaults to NULL in order to avoid a brief period of potential - // deadlocks on the index. - 'revision_id' => array( - 'description' => 'The current version identifier.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'log' => array( - 'description' => 'The log entry explaining the changes in this version.', - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - ), - 'info' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Block description.', - ), - 'changed' => array( - 'description' => 'The Unix timestamp when the version was most recently saved.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('revision_id'), - ); - return $schema; -} diff --git a/core/modules/block/custom_block/custom_block.libraries.yml b/core/modules/block/custom_block/custom_block.libraries.yml deleted file mode 100644 index 34539a8..0000000 --- a/core/modules/block/custom_block/custom_block.libraries.yml +++ /dev/null @@ -1,8 +0,0 @@ -drupal.custom_block: - version: VERSION - js: - js/custom_block.js: {} - dependencies: - - core/jquery - - core/drupal - - core/drupal.form diff --git a/core/modules/block/custom_block/custom_block.local_actions.yml b/core/modules/block/custom_block/custom_block.local_actions.yml deleted file mode 100644 index e3b57c6..0000000 --- a/core/modules/block/custom_block/custom_block.local_actions.yml +++ /dev/null @@ -1,14 +0,0 @@ -custom_block_type_add: - route_name: custom_block.type_add - title: 'Add custom block type' - appears_on: - - custom_block.type_list - -custom_block_add_action: - route_name: custom_block.add_page - title: 'Add custom block' - appears_on: - - block.admin_display - - block.admin_display_theme - - custom_block.list - class: \Drupal\custom_block\Plugin\Menu\LocalAction\CustomBlockAddLocalAction diff --git a/core/modules/block/custom_block/custom_block.local_tasks.yml b/core/modules/block/custom_block/custom_block.local_tasks.yml deleted file mode 100644 index 041abb7..0000000 --- a/core/modules/block/custom_block/custom_block.local_tasks.yml +++ /dev/null @@ -1,27 +0,0 @@ -custom_block.list: - title: 'Custom block library' - route_name: custom_block.list - base_route: block.admin_display -custom_block.list_sub: - title: Blocks - route_name: custom_block.list - parent_id: custom_block.list -custom_block.type_list: - title: Types - route_name: custom_block.type_list - parent_id: custom_block.list - -custom_block.edit: - title: Edit - route_name: custom_block.edit - base_route: custom_block.edit -custom_block.delete: - title: Delete - route_name: custom_block.delete - base_route: custom_block.edit - -# Default tab for custom block type editing. -custom_block.type_edit: - title: 'Edit' - route_name: custom_block.type_edit - base_route: custom_block.type_edit diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module deleted file mode 100644 index 00caf8e..0000000 --- a/core/modules/block/custom_block/custom_block.module +++ /dev/null @@ -1,117 +0,0 @@ -' . t('About') . ''; - $output .= '

' . t('The Custom Block module allows you to create blocks of content, which can be placed in regions throughout the website. Custom blocks can have fields; see the Field module help for more information. Once created, custom blocks can be placed like blocks provided by other modules; see the Block module help page for details. For more information, see the online documentation for the Custom Block module.', array('!custom-blocks' => \Drupal::url('custom_block.list'), '!field-help' => \Drupal::url('help.page', array('name' => 'field')), '!blocks' => \Drupal::url('help.page', array('name' => 'block')), '!online-help' => 'https://drupal.org/documentation/modules/custom_block')) . '

'; - $output .= '

' . t('Uses') . '

'; - $output .= '
'; - $output .= '
' . t('Creating and managing custom block types') . '
'; - $output .= '
' . t('Users with the Administer blocks permission can create different custom block types, each with different fields and display settings, from the Custom block types page. The Custom block types page lists all of your created custom block types, and allows you to edit and manage them. For more information about managing fields and display settings, see the Field UI module help.', array('!types' => \Drupal::url('custom_block.type_list'), '!field-ui' => \Drupal::url('help.page', array('name' => 'field_ui')))) . '
'; - $output .= '
' . t('Creating custom blocks') . '
'; - $output .= '
' . t('Users with the Administer blocks permission can add custom blocks of each of their defined custom block types. Created custom blocks are then listed on the Blocks administration page.', array('!blocks' => \Drupal::url('block.admin_display'), '!block-add' => \Drupal::url('custom_block.add_page'))) . '
'; - $output .= '
'; - return $output; - - case 'custom_block.list': - $output = '

' . t('This page lists user-created blocks. These blocks are derived from block types. A block type can consist of different fields and display settings. From the block types tab you can manage these fields as well as create new block types.') . '

'; - return $output; - - case 'custom_block.type_list': - $output = '

' . t('This page lists block types. A block type can consist of different fields and display settings. From here you can manage these fields as well as create new block types.') . '

'; - return $output; - - } -} - -/** - * Implements hook_theme(). - */ -function custom_block_theme($existing, $type, $theme, $path) { - return array( - 'custom_block_add_list' => array( - 'variables' => array('content' => NULL), - 'file' => 'custom_block.pages.inc', - 'template' => 'custom-block-add-list', - ), - ); -} - -/** - * Implements hook_entity_type_alter(). - */ -function custom_block_entity_type_alter(array &$entity_types) { - /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */ - // Add a translation handler for fields if the language module is enabled. - if (\Drupal::moduleHandler()->moduleExists('language')) { - $translation = $entity_types['custom_block']->get('translation'); - $translation['custom_block'] = TRUE; - $entity_types['custom_block']->set('translation', $translation); - } -} - -/** - * Adds the default body field to a custom block type. - * - * @param string $block_type_id - * Id of the block type. - * @param string $label - * (optional) The label for the body instance. Defaults to 'Body' - * - * @return array() - * Body field instance. - */ -function custom_block_add_body_field($block_type_id, $label = 'Body') { - // Add or remove the body field, as needed. - $field = FieldConfig::loadByName('custom_block', 'body'); - $instance = FieldInstanceConfig::loadByName('custom_block', $block_type_id, 'body'); - if (empty($field)) { - $field = entity_create('field_config', array( - 'name' => 'body', - 'entity_type' => 'custom_block', - 'type' => 'text_with_summary', - )); - $field->save(); - } - if (empty($instance)) { - $instance = entity_create('field_instance_config', array( - 'field_name' => 'body', - 'entity_type' => 'custom_block', - 'bundle' => $block_type_id, - 'label' => $label, - 'settings' => array('display_summary' => FALSE), - )); - $instance->save(); - - // Assign widget settings for the 'default' form mode. - entity_get_form_display('custom_block', $block_type_id, 'default') - ->setComponent('body', array( - 'type' => 'text_textarea_with_summary', - )) - ->save(); - - // Assign display settings for 'default' view mode. - entity_get_display('custom_block', $block_type_id, 'default') - ->setComponent('body', array( - 'label' => 'hidden', - 'type' => 'text_default', - )) - ->save(); - } - - return $instance; -} diff --git a/core/modules/block/custom_block/custom_block.pages.inc b/core/modules/block/custom_block/custom_block.pages.inc deleted file mode 100644 index f24e16b..0000000 --- a/core/modules/block/custom_block/custom_block.pages.inc +++ /dev/null @@ -1,37 +0,0 @@ -query->all(); - foreach ($variables['content'] as $type) { - $variables['types'][$type->id()] = array( - 'link' => \Drupal::l($type->label(), 'custom_block.add_form', array('custom_block_type' => $type->id()), array('query' => $query)), - 'description' => Xss::filterAdmin($type->description), - 'title' => $type->label(), - 'localized_options' => array( - 'query' => $query, - ), - ); - } -} diff --git a/core/modules/block/custom_block/custom_block.routing.yml b/core/modules/block/custom_block/custom_block.routing.yml deleted file mode 100644 index cad1f09..0000000 --- a/core/modules/block/custom_block/custom_block.routing.yml +++ /dev/null @@ -1,80 +0,0 @@ -custom_block.type_list: - path: '/admin/structure/block/custom-blocks/types' - defaults: - _entity_list: 'custom_block_type' - _title: 'Edit' - requirements: - _permission: 'administer blocks' - -custom_block.add_page: - path: '/block/add' - defaults: - _content: '\Drupal\custom_block\Controller\CustomBlockController::add' - _title: 'Add custom block' - options: - _admin_route: TRUE - requirements: - _permission: 'administer blocks' - -custom_block.add_form: - path: '/block/add/{custom_block_type}' - defaults: - _content: '\Drupal\custom_block\Controller\CustomBlockController::addForm' - _title_callback: 'Drupal\custom_block\Controller\CustomBlockController::getAddFormTitle' - options: - _admin_route: TRUE - requirements: - _permission: 'administer blocks' - -custom_block.type_delete: - path: '/admin/structure/block/custom-blocks/manage/{custom_block_type}/delete' - defaults: - _entity_form: 'custom_block_type.delete' - _title: 'Delete' - requirements: - _entity_access: 'custom_block_type.delete' - options: - _admin_route: TRUE - -custom_block.edit: - path: '/block/{custom_block}' - defaults: - _entity_form: 'custom_block.edit' - options: - _admin_route: TRUE - requirements: - _entity_access: 'custom_block.update' - -custom_block.delete: - path: '/block/{custom_block}/delete' - defaults: - _entity_form: 'custom_block.delete' - _title: 'Delete' - options: - _admin_route: TRUE - requirements: - _entity_access: 'custom_block.delete' - -custom_block.type_add: - path: '/admin/structure/block/custom-blocks/types/add' - defaults: - _entity_form: 'custom_block_type.add' - _title: 'Add' - requirements: - _permission: 'administer blocks' - -custom_block.type_edit: - path: '/admin/structure/block/custom-blocks/manage/{custom_block_type}' - defaults: - _entity_form: 'custom_block_type.edit' - _title: 'Edit' - requirements: - _entity_access: 'custom_block_type.update' - -custom_block.list: - path: '/admin/structure/block/custom-blocks' - defaults: - _title: 'Custom block library' - _entity_list: 'custom_block' - requirements: - _permission: 'administer blocks' diff --git a/core/modules/block/custom_block/js/custom_block.js b/core/modules/block/custom_block/js/custom_block.js deleted file mode 100644 index be0ea7d..0000000 --- a/core/modules/block/custom_block/js/custom_block.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file - * Defines Javascript behaviors for the custom_block module. - */ - -(function ($) { - - "use strict"; - - Drupal.behaviors.customBlockDetailsSummaries = { - attach: function (context) { - var $context = $(context); - $context.find('.custom-block-form-revision-information').drupalSetSummary(function (context) { - var $context = $(context); - var revisionCheckbox = $context.find('.form-item-revision input'); - - // Return 'New revision' if the 'Create new revision' checkbox is checked, - // or if the checkbox doesn't exist, but the revision log does. For users - // without the "Administer content" permission the checkbox won't appear, - // but the revision log will if the content type is set to auto-revision. - if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $context.find('.form-item-log textarea').length)) { - return Drupal.t('New revision'); - } - - return Drupal.t('No revision'); - }); - - $context.find('fieldset.custom-block-translation-options').drupalSetSummary(function (context) { - var $context = $(context); - var translate; - var $checkbox = $context.find('.form-item-translation-translate input'); - - if ($checkbox.size()) { - translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated'); - } - else { - $checkbox = $context.find('.form-item-translation-retranslate input'); - translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated'); - } - - return translate; - }); - } - }; - -})(jQuery); diff --git a/core/modules/block/custom_block/src/Controller/CustomBlockController.php b/core/modules/block/custom_block/src/Controller/CustomBlockController.php deleted file mode 100644 index e30c42d..0000000 --- a/core/modules/block/custom_block/src/Controller/CustomBlockController.php +++ /dev/null @@ -1,115 +0,0 @@ -get('entity.manager'); - return new static( - $entity_manager->getStorage('custom_block'), - $entity_manager->getStorage('custom_block_type') - ); - } - - /** - * Constructs a CustomBlock object. - * - * @param \Drupal\Core\Entity\EntityStorageInterface $custom_block_storage - * The custom block storage. - * @param \Drupal\Core\Entity\EntityStorageInterface $custom_block_type_storage - * The custom block type storage. - */ - public function __construct(EntityStorageInterface $custom_block_storage, EntityStorageInterface $custom_block_type_storage) { - $this->customBlockStorage = $custom_block_storage; - $this->customBlockTypeStorage = $custom_block_type_storage; - } - - /** - * Displays add custom block links for available types. - * - * @param \Symfony\Component\HttpFoundation\Request $request - * The current request object. - * - * @return array - * A render array for a list of the custom block types that can be added or - * if there is only one custom block type defined for the site, the function - * returns the custom block add page for that custom block type. - */ - public function add(Request $request) { - $types = $this->customBlockTypeStorage->loadMultiple(); - if ($types && count($types) == 1) { - $type = reset($types); - return $this->addForm($type, $request); - } - - return array('#theme' => 'custom_block_add_list', '#content' => $types); - } - - /** - * Presents the custom block creation form. - * - * @param \Drupal\custom_block\CustomBlockTypeInterface $custom_block_type - * The custom block type to add. - * @param \Symfony\Component\HttpFoundation\Request $request - * The current request object. - * - * @return array - * A form array as expected by drupal_render(). - */ - public function addForm(CustomBlockTypeInterface $custom_block_type, Request $request) { - $block = $this->customBlockStorage->create(array( - 'type' => $custom_block_type->id() - )); - if (($theme = $request->query->get('theme')) && in_array($theme, array_keys(list_themes()))) { - // 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 - // newly created block in the given theme. - $block->setTheme($theme); - } - return $this->entityFormBuilder()->getForm($block); - } - - /** - * Provides the page title for this controller. - * - * @param \Drupal\custom_block\CustomBlockTypeInterface $custom_block_type - * The custom block type being added. - * - * @return string - * The page title. - */ - public function getAddFormTitle(CustomBlockTypeInterface $custom_block_type) { - return $this->t('Add %type custom block', array('%type' => $custom_block_type->label())); - } - -} diff --git a/core/modules/block/custom_block/src/CustomBlockAccessController.php b/core/modules/block/custom_block/src/CustomBlockAccessController.php deleted file mode 100644 index c1d65be..0000000 --- a/core/modules/block/custom_block/src/CustomBlockAccessController.php +++ /dev/null @@ -1,29 +0,0 @@ -customBlockStorage = $custom_block_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('custom_block'), - $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_custom_block_prepare() - * on all modules. - */ - protected function prepareEntity() { - $block = $this->entity; - // Set up default values, if required. - $block_type = entity_load('custom_block_type', $block->bundle()); - if (!$block->isNew()) { - $block->setRevisionLog(NULL); - } - // Always use the default revision setting. - $block->setNewRevision($block_type->revision); - } - - /** - * {@inheritdoc} - */ - public function form(array $form, array &$form_state) { - $block = $this->entity; - $account = $this->currentUser(); - - if ($this->operation == 'edit') { - $form['#title'] = $this->t('Edit custom block %label', array('%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] = drupal_html_class('block-' . $block->bundle() . '-form'); - - if ($this->moduleHandler->moduleExists('language')) { - $language_configuration = language_get_default_configuration('custom_block', $block->bundle()); - - // Set the correct default language. - if ($block->isNew()) { - $language_default = $this->languageManager->getCurrentLanguage($language_configuration['langcode']); - $block->langcode->value = $language_default->id; - } - } - - $form['langcode'] = array( - '#title' => $this->t('Language'), - '#type' => 'language_select', - '#default_value' => $block->getUntranslated()->language()->id, - '#languages' => Language::STATE_ALL, - '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'], - ); - - $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('custom-block-form-revision-information'), - ), - '#attached' => array( - 'library' => array('custom_block/drupal.custom_block'), - ), - '#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="log"]' => array('empty' => FALSE), - ), - ); - } - - $form['revision_information']['log'] = array( - '#type' => 'textarea', - '#title' => $this->t('Revision log message'), - '#rows' => 4, - '#default_value' => $block->getRevisionLog(), - '#description' => $this->t('Briefly desribe the changes you have made.'), - ); - - return parent::form($form, $form_state, $block); - } - - /** - * Overrides \Drupal\Core\Entity\EntityForm::submit(). - * - * Updates the custom block object by processing the submitted values. - * - * This function can be called by a "Next" button of a wizard to update the - * form state's entity with the current step's values before proceeding to the - * next step. - */ - public function submit(array $form, array &$form_state) { - // Build the block object from the submitted values. - $block = parent::submit($form, $form_state); - - // Save as a new revision if requested to do so. - if (!empty($form_state['values']['revision'])) { - $block->setNewRevision(); - } - - return $block; - } - - /** - * {@inheritdoc} - */ - public function save(array $form, array &$form_state) { - $block = $this->entity; - $insert = $block->isNew(); - $block->save(); - $watchdog_args = array('@type' => $block->bundle(), '%info' => $block->label()); - $block_type = entity_load('custom_block_type', $block->bundle()); - $t_args = array('@type' => $block_type->label(), '%info' => $block->label()); - - if ($insert) { - watchdog('content', '@type: added %info.', $watchdog_args, WATCHDOG_NOTICE); - drupal_set_message($this->t('@type %info has been created.', $t_args)); - } - else { - watchdog('content', '@type: updated %info.', $watchdog_args, WATCHDOG_NOTICE); - drupal_set_message($this->t('@type %info has been updated.', $t_args)); - } - - if ($block->id()) { - $form_state['values']['id'] = $block->id(); - $form_state['id'] = $block->id(); - if ($insert) { - if (!$theme = $block->getTheme()) { - $theme = $this->config('system.theme')->get('default'); - } - $form_state['redirect_route'] = array( - 'route_name' => 'block.admin_add', - 'route_parameters' => array( - 'plugin_id' => 'custom_block:' . $block->uuid(), - 'theme' => $theme, - ), - ); - } - else { - $form_state['redirect_route']['route_name'] = 'custom_block.list'; - } - } - else { - // In the unlikely case something went wrong on save, the block will be - // rebuilt and block form redisplayed. - drupal_set_message($this->t('The block could not be saved.'), 'error'); - $form_state['rebuild'] = TRUE; - } - - // Clear the page and block caches. - Cache::invalidateTags(array('content' => TRUE)); - } - - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, array &$form_state) { - if ($this->entity->isNew()) { - $exists = $this->customBlockStorage->loadByProperties(array('info' => $form_state['values']['info'])); - if (!empty($exists)) { - $this->setFormError('info', $form_state, $this->t('A block with description %name already exists.', array( - '%name' => $form_state['values']['info'][0]['value'], - ))); - } - } - } - -} diff --git a/core/modules/block/custom_block/src/CustomBlockInterface.php b/core/modules/block/custom_block/src/CustomBlockInterface.php deleted file mode 100644 index 00cac2c..0000000 --- a/core/modules/block/custom_block/src/CustomBlockInterface.php +++ /dev/null @@ -1,83 +0,0 @@ -getLabel($entity); - return $row + parent::buildRow($entity); - } - - /** - * {@inheritdoc} - */ - public function getDefaultOperations(EntityInterface $entity) { - $operations = parent::getDefaultOperations($entity); - if (isset($operations['edit'])) { - $operations['edit']['query']['destination'] = 'admin/structure/block/custom-blocks'; - } - return $operations; - } - -} diff --git a/core/modules/block/custom_block/src/CustomBlockTranslationHandler.php b/core/modules/block/custom_block/src/CustomBlockTranslationHandler.php deleted file mode 100644 index 2bdd7f0..0000000 --- a/core/modules/block/custom_block/src/CustomBlockTranslationHandler.php +++ /dev/null @@ -1,43 +0,0 @@ - 'additional_settings', - '#weight' => 100, - '#attributes' => array( - 'class' => array('custom-block-translation-options'), - ), - ); - } - } - - /** - * {@inheritdoc} - */ - protected function entityFormTitle(EntityInterface $entity) { - $block_type = entity_load('custom_block_type', $entity->bundle()); - return t('Edit @type @title', array('@type' => $block_type->label(), '@title' => $entity->label())); - } - -} diff --git a/core/modules/block/custom_block/src/CustomBlockTypeForm.php b/core/modules/block/custom_block/src/CustomBlockTypeForm.php deleted file mode 100644 index 61567f8..0000000 --- a/core/modules/block/custom_block/src/CustomBlockTypeForm.php +++ /dev/null @@ -1,107 +0,0 @@ -entity; - - $form['label'] = array( - '#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( - '#type' => 'machine_name', - '#default_value' => $block_type->id(), - '#machine_name' => array( - 'exists' => '\Drupal\custom_block\Entity\CustomBlockType::load', - ), - '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH, - '#disabled' => !$block_type->isNew(), - ); - - $form['description'] = array( - '#type' => 'textarea', - '#default_value' => $block_type->description, - '#description' => t('Enter a description for this block type.'), - '#title' => t('Description'), - ); - - $form['revision'] = array( - '#type' => 'checkbox', - '#title' => t('Create new revision'), - '#default_value' => $block_type->revision, - '#description' => t('Create a new revision by default for this block type.') - ); - - if ($this->moduleHandler->moduleExists('content_translation')) { - $form['language'] = array( - '#type' => 'details', - '#title' => t('Language settings'), - '#group' => 'additional_settings', - ); - - $language_configuration = language_get_default_configuration('custom_block', $block_type->id()); - $form['language']['language_configuration'] = array( - '#type' => 'language_configuration', - '#entity_information' => array( - 'entity_type' => 'custom_block', - 'bundle' => $block_type->id(), - ), - '#default_value' => $language_configuration, - ); - - $form['#submit'][] = 'language_configuration_element_submit'; - } - - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save'), - ); - - return $form; - } - - /** - * Overrides \Drupal\Core\Entity\EntityForm::save(). - */ - public function save(array $form, array &$form_state) { - $block_type = $this->entity; - $status = $block_type->save(); - - $edit_link = \Drupal::linkGenerator()->generateFromUrl($this->t('Edit'), $this->entity->urlInfo()); - if ($status == SAVED_UPDATED) { - drupal_set_message(t('Custom block type %label has been updated.', array('%label' => $block_type->label()))); - watchdog('custom_block', 'Custom block type %label has been updated.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, $edit_link); - } - else { - drupal_set_message(t('Custom block type %label has been added.', array('%label' => $block_type->label()))); - watchdog('custom_block', 'Custom block type %label has been added.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, $edit_link); - } - - $form_state['redirect_route']['route_name'] = 'custom_block.type_list'; - } - -} diff --git a/core/modules/block/custom_block/src/CustomBlockTypeInterface.php b/core/modules/block/custom_block/src/CustomBlockTypeInterface.php deleted file mode 100644 index 53bfe1b..0000000 --- a/core/modules/block/custom_block/src/CustomBlockTypeInterface.php +++ /dev/null @@ -1,17 +0,0 @@ -generateFromUrl($entity->label(), $entity->urlInfo()); - $row['description'] = Xss::filterAdmin($entity->description); - return $row + parent::buildRow($entity); - } - - /** - * {@inheritdoc} - */ - protected function getTitle() { - return $this->t('Custom block types'); - } - -} diff --git a/core/modules/block/custom_block/src/CustomBlockViewBuilder.php b/core/modules/block/custom_block/src/CustomBlockViewBuilder.php deleted file mode 100644 index 16e11ee..0000000 --- a/core/modules/block/custom_block/src/CustomBlockViewBuilder.php +++ /dev/null @@ -1,33 +0,0 @@ -isNew() && $view_mode == 'full') { - $build['#contextual_links']['custom_block'] = array( - 'route_parameters' => array('custom_block' => $entity->id()), - 'metadata' => array('changed' => $entity->getChangedTime()), - ); - } - } - -} diff --git a/core/modules/block/custom_block/src/Entity/CustomBlock.php b/core/modules/block/custom_block/src/Entity/CustomBlock.php deleted file mode 100644 index 71913b7..0000000 --- a/core/modules/block/custom_block/src/Entity/CustomBlock.php +++ /dev/null @@ -1,232 +0,0 @@ -revision_id->value = NULL; - $duplicate->id->value = NULL; - return $duplicate; - } - - /** - * {@inheritdoc} - */ - public function setTheme($theme) { - $this->theme = $theme; - return $this; - } - - /** - * {@inheritdoc} - */ - public function getTheme() { - return $this->theme; - } - - /** - * {@inheritdoc} - */ - public function postSave(EntityStorageInterface $storage, $update = TRUE) { - parent::postSave($storage, $update); - - // Invalidate the block cache to update custom block-based derivatives. - \Drupal::service('plugin.manager.block')->clearCachedDefinitions(); - } - - /** - * {@inheritdoc} - */ - public function getInstances() { - return entity_load_multiple_by_properties('block', array('plugin' => 'custom_block:' . $this->uuid())); - } - - /** - * {@inheritdoc} - */ - public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) { - parent::preSaveRevision($storage, $record); - - if ($this->isNewRevision()) { - // When inserting either a new custom block or a new custom_block - // revision, $entity->log must be set because {block_custom_revision}.log - // is a text column and therefore cannot have a default value. However, - // it might not be set at this point (for example, if the user submitting - // the form does not have permission to create revisions), so we ensure - // that it is at least an empty string in that case. - // @todo: Make the {block_custom_revision}.log column nullable so that we - // can remove this check. - if (!isset($record->log)) { - $record->log = ''; - } - } - elseif (isset($this->original) && (!isset($record->log) || $record->log === '')) { - // If we are updating an existing custom_block without adding a new - // revision and the user did not supply a log, keep the existing one. - $record->log = $this->original->getRevisionLog(); - } - } - - /** - * {@inheritdoc} - */ - public function delete() { - foreach ($this->getInstances() as $instance) { - $instance->delete(); - } - parent::delete(); - } - - /** - * {@inheritdoc} - */ - public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { - $fields['id'] = FieldDefinition::create('integer') - ->setLabel(t('Custom block ID')) - ->setDescription(t('The custom block ID.')) - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE); - - $fields['uuid'] = FieldDefinition::create('uuid') - ->setLabel(t('UUID')) - ->setDescription(t('The custom block UUID.')) - ->setReadOnly(TRUE); - - $fields['revision_id'] = FieldDefinition::create('integer') - ->setLabel(t('Revision ID')) - ->setDescription(t('The revision ID.')) - ->setReadOnly(TRUE) - ->setSetting('unsigned', TRUE); - - $fields['langcode'] = FieldDefinition::create('language') - ->setLabel(t('Language code')) - ->setDescription(t('The custom block language code.')); - - $fields['info'] = FieldDefinition::create('string') - ->setLabel(t('Block description')) - ->setDescription(t('A brief description of your block.')) - ->setRevisionable(TRUE) - ->setRequired(TRUE) - ->setDisplayOptions('form', array( - 'type' => 'string', - 'weight' => -5, - )) - ->setDisplayConfigurable('form', TRUE); - - $fields['type'] = FieldDefinition::create('entity_reference') - ->setLabel(t('Block type')) - ->setDescription(t('The block type.')) - ->setSetting('target_type', 'custom_block_type') - ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH); - - $fields['log'] = FieldDefinition::create('string') - ->setLabel(t('Revision log message')) - ->setDescription(t('The revision log message.')) - ->setRevisionable(TRUE); - - $fields['changed'] = FieldDefinition::create('changed') - ->setLabel(t('Changed')) - ->setDescription(t('The time that the custom block was last edited.')) - ->setRevisionable(TRUE); - - return $fields; - } - - /** - * {@inheritdoc} - */ - public function getChangedTime() { - return $this->get('changed')->value; - } - - /** - * {@inheritdoc} - */ - public function getRevisionLog() { - return $this->get('log')->value; - } - - /** - * {@inheritdoc} - */ - public function setInfo($info) { - $this->set('info', $info); - return $this; - } - - /** - * {@inheritdoc} - */ - public function setRevisionLog($log) { - $this->set('log', $log); - return $this; - } - -} diff --git a/core/modules/block/custom_block/src/Entity/CustomBlockType.php b/core/modules/block/custom_block/src/Entity/CustomBlockType.php deleted file mode 100644 index 65dd974..0000000 --- a/core/modules/block/custom_block/src/Entity/CustomBlockType.php +++ /dev/null @@ -1,86 +0,0 @@ -isSyncing()) { - if (!$this->isSyncing()) { - custom_block_add_body_field($this->id); - } - } - } - -} diff --git a/core/modules/block/custom_block/src/Form/CustomBlockDeleteForm.php b/core/modules/block/custom_block/src/Form/CustomBlockDeleteForm.php deleted file mode 100644 index 11d3935..0000000 --- a/core/modules/block/custom_block/src/Form/CustomBlockDeleteForm.php +++ /dev/null @@ -1,63 +0,0 @@ -t('Are you sure you want to delete %name?', array('%name' => $this->entity->label())); - } - - /** - * {@inheritdoc} - */ - public function getCancelRoute() { - return new Url('block.admin_display'); - } - - /** - * {@inheritdoc} - */ - public function getConfirmText() { - return $this->t('Delete'); - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, array &$form_state) { - $instances = $this->entity->getInstances(); - - $form['message'] = array( - '#markup' => format_plural(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); - } - - /** - * {@inheritdoc} - */ - public function submit(array $form, array &$form_state) { - $this->entity->delete(); - drupal_set_message($this->t('Custom block %label has been deleted.', array('%label' => $this->entity->label()))); - watchdog('custom_block', 'Custom block %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); - $form_state['redirect_route'] = new Url('custom_block.list'); - } - -} diff --git a/core/modules/block/custom_block/src/Form/CustomBlockTypeDeleteForm.php b/core/modules/block/custom_block/src/Form/CustomBlockTypeDeleteForm.php deleted file mode 100644 index c57d2ad..0000000 --- a/core/modules/block/custom_block/src/Form/CustomBlockTypeDeleteForm.php +++ /dev/null @@ -1,92 +0,0 @@ -queryFactory = $query_factory; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.query') - ); - } - - /** - * {@inheritdoc} - */ - public function getQuestion() { - return $this->t('Are you sure you want to delete %label?', array('%label' => $this->entity->label())); - } - - /** - * {@inheritdoc} - */ - public function getCancelRoute() { - return new Url('custom_block.type_list'); - } - - /** - * {@inheritdoc} - */ - public function getConfirmText() { - return $this->t('Delete'); - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, array &$form_state) { - $blocks = $this->queryFactory->get('custom_block')->condition('type', $this->entity->id())->execute(); - if (!empty($blocks)) { - $caption = '

' . format_plural(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())) . '

'; - $form['description'] = array('#markup' => $caption); - return $form; - } - else { - return parent::buildForm($form, $form_state); - } - } - - /** - * {@inheritdoc} - */ - public function submit(array $form, array &$form_state) { - $this->entity->delete(); - drupal_set_message(t('Custom block type %label has been deleted.', array('%label' => $this->entity->label()))); - watchdog('custom_block', 'Custom block type %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); - $form_state['redirect_route'] = $this->getCancelRoute(); - } - -} diff --git a/core/modules/block/custom_block/src/Plugin/Block/CustomBlockBlock.php b/core/modules/block/custom_block/src/Plugin/Block/CustomBlockBlock.php deleted file mode 100644 index 5ef3ec2..0000000 --- a/core/modules/block/custom_block/src/Plugin/Block/CustomBlockBlock.php +++ /dev/null @@ -1,164 +0,0 @@ -blockManager = $block_manager; - $this->entityManager = $entity_manager; - $this->moduleHandler = $module_handler; - $this->account = $account; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('plugin.manager.block'), - $container->get('entity.manager'), - $container->get('module_handler'), - $container->get('current_user') - ); - } - - /** - * {@inheritdoc} - */ - public function defaultConfiguration() { - return array( - 'status' => TRUE, - 'info' => '', - 'view_mode' => 'full', - // Modify the default max age for custom block blocks: modifications made - // to them will automatically invalidate corresponding cache tags, thus - // allowing us to cache custom block blocks forever. - 'cache' => array( - 'max_age' => \Drupal\Core\Cache\Cache::PERMANENT, - ), - ); - } - - /** - * Overrides \Drupal\block\BlockBase::blockForm(). - * - * Adds body and description fields to the block configuration form. - */ - public function blockForm($form, &$form_state) { - $form['custom_block']['view_mode'] = array( - '#type' => 'select', - '#options' => $this->entityManager->getViewModeOptions('custom_block'), - '#title' => t('View mode'), - '#description' => t('Output the block in this view mode.'), - '#default_value' => $this->configuration['view_mode'] - ); - $form['title']['#description'] = t('The title of the block as shown to the user.'); - return $form; - } - - /** - * Overrides \Drupal\block\BlockBase::blockSubmit(). - */ - public function blockSubmit($form, &$form_state) { - // Invalidate the block cache to update custom block-based derivatives. - if ($this->moduleHandler->moduleExists('block')) { - $this->configuration['view_mode'] = $form_state['values']['custom_block']['view_mode']; - $this->blockManager->clearCachedDefinitions(); - } - } - - /** - * {@inheritdoc} - */ - public function build() { - $uuid = $this->getDerivativeId(); - if ($block = entity_load_by_uuid('custom_block', $uuid)) { - return entity_view($block, $this->configuration['view_mode']); - } - else { - return array( - '#markup' => t('Block with uuid %uuid does not exist. Add custom block.', array( - '%uuid' => $uuid, - '!url' => url('block/add') - )), - '#access' => $this->account->hasPermission('administer blocks') - ); - } - } -} diff --git a/core/modules/block/custom_block/src/Plugin/Derivative/CustomBlock.php b/core/modules/block/custom_block/src/Plugin/Derivative/CustomBlock.php deleted file mode 100644 index f93b413..0000000 --- a/core/modules/block/custom_block/src/Plugin/Derivative/CustomBlock.php +++ /dev/null @@ -1,28 +0,0 @@ -derivatives[$custom_block->uuid()] = $base_plugin_definition; - $this->derivatives[$custom_block->uuid()]['admin_label'] = $custom_block->label(); - } - return parent::getDerivativeDefinitions($base_plugin_definition); - } -} diff --git a/core/modules/block/custom_block/src/Plugin/Menu/LocalAction/CustomBlockAddLocalAction.php b/core/modules/block/custom_block/src/Plugin/Menu/LocalAction/CustomBlockAddLocalAction.php deleted file mode 100644 index af9b359..0000000 --- a/core/modules/block/custom_block/src/Plugin/Menu/LocalAction/CustomBlockAddLocalAction.php +++ /dev/null @@ -1,39 +0,0 @@ -attributes->has('theme')) { - $options['query']['theme'] = $request->attributes->get('theme'); - } - // Adds a destination on custom block listing. - if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'custom_block.list') { - $options['query']['destination'] = 'admin/structure/block/custom-blocks'; - } - // Adds a destination on custom block listing. - if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'custom_block.list') { - $options['query']['destination'] = 'admin/structure/block/custom-blocks'; - } - return $options; - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockCacheTagsTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockCacheTagsTest.php deleted file mode 100644 index cfd87a9..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockCacheTagsTest.php +++ /dev/null @@ -1,57 +0,0 @@ - 'Llama', - 'type' => 'basic', - 'body' => array( - 'value' => 'The name "llama" was adopted by European settlers from native Peruvians.', - 'format' => 'plain_text', - ), - )); - $custom_block->save(); - - return $custom_block; - } - - /** - * {@inheritdoc} - * - * Each comment must have a comment body, which always has a text format. - */ - protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) { - return array('filter_format:plain_text'); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockCreationTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockCreationTest.php deleted file mode 100644 index 0ae892a..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockCreationTest.php +++ /dev/null @@ -1,222 +0,0 @@ - 'Custom Block creation', - 'description' => 'Create a block and test saving it.', - 'group' => 'Custom Block', - ); - } - - /** - * 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 testCustomBlockCreation() { - // Add a new view mode and verify if it is selected as expected. - $this->drupalLogin($this->drupalCreateUser(array('administer display modes'))); - $this->drupalGet('admin/structure/display-modes/view/add/custom_block'); - $edit = array( - 'id' => 'test_view_mode', - 'label' => 'Test View Mode', - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertRaw(t('Saved the %label view mode.', array('%label' => $edit['label']))); - - $this->drupalLogin($this->adminUser); - - // Create a block. - $edit = array(); - $edit['info[0][value]'] = 'Test Block'; - $edit['body[0][value]'] = $this->randomName(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.', array( - '!block' => 'Basic block', - '%name' => $edit['info[0][value]'] - )), 'Basic block created.'); - - // Change the view mode. - $view_mode['settings[custom_block][view_mode]'] = 'test_view_mode'; - $this->drupalPostForm(NULL, $view_mode, t('Save block')); - - // Go to the configure page and verify that the new view mode is correct. - $this->drupalGet('admin/structure/block/manage/testblock'); - $this->assertFieldByXPath('//select[@name="settings[custom_block][view_mode]"]/option[@selected="selected"]/@value', 'test_view_mode', 'View mode changed to Test View Mode'); - - // Test the available view mode options. - $this->assertOption('edit-settings-custom-block-view-mode', 'default', 'The default view mode is available.'); - - // Check that the block exists in the database. - $blocks = entity_load_multiple_by_properties('custom_block', array('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 block with description %name already exists.', array( - '%name' => $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 testDefaultCustomBlockCreation() { - $edit = array(); - $edit['info[0][value]'] = $this->randomName(8); - $edit['body[0][value]'] = $this->randomName(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.', array( - '!block' => 'Basic block', - '%name' => $edit['info[0][value]'], - )), 'Basic block created.'); - - // Check that the block exists in the database. - $blocks = entity_load_multiple_by_properties('custom_block', array('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->createCustomBlock('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('custom_block', 'b') - ->fields('b', array('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('custom_block', 'b') - ->fields('b', array('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 = array(); - $edit['info[0][value]'] = $this->randomName(8); - $body = $this->randomName(16); - $edit['body[0][value]'] = $body; - $this->drupalPostForm('block/add/basic', $edit, t('Save')); - - // Place the block. - $instance = array( - 'id' => drupal_strtolower($edit['info[0][value]']), - 'settings[label]' => $edit['info[0][value]'], - 'region' => 'sidebar_first', - ); - $block = entity_load('custom_block', 1); - $url = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . \Drupal::config('system.theme')->get('default'); - $this->drupalPostForm($url, $instance, t('Save block')); - - $block = CustomBlock::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(format_plural(1, 'This will also remove 1 placed block instance.', 'This will also remove @count placed block instance.')); - - $this->drupalPostForm(NULL, array(), 'Delete'); - $this->assertRaw(t('Custom block %name has been deleted.', array('%name' => $edit['info[0][value]']))); - - // Create another block and force the plugin cache to flush. - $edit2 = array(); - $edit2['info[0][value]'] = $this->randomName(8); - $body2 = $this->randomName(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 = array(); - $edit3['info[0][value]'] = $this->randomName(8); - $body = $this->randomName(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'); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockFieldTest.php deleted file mode 100644 index 5c7d46b..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockFieldTest.php +++ /dev/null @@ -1,118 +0,0 @@ - 'Custom Block field test', - 'description' => 'Test block fieldability.', - 'group' => 'Custom Block', - ); - } - - /** - * Checks block edit functionality. - */ - public function testBlockFields() { - $this->drupalLogin($this->adminUser); - - $this->blockType = $this->createCustomBlockType('link'); - - // Create a field with settings to validate. - $this->field = entity_create('field_config', array( - 'name' => drupal_strtolower($this->randomName()), - 'entity_type' => 'custom_block', - 'type' => 'link', - 'cardinality' => 2, - )); - $this->field->save(); - $this->instance = entity_create('field_instance_config', array( - 'field_name' => $this->field->getName(), - 'entity_type' => 'custom_block', - 'bundle' => 'link', - 'settings' => array( - 'title' => DRUPAL_OPTIONAL, - ), - )); - $this->instance->save(); - entity_get_form_display('custom_block', 'link', 'default') - ->setComponent($this->field->getName(), array( - 'type' => 'link_default', - )) - ->save(); - entity_get_display('custom_block', 'link', 'default') - ->setComponent($this->field->getName(), array( - 'type' => 'link', - 'label' => 'hidden', - )) - ->save(); - - // Create a block. - $this->drupalGet('block/add/link'); - $edit = array( - 'info[0][value]' => $this->randomName(8), - $this->field->getName() . '[0][url]' => 'http://example.com', - $this->field->getName() . '[0][title]' => 'Example.com' - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $block = entity_load('custom_block', 1); - $url = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . \Drupal::config('system.theme')->get('default'); - // Place the block. - $instance = array( - 'id' => drupal_strtolower($edit['info[0][value]']), - 'settings[label]' => $edit['info[0][value]'], - 'region' => 'sidebar_first', - ); - $this->drupalPostForm($url, $instance, t('Save block')); - // Navigate to home page. - $this->drupalGet(''); - $this->assertLinkByHref('http://example.com'); - $this->assertText('Example.com'); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockListTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockListTest.php deleted file mode 100644 index 8bded49..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockListTest.php +++ /dev/null @@ -1,120 +0,0 @@ - 'Custom Block listing', - 'description' => 'Tests the listing of custom blocks.', - 'group' => 'Custom Block', - ); - } - - /** - * Tests the custom block listing page. - */ - public function testListing() { - $this->drupalLogin($this->drupalCreateUser(array('administer blocks', 'translate configuration'))); - $this->drupalGet('admin/structure/block/custom-blocks'); - - // Test for the page title. - $this->assertTitle(t('Custom block library') . ' | Drupal'); - - // Test for the table. - $element = $this->xpath('//div[@class="l-content"]//table'); - $this->assertTrue($element, 'Configuration entity list table found.'); - - // Test the table header. - $elements = $this->xpath('//div[@class="l-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 = array(t('Block description'), t('Operations')); - foreach ($elements as $key => $element) { - $this->assertIdentical((string) $element[0], $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 = array(); - $edit['info[0][value]'] = $label; - $edit['body[0][value]'] = $this->randomName(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="l-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((string) $elements[0], $label); - - // Edit the entity using the operations link. - $blocks = $this->container - ->get('entity.manager') - ->getStorage('custom_block') - ->loadByProperties(array('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', array('%label' => $label)) . ' | Drupal')); - $edit = array('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 %label?', array('%label' => $new_label)) . ' | Drupal')); - $this->drupalPostForm(NULL, array(), $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.')); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockPageViewTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockPageViewTest.php deleted file mode 100644 index fafb357..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockPageViewTest.php +++ /dev/null @@ -1,47 +0,0 @@ - 'Custom Block page view', - 'description' => 'Create a block and test block access by attempting to view the block.', - 'group' => 'Custom Block', - ); - } - - /** - * Checks block edit functionality. - */ - public function testPageEdit() { - $this->drupalLogin($this->adminUser); - $block = $this->createCustomBlock(); - - // Attempt to view the block. - $this->drupalGet('custom-block/' . $block->id()); - - // Assert response was '200' and not '403 Access denied'. - $this->assertResponse('200', 'User was able the view the block'); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockRevisionsTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockRevisionsTest.php deleted file mode 100644 index 75f19aa..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockRevisionsTest.php +++ /dev/null @@ -1,104 +0,0 @@ - 'Custom Block revisions', - 'description' => 'Create a block with revisions.', - 'group' => 'Custom Block', - ); - } - - /** - * Sets the test up. - */ - protected function setUp() { - parent::setUp(); - - // Create initial block. - $block = $this->createCustomBlock('initial'); - - $blocks = array(); - $logs = array(); - - // Get original block. - $blocks[] = $block->getRevisionId(); - $logs[] = ''; - - // Create three revisions. - $revision_count = 3; - for ($i = 0; $i < $revision_count; $i++) { - $block->setNewRevision(TRUE); - $block->setRevisionLog($this->randomName(32)); - $logs[] = $block->getRevisionLog(); - $block->save(); - $blocks[] = $block->getRevisionId(); - } - - $this->blocks = $blocks; - $this->logs = $logs; - } - - /** - * Checks block revision related operations. - */ - public function testRevisions() { - $blocks = $this->blocks; - $logs = $this->logs; - - foreach ($blocks as $delta => $revision_id) { - // Confirm the correct revision text appears. - $loaded = entity_revision_load('custom_block', $revision_id); - // Verify log is the same. - $this->assertEqual($loaded->getRevisionLog(), $logs[$delta], format_string('Correct log message found for revision !revision', array( - '!revision' => $loaded->getRevisionId(), - ))); - } - - // 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->randomName(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 = entity_load('custom_block', $loaded->id()); - $this->assertTrue($loaded->getRevisionId() > $default_revision->getRevisionId(), 'Revision id is greater than default revision id.'); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockSaveTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockSaveTest.php deleted file mode 100644 index bae766a..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockSaveTest.php +++ /dev/null @@ -1,117 +0,0 @@ - 'Custom Block save', - 'description' => 'Test $custom_block->save() for saving content.', - 'group' => 'Custom Block', - ); - } - - /** - * 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 {custom_block}')->fetchField(); - $test_id = $max_id + mt_rand(1000, 1000000); - $info = $this->randomName(8); - $block_array = array( - 'info' => $info, - 'body' => array('value' => $this->randomName(32)), - 'type' => 'basic', - 'id' => $test_id - ); - $block = entity_create('custom_block', $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 = CustomBlock::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 determing changes in hook_block_presave(). - * - * Verifies the static block load cache is cleared upon save. - */ - public function testDeterminingChanges() { - // Initial creation. - $block = $this->createCustomBlock('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 custom_block_test_custom_block_presave() and - // custom_block_test_custom_block_update() determine changes and change the - // title as well as programatically 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 = CustomBlock::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_custom_block_insert() is invoked, so that the block can be saved again - * in a hook implementation without errors. - * - * @see block_test_block_insert() - */ - public function testCustomBlockSaveOnInsert() { - // custom_block_test_custom_block_insert() triggers a save on insert if the - // title equals 'new'. - $block = $this->createCustomBlock('new'); - $this->assertEqual($block->label(), 'CustomBlock ' . $block->id(), 'Custom block saved on block insert.'); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockTestBase.php b/core/modules/block/custom_block/src/Tests/CustomBlockTestBase.php deleted file mode 100644 index cf731fc..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockTestBase.php +++ /dev/null @@ -1,96 +0,0 @@ -adminUser = $this->drupalCreateUser($this->permissions); - } - - /** - * Creates a custom block. - * - * @param 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'. - * - * @return \Drupal\custom_block\Entity\CustomBlock - * Created custom block. - */ - protected function createCustomBlock($title = FALSE, $bundle = 'basic') { - $title = ($title ? : $this->randomName()); - if ($custom_block = entity_create('custom_block', array( - 'info' => $title, - 'type' => $bundle, - 'langcode' => 'en' - ))) { - $custom_block->save(); - } - return $custom_block; - } - - /** - * Creates a custom block type (bundle). - * - * @param string $label - * The block type label. - * - * @return \Drupal\custom_block\Entity\CustomBlockType - * Created custom block type. - */ - protected function createCustomBlockType($label) { - $bundle = entity_create('custom_block_type', array( - 'id' => $label, - 'label' => $label, - 'revision' => FALSE - )); - $bundle->save(); - return $bundle; - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockTranslationUITest.php b/core/modules/block/custom_block/src/Tests/CustomBlockTranslationUITest.php deleted file mode 100644 index 761936e..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockTranslationUITest.php +++ /dev/null @@ -1,140 +0,0 @@ - 'Custom Block translation UI', - 'description' => 'Tests the node translation UI.', - 'group' => 'Custom Block', - ); - } - - /** - * Overrides \Drupal\simpletest\WebTestBase::setUp(). - */ - public function setUp() { - $this->entityTypeId = 'custom_block'; - $this->bundle = 'basic'; - $this->name = drupal_strtolower($this->randomName()); - $this->testLanguageSelector = FALSE; - parent::setUp(); - } - - /** - * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getTranslatorPermission(). - */ - public function getTranslatorPermissions() { - return array_merge(parent::getTranslatorPermissions(), array( - 'translate any entity', - 'access administration pages', - 'administer blocks', - 'administer custom_block fields' - )); - } - - /** - * Creates a custom block. - * - * @param string $title - * (optional) Title of block. When no value is given uses a random name. - * Defaults to FALSE. - * @param string $bundle - * (optional) Bundle name. When no value is given, defaults to - * $this->bundle. Defaults to FALSE. - * - * @return \Drupal\custom_block\Entity\CustomBlock - * Created custom block. - */ - protected function createCustomBlock($title = FALSE, $bundle = FALSE) { - $title = ($title ? : $this->randomName()); - $bundle = ($bundle ? : $this->bundle); - $custom_block = entity_create('custom_block', array( - 'info' => $title, - 'type' => $bundle, - 'langcode' => 'en' - )); - $custom_block->save(); - return $custom_block; - } - - /** - * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues(). - */ - protected function getNewEntityValues($langcode) { - return array('info' => $this->name) + 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; - } - - /** - * 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->randomName(); - $bundle = entity_create('custom_block_type', array( - 'id' => $disabled_bundle, - 'label' => $disabled_bundle, - 'revision' => FALSE - )); - $bundle->save(); - - // Create a node for each bundle. - $enabled_custom_block = $this->createCustomBlock(); - $disabled_custom_block = $this->createCustomBlock(FALSE, $bundle->id()); - - // Make sure that only a single row was inserted into the - // {content_translation} table. - $rows = db_query('SELECT * FROM {content_translation}')->fetchAll(); - $this->assertEqual(1, count($rows)); - $this->assertEqual($enabled_custom_block->id(), reset($rows)->entity_id); - } - -} diff --git a/core/modules/block/custom_block/src/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/src/Tests/CustomBlockTypeTest.php deleted file mode 100644 index c9c9187..0000000 --- a/core/modules/block/custom_block/src/Tests/CustomBlockTypeTest.php +++ /dev/null @@ -1,213 +0,0 @@ - 'CustomBlock types', - 'description' => 'Ensures that custom block type functions work correctly.', - 'group' => 'Custom Block', - ); - } - - /** - * Tests creating a block type programmatically and via a form. - */ - public function testCustomBlockTypeCreation() { - // Create a block type programmaticaly. - $type = $this->createCustomBlockType('other'); - - $block_type = entity_load('custom_block_type', 'other'); - $this->assertTrue($block_type, 'The new block type has been created.'); - - // Login a test user. - $this->drupalLogin($this->adminUser); - - $this->drupalGet('block/add/' . $type->id()); - $this->assertResponse(200, 'The new block type can be accessed at bloack/add.'); - - // Create a block type via the user interface. - $edit = array( - 'id' => 'foo', - 'label' => 'title for foo', - ); - $this->drupalPostForm('admin/structure/block/custom-blocks/types/add', $edit, t('Save')); - $block_type = entity_load('custom_block_type', 'foo'); - $this->assertTrue($block_type, 'The new block type has been created.'); - - // Check that the block type was created in site default language. - $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->id; - $this->assertEqual($block_type->langcode, $default_langcode); - } - - /** - * Tests editing a block type using the UI. - */ - public function testCustomBlockTypeEditing() { - $this->drupalLogin($this->adminUser); - // We need two block types to prevent /block/add redirecting. - $this->createCustomBlockType('other'); - - $field_definition = \Drupal::entityManager()->getFieldDefinitions('custom_block', 'other')['body']; - $this->assertEqual($field_definition->getLabel(), 'Body', 'Body field was found.'); - - // Verify that title and body fields are displayed. - $this->drupalGet('block/add/basic'); - $this->assertRaw('Block description', 'Block info field was found.'); - $this->assertRaw('Body', 'Body field was found.'); - - // Change the block type name. - $edit = array( - 'label' => 'Bar', - ); - $this->drupalPostForm('admin/structure/block/custom-blocks/manage/basic', $edit, t('Save')); - - $this->drupalGet('block/add'); - $this->assertRaw('Bar', 'New name was displayed.'); - $this->clickLink('Bar'); - $this->assertEqual(url('block/add/basic', array('absolute' => TRUE)), $this->getUrl(), 'Original machine name was used in URL.'); - - // Remove the body field. - $this->drupalPostForm('admin/structure/block/custom-blocks/manage/basic/fields/custom_block.basic.body/delete', array(), t('Delete')); - // Resave the settings for this type. - $this->drupalPostForm('admin/structure/block/custom-blocks/manage/basic', array(), t('Save')); - // Check that the body field doesn't exist. - $this->drupalGet('block/add/basic'); - $this->assertNoRaw('Body', 'Body field was not found.'); - } - - /** - * Tests deleting a block type that still has content. - */ - public function testCustomBlockTypeDeletion() { - // Create a block type programmatically. - $type = $this->createCustomBlockType('foo'); - - $this->drupalLogin($this->adminUser); - - // Add a new block of this type. - $block = $this->createCustomBlock(FALSE, 'foo'); - // Attempt to delete the block type, which should not be allowed. - $this->drupalGet('admin/structure/block/custom-blocks/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())), - 'The block type will not be deleted until all blocks of that type are removed.' - ); - $this->assertNoText(t('This action cannot be undone.'), 'The node type deletion confirmation form is not available.'); - - // Delete the block. - $block->delete(); - // Attempt to delete the block type, which should now be allowed. - $this->drupalGet('admin/structure/block/custom-blocks/manage/' . $type->id() . '/delete'); - $this->assertRaw( - t('Are you sure you want to delete %type?', array('%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.'); - } - - /** - * Tests that redirects work as expected when multiple block types exist. - */ - public function testsCustomBlockAddTypes() { - $this->drupalLogin($this->adminUser); - // Create two block types programmatically. - $type = $this->createCustomBlockType('foo'); - $type = $this->createCustomBlockType('bar'); - - // Get the custom block storage. - $storage = $this->container - ->get('entity.manager') - ->getStorage('custom_block'); - - // Enable all themes. - theme_enable(array('bartik', 'seven')); - $themes = array('bartik', 'seven', 'stark'); - $theme_settings = $this->container->get('config.factory')->get('system.theme'); - foreach ($themes as $default_theme) { - // Change the default theme. - $theme_settings->set('default', $default_theme)->save(); - \Drupal::service('router.builder')->rebuild(); - - // For each enabled theme, go to its block page and test the redirects. - $themes = array('bartik', 'stark', 'seven'); - foreach ($themes as $theme) { - // Test that adding a block from the 'place blocks' form sends you to the - // block configure form. - $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/$theme"; - $this->drupalGet($path); - $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(url('block/add/foo', $options)); - $this->drupalGet('block/add/foo', $options); - } - else { - $this->clickLink('foo'); - } - // Create a new block. - $edit = array('info[0][value]' => $this->randomName(8)); - $this->drupalPostForm(NULL, $edit, t('Save')); - $blocks = $storage->loadByProperties(array('info' => $edit['info[0][value]'])); - if (!empty($blocks)) { - $block = reset($blocks); - $destination = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . $theme; - $this->assertUrl(url($destination, array('absolute' => TRUE))); - $this->drupalPostForm(NULL, array(), t('Save block')); - $this->assertUrl(url("admin/structure/block/list/$theme", array('absolute' => TRUE, 'query' => array('block-placement' => drupal_html_class($edit['info[0][value]']))))); - } - else { - $this->fail('Could not load created block.'); - } - } - } - - // Test that adding a block from the 'custom blocks list' doesn't send you - // to the block configure form. - $this->drupalGet('admin/structure/block/custom-blocks'); - $this->clickLink(t('Add custom block')); - $this->clickLink('foo'); - $edit = array('info[0][value]' => $this->randomName(8)); - $this->drupalPostForm(NULL, $edit, t('Save')); - $blocks = $storage->loadByProperties(array('info' => $edit['info[0][value]'])); - if (!empty($blocks)) { - $destination = 'admin/structure/block/custom-blocks'; - $this->assertUrl(url($destination, array('absolute' => TRUE))); - } - else { - $this->fail('Could not load created block.'); - } - } - -} diff --git a/core/modules/block/custom_block/src/Tests/PageEditTest.php b/core/modules/block/custom_block/src/Tests/PageEditTest.php deleted file mode 100644 index 8062fb5..0000000 --- a/core/modules/block/custom_block/src/Tests/PageEditTest.php +++ /dev/null @@ -1,77 +0,0 @@ - 'Custom Block edit', - 'description' => 'Create a block and test block edit functionality.', - 'group' => 'Custom 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 = array(); - $edit['info[0][value]'] = drupal_strtolower($this->randomName(8)); - $edit[$body_key] = $this->randomName(16); - $this->drupalPostForm('block/add/basic', $edit, t('Save')); - - // Check that the block exists in the database. - $blocks = \Drupal::entityQuery('custom_block')->condition('info', $edit['info[0][value]'])->execute(); - $block = entity_load('custom_block', 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 = array(); - $edit[$title_key] = $this->randomName(8); - $edit[$body_key] = $this->randomName(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 = array(); - $edit['info[0][value]'] = $this->randomName(8); - $edit[$body_key] = $this->randomName(16); - $edit['revision'] = TRUE; - $this->drupalPostForm(NULL, $edit, t('Save')); - - // Ensure that the block revision has been created. - $revised_block = entity_load('custom_block', $block->id(), TRUE); - $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 !label?', array('!label' => $revised_block->label()))); - } - -} diff --git a/core/modules/block/custom_block/templates/custom-block-add-list.html.twig b/core/modules/block/custom_block/templates/custom-block-add-list.html.twig deleted file mode 100644 index d2af8e8..0000000 --- a/core/modules/block/custom_block/templates/custom-block-add-list.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{# -/** - * @file - * Default theme implementation to present a list of custom block types. - * - * Available variables: - * - types: A collection of all the available custom block types. - * Each block type contains the following: - * - link: A link to add a block of this type. - * - description: A description of this custom block type. - * - * @see template_preprocess_custom_block_add_list() - * - * @ingroup themeable - */ -#} -{% spaceless %} -
- {% for type in types %} -
{{ type.link }}
-
{{ type.description }}
- {% endfor %} -
-{% endspaceless %} diff --git a/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.info.yml b/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.info.yml deleted file mode 100644 index 747efa4..0000000 --- a/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.info.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: "Custom Block module tests" -type: module -description: "Support module for custom block related testing." -package: Testing -version: VERSION -core: 8.x diff --git a/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.module b/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.module deleted file mode 100644 index 65e9c56..0000000 --- a/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.module +++ /dev/null @@ -1,68 +0,0 @@ - 'Yowser', - ); -} - -/** - * Implements hook_custom_block_presave(). - */ -function custom_block_test_custom_block_presave(CustomBlock $custom_block) { - if ($custom_block->label() == 'testing_custom_block_presave') { - $custom_block->setInfo($custom_block->label() .'_presave'); - } - // Determine changes. - if (!empty($custom_block->original) && $custom_block->original->label() == 'test_changes') { - if ($custom_block->original->label() != $custom_block->label()) { - $custom_block->setInfo($custom_block->label() .'_presave'); - // Drupal 1.0 release. - $custom_block->changed = 979534800; - } - } -} - -/** - * Implements hook_custom_block_update(). - */ -function custom_block_test_custom_block_update(CustomBlock $custom_block) { - // Determine changes on update. - if (!empty($custom_block->original) && $custom_block->original->label() == 'test_changes') { - if ($custom_block->original->label() != $custom_block->label()) { - $custom_block->setInfo($custom_block->label() .'_update'); - } - } -} - -/** - * Implements hook_custom_block_insert(). - * - * This tests saving a custom_block on custom_block insert. - * - * @see \Drupal\custom_block\Tests\CustomBlockSaveTest::testCustomBlockSaveOnInsert() - */ -function custom_block_test_custom_block_insert(CustomBlock $custom_block) { - // Set the custom_block title to the custom_block ID and save. - if ($custom_block->label() == 'new') { - $custom_block->setInfo('CustomBlock ' . $custom_block->id()); - $custom_block->save(); - } - if ($custom_block->label() == 'fail_creation') { - throw new Exception('Test exception for rollback.'); - } -} diff --git a/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.routing.yml b/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.routing.yml deleted file mode 100644 index a7ca068..0000000 --- a/core/modules/block/custom_block/tests/modules/custom_block_test/custom_block_test.routing.yml +++ /dev/null @@ -1,6 +0,0 @@ -custom_block_test.custom_block_view: - path: '/custom-block/{custom_block}' - defaults: - _entity_view: 'custom_block' - requirements: - _entity_access: 'custom_block.view' diff --git a/core/modules/block/custom_block/tests/src/Menu/CustomBlockLocalTasksTest.php b/core/modules/block/custom_block/tests/src/Menu/CustomBlockLocalTasksTest.php deleted file mode 100644 index d04ad15..0000000 --- a/core/modules/block/custom_block/tests/src/Menu/CustomBlockLocalTasksTest.php +++ /dev/null @@ -1,64 +0,0 @@ - 'Custom Block local tasks test', - 'description' => 'Test custom_block local tasks.', - 'group' => 'Block', - ); - } - - public function setUp() { - $this->directoryList = array( - 'block' => 'core/modules/block', - 'custom_block' => 'core/modules/block/custom_block', - ); - parent::setUp(); - } - - /** - * Checks custom_block listing local tasks. - * - * @dataProvider getCustomBlockListingRoutes - */ - public function testCustomBlockListLocalTasks($route) { - // - $this->assertLocalTasks($route, array( - 0 => array( - 'block.admin_display', - 'custom_block.list', - ), - 1 => array( - 'custom_block.list_sub', - 'custom_block.type_list', - ) - )); - } - - /** - * Provides a list of routes to test. - */ - public function getCustomBlockListingRoutes() { - return array( - array('custom_block.list', 'custom_block.type_list'), - ); - } - -} diff --git a/core/modules/block_content/block_content.contextual_links.yml b/core/modules/block_content/block_content.contextual_links.yml new file mode 100644 index 0000000..4751e6c --- /dev/null +++ b/core/modules/block_content/block_content.contextual_links.yml @@ -0,0 +1,10 @@ +block_content.block_edit: + title: 'Edit' + group: block_content + route_name: 'block_content.edit' + +block_content.block_delete: + title: 'Delete' + group: block_content + route_name: 'block_content.delete' + weight: 1 diff --git a/core/modules/block_content/block_content.info.yml b/core/modules/block_content/block_content.info.yml new file mode 100644 index 0000000..e1ee81f --- /dev/null +++ b/core/modules/block_content/block_content.info.yml @@ -0,0 +1,10 @@ +name: 'Block Content' +type: module +description: 'Allows the creation of custom blocks through the user interface.' +package: Core +version: VERSION +core: 8.x +dependencies: + - block + - text +configure: block_content.list diff --git a/core/modules/block_content/block_content.install b/core/modules/block_content/block_content.install new file mode 100644 index 0000000..29ef0bb --- /dev/null +++ b/core/modules/block_content/block_content.install @@ -0,0 +1,125 @@ + 'Stores contents of custom-made blocks.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => "The block's {block_content}.id.", + ), + 'uuid' => array( + 'description' => 'Unique Key: Universally unique identifier for this entity.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), + 'info' => array( + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'Block description.', + ), + // Defaults to NULL in order to avoid a brief period of potential + // deadlocks on the index. + 'revision_id' => array( + 'description' => 'The current {block_custom_revision}.revision_id version identifier.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => NULL, + ), + 'type' => array( + 'description' => 'The type of this custom block.', + 'type' => 'varchar', + 'length' => EntityTypeInterface::BUNDLE_MAX_LENGTH, + 'not null' => TRUE, + 'default' => '', + ), + 'changed' => array( + 'description' => 'The Unix timestamp when the custom block was most recently saved.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of this node.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('id'), + 'indexes' => array( + 'block_custom_type' => array('type'), + ), + 'unique keys' => array( + 'revision_id' => array('revision_id'), + 'uuid' => array('uuid'), + 'info' => array('info'), + ), + 'foreign keys' => array( + 'block_content_revision' => array( + 'table' => 'block_content_revision', + 'columns' => array('revision_id' => 'revision_id'), + ), + ), + ); + + $schema['block_content_revision'] = array( + 'description' => 'Stores contents of custom-made blocks.', + 'fields' => array( + 'id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => "The block's {block_content}.id.", + ), + // Defaults to NULL in order to avoid a brief period of potential + // deadlocks on the index. + 'revision_id' => array( + 'description' => 'The current version identifier.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'log' => array( + 'description' => 'The log entry explaining the changes in this version.', + 'type' => 'text', + 'not null' => TRUE, + 'size' => 'big', + ), + 'info' => array( + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'Block description.', + ), + 'changed' => array( + 'description' => 'The Unix timestamp when the version was most recently saved.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('revision_id'), + ); + return $schema; +} diff --git a/core/modules/block_content/block_content.libraries.yml b/core/modules/block_content/block_content.libraries.yml new file mode 100644 index 0000000..5a1b5b6 --- /dev/null +++ b/core/modules/block_content/block_content.libraries.yml @@ -0,0 +1,8 @@ +drupal.block_content: + version: VERSION + js: + js/block_content.js: {} + dependencies: + - core/jquery + - core/drupal + - core/drupal.form diff --git a/core/modules/block_content/block_content.local_actions.yml b/core/modules/block_content/block_content.local_actions.yml new file mode 100644 index 0000000..735e374 --- /dev/null +++ b/core/modules/block_content/block_content.local_actions.yml @@ -0,0 +1,14 @@ +block_content_type_add: + route_name: block_content.type_add + title: 'Add custom block type' + appears_on: + - block_content.type_list + +block_content_add_action: + route_name: block_content.add_page + title: 'Add custom block' + appears_on: + - block.admin_display + - block.admin_display_theme + - block_content.list + class: \Drupal\block_content\Plugin\Menu\LocalAction\BlockContentAddLocalAction diff --git a/core/modules/block_content/block_content.local_tasks.yml b/core/modules/block_content/block_content.local_tasks.yml new file mode 100644 index 0000000..0674c99 --- /dev/null +++ b/core/modules/block_content/block_content.local_tasks.yml @@ -0,0 +1,27 @@ +block_content.list: + title: 'Custom block library' + route_name: block_content.list + base_route: block.admin_display +block_content.list_sub: + title: Blocks + route_name: block_content.list + parent_id: block_content.list +block_content.type_list: + title: Types + route_name: block_content.type_list + parent_id: block_content.list + +block_content.edit: + title: Edit + route_name: block_content.edit + base_route: block_content.edit +block_content.delete: + title: Delete + route_name: block_content.delete + base_route: block_content.edit + +# Default tab for custom block type editing. +block_content.type_edit: + title: 'Edit' + route_name: block_content.type_edit + base_route: block_content.type_edit diff --git a/core/modules/block_content/block_content.module b/core/modules/block_content/block_content.module new file mode 100644 index 0000000..95086c9 --- /dev/null +++ b/core/modules/block_content/block_content.module @@ -0,0 +1,117 @@ +' . t('About') . ''; + $output .= '

' . t('The Custom Block module allows you to create blocks of content, which can be placed in regions throughout the website. Custom blocks can have fields; see the Field module help for more information. Once created, custom blocks can be placed like blocks provided by other modules; see the Block module help page for details. For more information, see the online documentation for the Custom Block module.', array('!block-content' => \Drupal::url('block_content.list'), '!field-help' => \Drupal::url('help.page', array('name' => 'field')), '!blocks' => \Drupal::url('help.page', array('name' => 'block')), '!online-help' => 'https://drupal.org/documentation/modules/block_content')) . '

'; + $output .= '

' . t('Uses') . '

'; + $output .= '
'; + $output .= '
' . t('Creating and managing custom block types') . '
'; + $output .= '
' . t('Users with the Administer blocks permission can create different custom block types, each with different fields and display settings, from the Custom block types page. The Custom block types page lists all of your created custom block types, and allows you to edit and manage them. For more information about managing fields and display settings, see the Field UI module help.', array('!types' => \Drupal::url('block_content.type_list'), '!field-ui' => \Drupal::url('help.page', array('name' => 'field_ui')))) . '
'; + $output .= '
' . t('Creating custom blocks') . '
'; + $output .= '
' . t('Users with the Administer blocks permission can add custom blocks of each of their defined custom block types. Created custom blocks are then listed on the Blocks administration page.', array('!blocks' => \Drupal::url('block.admin_display'), '!block-add' => \Drupal::url('block_content.add_page'))) . '
'; + $output .= '
'; + return $output; + + case 'block_content.list': + $output = '

' . t('This page lists user-created blocks. These blocks are derived from block types. A block type can consist of different fields and display settings. From the block types tab you can manage these fields as well as create new block types.') . '

'; + return $output; + + case 'block_content.type_list': + $output = '

' . t('This page lists block types. A block type can consist of different fields and display settings. From here you can manage these fields as well as create new block types.') . '

'; + return $output; + + } +} + +/** + * Implements hook_theme(). + */ +function block_content_theme($existing, $type, $theme, $path) { + return array( + 'block_content_add_list' => array( + 'variables' => array('content' => NULL), + 'file' => 'block_content.pages.inc', + 'template' => 'block-content-add-list', + ), + ); +} + +/** + * Implements hook_entity_type_alter(). + */ +function block_content_entity_type_alter(array &$entity_types) { + /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */ + // Add a translation handler for fields if the language module is enabled. + if (\Drupal::moduleHandler()->moduleExists('language')) { + $translation = $entity_types['block_content']->get('translation'); + $translation['block_content'] = TRUE; + $entity_types['block_content']->set('translation', $translation); + } +} + +/** + * Adds the default body field to a custom block type. + * + * @param string $block_type_id + * Id of the block type. + * @param string $label + * (optional) The label for the body instance. Defaults to 'Body' + * + * @return array() + * Body field instance. + */ +function block_content_add_body_field($block_type_id, $label = 'Body') { + // Add or remove the body field, as needed. + $field = FieldConfig::loadByName('block_content', 'body'); + $instance = FieldInstanceConfig::loadByName('block_content', $block_type_id, 'body'); + if (empty($field)) { + $field = entity_create('field_config', array( + 'name' => 'body', + 'entity_type' => 'block_content', + 'type' => 'text_with_summary', + )); + $field->save(); + } + if (empty($instance)) { + $instance = entity_create('field_instance_config', array( + 'field_name' => 'body', + 'entity_type' => 'block_content', + 'bundle' => $block_type_id, + 'label' => $label, + 'settings' => array('display_summary' => FALSE), + )); + $instance->save(); + + // Assign widget settings for the 'default' form mode. + entity_get_form_display('block_content', $block_type_id, 'default') + ->setComponent('body', array( + '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( + 'label' => 'hidden', + 'type' => 'text_default', + )) + ->save(); + } + + return $instance; +} diff --git a/core/modules/block_content/block_content.pages.inc b/core/modules/block_content/block_content.pages.inc new file mode 100644 index 0000000..d2dc0c4 --- /dev/null +++ b/core/modules/block_content/block_content.pages.inc @@ -0,0 +1,37 @@ +query->all(); + foreach ($variables['content'] as $type) { + $variables['types'][$type->id()] = array( + 'link' => \Drupal::l($type->label(), 'block_content.add_form', array('block_content_type' => $type->id()), array('query' => $query)), + 'description' => Xss::filterAdmin($type->description), + 'title' => $type->label(), + 'localized_options' => array( + 'query' => $query, + ), + ); + } +} diff --git a/core/modules/block_content/block_content.routing.yml b/core/modules/block_content/block_content.routing.yml new file mode 100644 index 0000000..b6a1aaf --- /dev/null +++ b/core/modules/block_content/block_content.routing.yml @@ -0,0 +1,80 @@ +block_content.type_list: + path: '/admin/structure/block/block-content/types' + defaults: + _entity_list: 'block_content_type' + _title: 'Edit' + requirements: + _permission: 'administer blocks' + +block_content.add_page: + path: '/block/add' + defaults: + _content: '\Drupal\block_content\Controller\BlockContentController::add' + _title: 'Add custom block' + options: + _admin_route: TRUE + requirements: + _permission: 'administer blocks' + +block_content.add_form: + path: '/block/add/{block_content_type}' + defaults: + _content: '\Drupal\block_content\Controller\BlockContentController::addForm' + _title_callback: 'Drupal\block_content\Controller\BlockContentController::getAddFormTitle' + options: + _admin_route: TRUE + requirements: + _permission: 'administer blocks' + +block_content.type_delete: + path: '/admin/structure/block/block-content/manage/{block_content_type}/delete' + defaults: + _entity_form: 'block_content_type.delete' + _title: 'Delete' + requirements: + _entity_access: 'block_content_type.delete' + options: + _admin_route: TRUE + +block_content.edit: + path: '/block/{block_content}' + defaults: + _entity_form: 'block_content.edit' + options: + _admin_route: TRUE + requirements: + _entity_access: 'block_content.update' + +block_content.delete: + path: '/block/{block_content}/delete' + defaults: + _entity_form: 'block_content.delete' + _title: 'Delete' + options: + _admin_route: TRUE + requirements: + _entity_access: 'block_content.delete' + +block_content.type_add: + path: '/admin/structure/block/block-content/types/add' + defaults: + _entity_form: 'block_content_type.add' + _title: 'Add' + requirements: + _permission: 'administer blocks' + +block_content.type_edit: + path: '/admin/structure/block/block-content/manage/{block_content_type}' + defaults: + _entity_form: 'block_content_type.edit' + _title: 'Edit' + requirements: + _entity_access: 'block_content_type.update' + +block_content.list: + path: '/admin/structure/block/block-content' + defaults: + _title: 'Custom block library' + _entity_list: 'block_content' + requirements: + _permission: 'administer blocks' diff --git a/core/modules/block_content/config/install/block_content.type.basic.yml b/core/modules/block_content/config/install/block_content.type.basic.yml new file mode 100644 index 0000000..02982e4 --- /dev/null +++ b/core/modules/block_content/config/install/block_content.type.basic.yml @@ -0,0 +1,5 @@ +id: basic +label: 'Basic block' +revision: 0 +description: 'A basic block contains a title and a body.' +langcode: en diff --git a/core/modules/block_content/config/install/entity.view_mode.block_content.full.yml b/core/modules/block_content/config/install/entity.view_mode.block_content.full.yml new file mode 100644 index 0000000..c558d54 --- /dev/null +++ b/core/modules/block_content/config/install/entity.view_mode.block_content.full.yml @@ -0,0 +1,8 @@ +id: block_content.full +label: Full +status: false +cache: true +targetEntityType: block_content +dependencies: + module: + - block_content diff --git a/core/modules/block_content/config/schema/block_content.schema.yml b/core/modules/block_content/config/schema/block_content.schema.yml new file mode 100644 index 0000000..d87edfc --- /dev/null +++ b/core/modules/block_content/config/schema/block_content.schema.yml @@ -0,0 +1,27 @@ +# Schema for the configuration files of the Custom Block module. + +block_content.type.*: + type: mapping + label: 'Custom block type settings' + mapping: + id: + type: string + label: 'Machine-readable name' + uuid: + type: string + label: 'UUID' + label: + type: label + label: 'Label' + revision: + type: integer + label: 'Create new revision' + description: + type: text + label: 'Description' + status: + type: boolean + label: 'Status' + langcode: + type: string + label: 'Default language' diff --git a/core/modules/block_content/js/block_content.js b/core/modules/block_content/js/block_content.js new file mode 100644 index 0000000..45e4583 --- /dev/null +++ b/core/modules/block_content/js/block_content.js @@ -0,0 +1,46 @@ +/** + * @file + * Defines Javascript behaviors for the block_content module. + */ + +(function ($) { + + "use strict"; + + Drupal.behaviors.blockContentDetailsSummaries = { + attach: function (context) { + var $context = $(context); + $context.find('.block-content-form-revision-information').drupalSetSummary(function (context) { + var $context = $(context); + var revisionCheckbox = $context.find('.form-item-revision input'); + + // Return 'New revision' if the 'Create new revision' checkbox is checked, + // or if the checkbox doesn't exist, but the revision log does. For users + // without the "Administer content" permission the checkbox won't appear, + // but the revision log will if the content type is set to auto-revision. + if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $context.find('.form-item-log textarea').length)) { + return Drupal.t('New revision'); + } + + return Drupal.t('No revision'); + }); + + $context.find('fieldset.block-content-translation-options').drupalSetSummary(function (context) { + var $context = $(context); + var translate; + var $checkbox = $context.find('.form-item-translation-translate input'); + + if ($checkbox.size()) { + translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated'); + } + else { + $checkbox = $context.find('.form-item-translation-retranslate input'); + translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated'); + } + + return translate; + }); + } + }; + +})(jQuery); diff --git a/core/modules/block_content/src/BlockContentAccessController.php b/core/modules/block_content/src/BlockContentAccessController.php new file mode 100644 index 0000000..5709498 --- /dev/null +++ b/core/modules/block_content/src/BlockContentAccessController.php @@ -0,0 +1,29 @@ +blockContentStorage = $block_content_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'), + $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 = entity_load('block_content_type', $block->bundle()); + if (!$block->isNew()) { + $block->setRevisionLog(NULL); + } + // Always use the default revision setting. + $block->setNewRevision($block_type->revision); + } + + /** + * {@inheritdoc} + */ + public function form(array $form, array &$form_state) { + $block = $this->entity; + $account = $this->currentUser(); + + if ($this->operation == 'edit') { + $form['#title'] = $this->t('Edit custom block %label', array('%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] = drupal_html_class('block-' . $block->bundle() . '-form'); + + if ($this->moduleHandler->moduleExists('language')) { + $language_configuration = language_get_default_configuration('block_content', $block->bundle()); + + // Set the correct default language. + if ($block->isNew()) { + $language_default = $this->languageManager->getCurrentLanguage($language_configuration['langcode']); + $block->langcode->value = $language_default->id; + } + } + + $form['langcode'] = array( + '#title' => $this->t('Language'), + '#type' => 'language_select', + '#default_value' => $block->getUntranslated()->language()->id, + '#languages' => Language::STATE_ALL, + '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'], + ); + + $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="log"]' => array('empty' => FALSE), + ), + ); + } + + $form['revision_information']['log'] = array( + '#type' => 'textarea', + '#title' => $this->t('Revision log message'), + '#rows' => 4, + '#default_value' => $block->getRevisionLog(), + '#description' => $this->t('Briefly desribe the changes you have made.'), + ); + + return parent::form($form, $form_state, $block); + } + + /** + * Overrides \Drupal\Core\Entity\EntityForm::submit(). + * + * Updates the custom block object by processing the submitted values. + * + * This function can be called by a "Next" button of a wizard to update the + * form state's entity with the current step's values before proceeding to the + * next step. + */ + public function submit(array $form, array &$form_state) { + // Build the block object from the submitted values. + $block = parent::submit($form, $form_state); + + // Save as a new revision if requested to do so. + if (!empty($form_state['values']['revision'])) { + $block->setNewRevision(); + } + + return $block; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, array &$form_state) { + $block = $this->entity; + $insert = $block->isNew(); + $block->save(); + $watchdog_args = array('@type' => $block->bundle(), '%info' => $block->label()); + $block_type = entity_load('block_content_type', $block->bundle()); + $t_args = array('@type' => $block_type->label(), '%info' => $block->label()); + + if ($insert) { + watchdog('content', '@type: added %info.', $watchdog_args, WATCHDOG_NOTICE); + drupal_set_message($this->t('@type %info has been created.', $t_args)); + } + else { + watchdog('content', '@type: updated %info.', $watchdog_args, WATCHDOG_NOTICE); + drupal_set_message($this->t('@type %info has been updated.', $t_args)); + } + + if ($block->id()) { + $form_state['values']['id'] = $block->id(); + $form_state['id'] = $block->id(); + if ($insert) { + if (!$theme = $block->getTheme()) { + $theme = $this->config('system.theme')->get('default'); + } + $form_state['redirect_route'] = array( + 'route_name' => 'block.admin_add', + 'route_parameters' => array( + 'plugin_id' => 'block_content:' . $block->uuid(), + 'theme' => $theme, + ), + ); + } + else { + $form_state['redirect_route']['route_name'] = 'block_content.list'; + } + } + else { + // In the unlikely case something went wrong on save, the block will be + // rebuilt and block form redisplayed. + drupal_set_message($this->t('The block could not be saved.'), 'error'); + $form_state['rebuild'] = TRUE; + } + + // Clear the page and block caches. + Cache::invalidateTags(array('content' => TRUE)); + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + if ($this->entity->isNew()) { + $exists = $this->blockContentStorage->loadByProperties(array('info' => $form_state['values']['info'])); + if (!empty($exists)) { + $this->setFormError('info', $form_state, $this->t('A block with description %name already exists.', array( + '%name' => $form_state['values']['info'][0]['value'], + ))); + } + } + } + +} diff --git a/core/modules/block_content/src/BlockContentInterface.php b/core/modules/block_content/src/BlockContentInterface.php new file mode 100644 index 0000000..29ef69f --- /dev/null +++ b/core/modules/block_content/src/BlockContentInterface.php @@ -0,0 +1,83 @@ +getLabel($entity); + return $row + parent::buildRow($entity); + } + + /** + * {@inheritdoc} + */ + public function getDefaultOperations(EntityInterface $entity) { + $operations = parent::getDefaultOperations($entity); + if (isset($operations['edit'])) { + $operations['edit']['query']['destination'] = 'admin/structure/block/block-content'; + } + return $operations; + } + +} diff --git a/core/modules/block_content/src/BlockContentTranslationHandler.php b/core/modules/block_content/src/BlockContentTranslationHandler.php new file mode 100644 index 0000000..148e249 --- /dev/null +++ b/core/modules/block_content/src/BlockContentTranslationHandler.php @@ -0,0 +1,43 @@ + 'additional_settings', + '#weight' => 100, + '#attributes' => array( + 'class' => array('block-content-translation-options'), + ), + ); + } + } + + /** + * {@inheritdoc} + */ + protected function entityFormTitle(EntityInterface $entity) { + $block_type = entity_load('block_content_type', $entity->bundle()); + return t('Edit @type @title', array('@type' => $block_type->label(), '@title' => $entity->label())); + } + +} diff --git a/core/modules/block_content/src/BlockContentTypeForm.php b/core/modules/block_content/src/BlockContentTypeForm.php new file mode 100644 index 0000000..e64bfa3 --- /dev/null +++ b/core/modules/block_content/src/BlockContentTypeForm.php @@ -0,0 +1,107 @@ +entity; + + $form['label'] = array( + '#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( + '#type' => 'machine_name', + '#default_value' => $block_type->id(), + '#machine_name' => array( + 'exists' => '\Drupal\block_content\Entity\BlockContentType::load', + ), + '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH, + '#disabled' => !$block_type->isNew(), + ); + + $form['description'] = array( + '#type' => 'textarea', + '#default_value' => $block_type->description, + '#description' => t('Enter a description for this block type.'), + '#title' => t('Description'), + ); + + $form['revision'] = array( + '#type' => 'checkbox', + '#title' => t('Create new revision'), + '#default_value' => $block_type->revision, + '#description' => t('Create a new revision by default for this block type.') + ); + + if ($this->moduleHandler->moduleExists('content_translation')) { + $form['language'] = array( + '#type' => 'details', + '#title' => t('Language settings'), + '#group' => 'additional_settings', + ); + + $language_configuration = language_get_default_configuration('block_content', $block_type->id()); + $form['language']['language_configuration'] = array( + '#type' => 'language_configuration', + '#entity_information' => array( + '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( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; + } + + /** + * Overrides \Drupal\Core\Entity\EntityForm::save(). + */ + public function save(array $form, array &$form_state) { + $block_type = $this->entity; + $status = $block_type->save(); + + $edit_link = \Drupal::linkGenerator()->generateFromUrl($this->t('Edit'), $this->entity->urlInfo()); + if ($status == SAVED_UPDATED) { + drupal_set_message(t('Custom block type %label has been updated.', array('%label' => $block_type->label()))); + watchdog('block_content', 'Custom block type %label has been updated.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, $edit_link); + } + else { + drupal_set_message(t('Custom block type %label has been added.', array('%label' => $block_type->label()))); + watchdog('block_content', 'Custom block type %label has been added.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, $edit_link); + } + + $form_state['redirect_route']['route_name'] = 'block_content.type_list'; + } + +} diff --git a/core/modules/block_content/src/BlockContentTypeInterface.php b/core/modules/block_content/src/BlockContentTypeInterface.php new file mode 100644 index 0000000..cb21631 --- /dev/null +++ b/core/modules/block_content/src/BlockContentTypeInterface.php @@ -0,0 +1,17 @@ +generateFromUrl($entity->label(), $entity->urlInfo()); + $row['description'] = Xss::filterAdmin($entity->description); + return $row + parent::buildRow($entity); + } + + /** + * {@inheritdoc} + */ + protected function getTitle() { + return $this->t('Custom block types'); + } + +} diff --git a/core/modules/block_content/src/BlockContentViewBuilder.php b/core/modules/block_content/src/BlockContentViewBuilder.php new file mode 100644 index 0000000..0977e9f --- /dev/null +++ b/core/modules/block_content/src/BlockContentViewBuilder.php @@ -0,0 +1,33 @@ +isNew() && $view_mode == 'full') { + $build['#contextual_links']['block_content'] = array( + 'route_parameters' => array('block_content' => $entity->id()), + 'metadata' => array('changed' => $entity->getChangedTime()), + ); + } + } + +} diff --git a/core/modules/block_content/src/Controller/BlockContentController.php b/core/modules/block_content/src/Controller/BlockContentController.php new file mode 100644 index 0000000..4716bba --- /dev/null +++ b/core/modules/block_content/src/Controller/BlockContentController.php @@ -0,0 +1,115 @@ +get('entity.manager'); + return new static( + $entity_manager->getStorage('block_content'), + $entity_manager->getStorage('block_content_type') + ); + } + + /** + * Constructs a BlockContent object. + * + * @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. + */ + public function __construct(EntityStorageInterface $block_content_storage, EntityStorageInterface $block_content_type_storage) { + $this->blockContentStorage = $block_content_storage; + $this->blockContentTypeStorage = $block_content_type_storage; + } + + /** + * Displays add custom block links for available types. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The current request object. + * + * @return array + * A render array for a list of the custom block types that can be added or + * if there is only one custom block type defined for the site, the function + * returns the custom block add page for that custom block type. + */ + public function add(Request $request) { + $types = $this->blockContentTypeStorage->loadMultiple(); + if ($types && count($types) == 1) { + $type = reset($types); + return $this->addForm($type, $request); + } + + return array('#theme' => 'block_content_add_list', '#content' => $types); + } + + /** + * Presents the custom block creation form. + * + * @param \Drupal\block_content\BlockContentTypeInterface $block_content_type + * The custom block type to add. + * @param \Symfony\Component\HttpFoundation\Request $request + * The current request object. + * + * @return array + * A form array as expected by drupal_render(). + */ + public function addForm(BlockContentTypeInterface $block_content_type, Request $request) { + $block = $this->blockContentStorage->create(array( + 'type' => $block_content_type->id() + )); + if (($theme = $request->query->get('theme')) && in_array($theme, array_keys(list_themes()))) { + // 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 + // newly created block in the given theme. + $block->setTheme($theme); + } + return $this->entityFormBuilder()->getForm($block); + } + + /** + * Provides the page title for this controller. + * + * @param \Drupal\block_content\BlockContentTypeInterface $block_content_type + * The custom block type being added. + * + * @return string + * The page title. + */ + public function getAddFormTitle(BlockContentTypeInterface $block_content_type) { + return $this->t('Add %type custom block', array('%type' => $block_content_type->label())); + } + +} diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php new file mode 100644 index 0000000..d85baef --- /dev/null +++ b/core/modules/block_content/src/Entity/BlockContent.php @@ -0,0 +1,232 @@ +revision_id->value = NULL; + $duplicate->id->value = NULL; + return $duplicate; + } + + /** + * {@inheritdoc} + */ + public function setTheme($theme) { + $this->theme = $theme; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getTheme() { + return $this->theme; + } + + /** + * {@inheritdoc} + */ + public function postSave(EntityStorageInterface $storage, $update = TRUE) { + parent::postSave($storage, $update); + + // Invalidate the block cache to update custom block-based derivatives. + \Drupal::service('plugin.manager.block')->clearCachedDefinitions(); + } + + /** + * {@inheritdoc} + */ + public function getInstances() { + return entity_load_multiple_by_properties('block', array('plugin' => 'block_content:' . $this->uuid())); + } + + /** + * {@inheritdoc} + */ + public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) { + parent::preSaveRevision($storage, $record); + + if ($this->isNewRevision()) { + // When inserting either a new custom block or a new block_content + // revision, $entity->log must be set because {block_custom_revision}.log + // is a text column and therefore cannot have a default value. However, + // it might not be set at this point (for example, if the user submitting + // the form does not have permission to create revisions), so we ensure + // that it is at least an empty string in that case. + // @todo: Make the {block_custom_revision}.log column nullable so that we + // can remove this check. + if (!isset($record->log)) { + $record->log = ''; + } + } + elseif (isset($this->original) && (!isset($record->log) || $record->log === '')) { + // If we are updating an existing block_content without adding a new + // revision and the user did not supply a log, keep the existing one. + $record->log = $this->original->getRevisionLog(); + } + } + + /** + * {@inheritdoc} + */ + public function delete() { + foreach ($this->getInstances() as $instance) { + $instance->delete(); + } + parent::delete(); + } + + /** + * {@inheritdoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields['id'] = FieldDefinition::create('integer') + ->setLabel(t('Custom block ID')) + ->setDescription(t('The custom block ID.')) + ->setReadOnly(TRUE) + ->setSetting('unsigned', TRUE); + + $fields['uuid'] = FieldDefinition::create('uuid') + ->setLabel(t('UUID')) + ->setDescription(t('The custom block UUID.')) + ->setReadOnly(TRUE); + + $fields['revision_id'] = FieldDefinition::create('integer') + ->setLabel(t('Revision ID')) + ->setDescription(t('The revision ID.')) + ->setReadOnly(TRUE) + ->setSetting('unsigned', TRUE); + + $fields['langcode'] = FieldDefinition::create('language') + ->setLabel(t('Language code')) + ->setDescription(t('The custom block language code.')); + + $fields['info'] = FieldDefinition::create('string') + ->setLabel(t('Block description')) + ->setDescription(t('A brief description of your block.')) + ->setRevisionable(TRUE) + ->setRequired(TRUE) + ->setDisplayOptions('form', array( + 'type' => 'string', + 'weight' => -5, + )) + ->setDisplayConfigurable('form', TRUE); + + $fields['type'] = FieldDefinition::create('entity_reference') + ->setLabel(t('Block type')) + ->setDescription(t('The block type.')) + ->setSetting('target_type', 'block_content_type') + ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH); + + $fields['log'] = FieldDefinition::create('string') + ->setLabel(t('Revision log message')) + ->setDescription(t('The revision log message.')) + ->setRevisionable(TRUE); + + $fields['changed'] = FieldDefinition::create('changed') + ->setLabel(t('Changed')) + ->setDescription(t('The time that the custom block was last edited.')) + ->setRevisionable(TRUE); + + return $fields; + } + + /** + * {@inheritdoc} + */ + public function getChangedTime() { + return $this->get('changed')->value; + } + + /** + * {@inheritdoc} + */ + public function getRevisionLog() { + return $this->get('log')->value; + } + + /** + * {@inheritdoc} + */ + public function setInfo($info) { + $this->set('info', $info); + return $this; + } + + /** + * {@inheritdoc} + */ + public function setRevisionLog($log) { + $this->set('log', $log); + return $this; + } + +} diff --git a/core/modules/block_content/src/Entity/BlockContentType.php b/core/modules/block_content/src/Entity/BlockContentType.php new file mode 100644 index 0000000..17a358e --- /dev/null +++ b/core/modules/block_content/src/Entity/BlockContentType.php @@ -0,0 +1,101 @@ +isSyncing()) { + entity_invoke_bundle_hook('create', 'block_content', $this->id()); + if (!$this->isSyncing()) { + block_content_add_body_field($this->id); + } + } + elseif ($this->getOriginalId() != $this->id) { + entity_invoke_bundle_hook('rename', 'block_content', $this->getOriginalId(), $this->id); + } + } + + /** + * {@inheritdoc} + */ + public static function postDelete(EntityStorageInterface $storage, array $entities) { + parent::postDelete($storage, $entities); + + foreach ($entities as $entity) { + entity_invoke_bundle_hook('delete', 'block_content', $entity->id()); + } + } + +} diff --git a/core/modules/block_content/src/Form/BlockContentDeleteForm.php b/core/modules/block_content/src/Form/BlockContentDeleteForm.php new file mode 100644 index 0000000..35c0386 --- /dev/null +++ b/core/modules/block_content/src/Form/BlockContentDeleteForm.php @@ -0,0 +1,63 @@ +t('Are you sure you want to delete %name?', array('%name' => $this->entity->label())); + } + + /** + * {@inheritdoc} + */ + public function getCancelRoute() { + return new Url('block.admin_display'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $instances = $this->entity->getInstances(); + + $form['message'] = array( + '#markup' => format_plural(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); + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, array &$form_state) { + $this->entity->delete(); + drupal_set_message($this->t('Custom block %label has been deleted.', array('%label' => $this->entity->label()))); + watchdog('block_content', 'Custom block %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); + $form_state['redirect_route'] = new Url('block_content.list'); + } + +} diff --git a/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php b/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php new file mode 100644 index 0000000..7e196ee --- /dev/null +++ b/core/modules/block_content/src/Form/BlockContentTypeDeleteForm.php @@ -0,0 +1,92 @@ +queryFactory = $query_factory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity.query') + ); + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->t('Are you sure you want to delete %label?', array('%label' => $this->entity->label())); + } + + /** + * {@inheritdoc} + */ + public function getCancelRoute() { + return new Url('block_content.type_list'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $blocks = $this->queryFactory->get('block_content')->condition('type', $this->entity->id())->execute(); + if (!empty($blocks)) { + $caption = '

' . format_plural(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())) . '

'; + $form['description'] = array('#markup' => $caption); + return $form; + } + else { + return parent::buildForm($form, $form_state); + } + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, array &$form_state) { + $this->entity->delete(); + drupal_set_message(t('Custom block type %label has been deleted.', array('%label' => $this->entity->label()))); + watchdog('block_content', 'Custom block type %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); + $form_state['redirect_route'] = $this->getCancelRoute(); + } + +} diff --git a/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php new file mode 100644 index 0000000..9f3d92d --- /dev/null +++ b/core/modules/block_content/src/Plugin/Block/BlockContentBlock.php @@ -0,0 +1,164 @@ +blockManager = $block_manager; + $this->entityManager = $entity_manager; + $this->moduleHandler = $module_handler; + $this->account = $account; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('plugin.manager.block'), + $container->get('entity.manager'), + $container->get('module_handler'), + $container->get('current_user') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return array( + 'status' => TRUE, + 'info' => '', + 'view_mode' => 'full', + // Modify the default max age for custom block blocks: modifications made + // to them will automatically invalidate corresponding cache tags, thus + // allowing us to cache custom block blocks forever. + 'cache' => array( + 'max_age' => \Drupal\Core\Cache\Cache::PERMANENT, + ), + ); + } + + /** + * Overrides \Drupal\block\BlockBase::blockForm(). + * + * Adds body and description fields to the block configuration form. + */ + public function blockForm($form, &$form_state) { + $form['block_content']['view_mode'] = array( + '#type' => 'select', + '#options' => $this->entityManager->getViewModeOptions('block_content'), + '#title' => t('View mode'), + '#description' => t('Output the block in this view mode.'), + '#default_value' => $this->configuration['view_mode'] + ); + $form['title']['#description'] = t('The title of the block as shown to the user.'); + return $form; + } + + /** + * Overrides \Drupal\block\BlockBase::blockSubmit(). + */ + public function blockSubmit($form, &$form_state) { + // Invalidate the block cache to update custom block-based derivatives. + if ($this->moduleHandler->moduleExists('block')) { + $this->configuration['view_mode'] = $form_state['values']['block_content']['view_mode']; + $this->blockManager->clearCachedDefinitions(); + } + } + + /** + * {@inheritdoc} + */ + public function build() { + $uuid = $this->getDerivativeId(); + if ($block = entity_load_by_uuid('block_content', $uuid)) { + return entity_view($block, $this->configuration['view_mode']); + } + else { + return array( + '#markup' => t('Block with uuid %uuid does not exist. Add custom block.', array( + '%uuid' => $uuid, + '!url' => url('block/add') + )), + '#access' => $this->account->hasPermission('administer blocks') + ); + } + } +} diff --git a/core/modules/block_content/src/Plugin/Derivative/BlockContent.php b/core/modules/block_content/src/Plugin/Derivative/BlockContent.php new file mode 100644 index 0000000..a7c1784 --- /dev/null +++ b/core/modules/block_content/src/Plugin/Derivative/BlockContent.php @@ -0,0 +1,28 @@ +derivatives[$block_content->uuid()] = $base_plugin_definition; + $this->derivatives[$block_content->uuid()]['admin_label'] = $block_content->label(); + } + return parent::getDerivativeDefinitions($base_plugin_definition); + } +} diff --git a/core/modules/block_content/src/Plugin/Menu/LocalAction/BlockContentAddLocalAction.php b/core/modules/block_content/src/Plugin/Menu/LocalAction/BlockContentAddLocalAction.php new file mode 100644 index 0000000..e22425e --- /dev/null +++ b/core/modules/block_content/src/Plugin/Menu/LocalAction/BlockContentAddLocalAction.php @@ -0,0 +1,39 @@ +attributes->has('theme')) { + $options['query']['theme'] = $request->attributes->get('theme'); + } + // Adds a destination on custom block listing. + if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'block_content.list') { + $options['query']['destination'] = 'admin/structure/block/block-content'; + } + // Adds a destination on custom block listing. + if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'block_content.list') { + $options['query']['destination'] = 'admin/structure/block/block-content'; + } + return $options; + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php b/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php new file mode 100644 index 0000000..52c3286 --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentCacheTagsTest.php @@ -0,0 +1,57 @@ + 'Llama', + 'type' => 'basic', + 'body' => array( + 'value' => 'The name "llama" was adopted by European settlers from native Peruvians.', + 'format' => 'plain_text', + ), + )); + $block_content->save(); + + return $block_content; + } + + /** + * {@inheritdoc} + * + * Each comment must have a comment body, which always has a text format. + */ + protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) { + return array('filter_format:plain_text'); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentCreationTest.php b/core/modules/block_content/src/Tests/BlockContentCreationTest.php new file mode 100644 index 0000000..dd98507 --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentCreationTest.php @@ -0,0 +1,222 @@ + 'Custom Block creation', + 'description' => 'Create a block and test saving it.', + 'group' => 'Custom Block', + ); + } + + /** + * 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() { + // Add a new view mode and verify if it is selected as expected. + $this->drupalLogin($this->drupalCreateUser(array('administer display modes'))); + $this->drupalGet('admin/structure/display-modes/view/add/block_content'); + $edit = array( + 'id' => 'test_view_mode', + 'label' => 'Test View Mode', + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertRaw(t('Saved the %label view mode.', array('%label' => $edit['label']))); + + $this->drupalLogin($this->adminUser); + + // Create a block. + $edit = array(); + $edit['info[0][value]'] = 'Test Block'; + $edit['body[0][value]'] = $this->randomName(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.', array( + '!block' => 'Basic block', + '%name' => $edit['info[0][value]'] + )), 'Basic block created.'); + + // Change the view mode. + $view_mode['settings[block_content][view_mode]'] = 'test_view_mode'; + $this->drupalPostForm(NULL, $view_mode, t('Save block')); + + // Go to the configure page and verify that the new view mode is correct. + $this->drupalGet('admin/structure/block/manage/testblock'); + $this->assertFieldByXPath('//select[@name="settings[block_content][view_mode]"]/option[@selected="selected"]/@value', 'test_view_mode', 'View mode changed to Test View Mode'); + + // Test the available view mode options. + $this->assertOption('edit-settings-block-content-view-mode', 'default', 'The default view mode is available.'); + + // Check that the block exists in the database. + $blocks = entity_load_multiple_by_properties('block_content', array('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 block with description %name already exists.', array( + '%name' => $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 = array(); + $edit['info[0][value]'] = $this->randomName(8); + $edit['body[0][value]'] = $this->randomName(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.', array( + '!block' => 'Basic block', + '%name' => $edit['info[0][value]'], + )), 'Basic block created.'); + + // Check that the block exists in the database. + $blocks = entity_load_multiple_by_properties('block_content', array('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', 'b') + ->fields('b', array('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', 'b') + ->fields('b', array('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 = array(); + $edit['info[0][value]'] = $this->randomName(8); + $body = $this->randomName(16); + $edit['body[0][value]'] = $body; + $this->drupalPostForm('block/add/basic', $edit, t('Save')); + + // Place the block. + $instance = array( + 'id' => drupal_strtolower($edit['info[0][value]']), + 'settings[label]' => $edit['info[0][value]'], + 'region' => 'sidebar_first', + ); + $block = entity_load('block_content', 1); + $url = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . \Drupal::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(format_plural(1, 'This will also remove 1 placed block instance.', 'This will also remove @count placed block instance.')); + + $this->drupalPostForm(NULL, array(), 'Delete'); + $this->assertRaw(t('Custom block %name has been deleted.', array('%name' => $edit['info[0][value]']))); + + // Create another block and force the plugin cache to flush. + $edit2 = array(); + $edit2['info[0][value]'] = $this->randomName(8); + $body2 = $this->randomName(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 = array(); + $edit3['info[0][value]'] = $this->randomName(8); + $body = $this->randomName(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'); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentFieldTest.php b/core/modules/block_content/src/Tests/BlockContentFieldTest.php new file mode 100644 index 0000000..f32a1ea --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentFieldTest.php @@ -0,0 +1,118 @@ + 'Custom Block field test', + 'description' => 'Test block fieldability.', + 'group' => 'Custom Block', + ); + } + + /** + * Checks block edit functionality. + */ + public function testBlockFields() { + $this->drupalLogin($this->adminUser); + + $this->blockType = $this->createBlockContentType('link'); + + // Create a field with settings to validate. + $this->field = entity_create('field_config', array( + 'name' => drupal_strtolower($this->randomName()), + 'entity_type' => 'block_content', + 'type' => 'link', + 'cardinality' => 2, + )); + $this->field->save(); + $this->instance = entity_create('field_instance_config', array( + 'field_name' => $this->field->getName(), + 'entity_type' => 'block_content', + 'bundle' => 'link', + 'settings' => array( + 'title' => DRUPAL_OPTIONAL, + ), + )); + $this->instance->save(); + entity_get_form_display('block_content', 'link', 'default') + ->setComponent($this->field->getName(), array( + 'type' => 'link_default', + )) + ->save(); + entity_get_display('block_content', 'link', 'default') + ->setComponent($this->field->getName(), array( + 'type' => 'link', + 'label' => 'hidden', + )) + ->save(); + + // Create a block. + $this->drupalGet('block/add/link'); + $edit = array( + 'info[0][value]' => $this->randomName(8), + $this->field->getName() . '[0][url]' => 'http://example.com', + $this->field->getName() . '[0][title]' => 'Example.com' + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + $block = entity_load('block_content', 1); + $url = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . \Drupal::config('system.theme')->get('default'); + // Place the block. + $instance = array( + 'id' => drupal_strtolower($edit['info[0][value]']), + 'settings[label]' => $edit['info[0][value]'], + 'region' => 'sidebar_first', + ); + $this->drupalPostForm($url, $instance, t('Save block')); + // Navigate to home page. + $this->drupalGet(''); + $this->assertLinkByHref('http://example.com'); + $this->assertText('Example.com'); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentListTest.php b/core/modules/block_content/src/Tests/BlockContentListTest.php new file mode 100644 index 0000000..048fdfb --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentListTest.php @@ -0,0 +1,120 @@ + 'Custom Block listing', + 'description' => 'Tests the listing of custom blocks.', + 'group' => 'Custom Block', + ); + } + + /** + * Tests the custom block listing page. + */ + public function testListing() { + $this->drupalLogin($this->drupalCreateUser(array('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="l-content"]//table'); + $this->assertTrue($element, 'Configuration entity list table found.'); + + // Test the table header. + $elements = $this->xpath('//div[@class="l-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 = array(t('Block description'), t('Operations')); + foreach ($elements as $key => $element) { + $this->assertIdentical((string) $element[0], $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 = array(); + $edit['info[0][value]'] = $label; + $edit['body[0][value]'] = $this->randomName(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="l-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((string) $elements[0], $label); + + // Edit the entity using the operations link. + $blocks = $this->container + ->get('entity.manager') + ->getStorage('block_content') + ->loadByProperties(array('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', array('%label' => $label)) . ' | Drupal')); + $edit = array('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 %label?', array('%label' => $new_label)) . ' | Drupal')); + $this->drupalPostForm(NULL, array(), $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.')); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentPageViewTest.php b/core/modules/block_content/src/Tests/BlockContentPageViewTest.php new file mode 100644 index 0000000..b8edb11 --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentPageViewTest.php @@ -0,0 +1,47 @@ + 'Custom Block page view', + 'description' => 'Create a block and test block access by attempting to view the block.', + 'group' => 'Custom Block', + ); + } + + /** + * Checks block edit 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'); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentRevisionsTest.php b/core/modules/block_content/src/Tests/BlockContentRevisionsTest.php new file mode 100644 index 0000000..ca05a73 --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentRevisionsTest.php @@ -0,0 +1,104 @@ + 'Custom Block revisions', + 'description' => 'Create a block with revisions.', + 'group' => 'Custom Block', + ); + } + + /** + * Sets the test up. + */ + protected function setUp() { + parent::setUp(); + + // Create initial block. + $block = $this->createBlockContent('initial'); + + $blocks = array(); + $logs = array(); + + // Get original block. + $blocks[] = $block->getRevisionId(); + $logs[] = ''; + + // Create three revisions. + $revision_count = 3; + for ($i = 0; $i < $revision_count; $i++) { + $block->setNewRevision(TRUE); + $block->setRevisionLog($this->randomName(32)); + $logs[] = $block->getRevisionLog(); + $block->save(); + $blocks[] = $block->getRevisionId(); + } + + $this->blocks = $blocks; + $this->logs = $logs; + } + + /** + * Checks block revision related operations. + */ + public function testRevisions() { + $blocks = $this->blocks; + $logs = $this->logs; + + foreach ($blocks as $delta => $revision_id) { + // Confirm the correct revision text appears. + $loaded = entity_revision_load('block_content', $revision_id); + // Verify log is the same. + $this->assertEqual($loaded->getRevisionLog(), $logs[$delta], format_string('Correct log message found for revision !revision', array( + '!revision' => $loaded->getRevisionId(), + ))); + } + + // 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->randomName(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 = entity_load('block_content', $loaded->id()); + $this->assertTrue($loaded->getRevisionId() > $default_revision->getRevisionId(), 'Revision id is greater than default revision id.'); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentSaveTest.php b/core/modules/block_content/src/Tests/BlockContentSaveTest.php new file mode 100644 index 0000000..03d0857 --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentSaveTest.php @@ -0,0 +1,117 @@ + 'Custom Block save', + 'description' => 'Test $block_content->save() for saving content.', + 'group' => 'Custom Block', + ); + } + + /** + * 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->randomName(8); + $block_array = array( + 'info' => $info, + 'body' => array('value' => $this->randomName(32)), + 'type' => 'basic', + 'id' => $test_id + ); + $block = entity_create('block_content', $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 determing 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 programatically 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.'); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentTestBase.php b/core/modules/block_content/src/Tests/BlockContentTestBase.php new file mode 100644 index 0000000..4f77de4 --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentTestBase.php @@ -0,0 +1,96 @@ +adminUser = $this->drupalCreateUser($this->permissions); + } + + /** + * Creates a custom block. + * + * @param 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'. + * + * @return \Drupal\block_content\Entity\BlockContent + * Created custom block. + */ + protected function createBlockContent($title = FALSE, $bundle = 'basic') { + $title = ($title ? : $this->randomName()); + if ($block_content = entity_create('block_content', array( + 'info' => $title, + 'type' => $bundle, + 'langcode' => 'en' + ))) { + $block_content->save(); + } + return $block_content; + } + + /** + * Creates a custom block type (bundle). + * + * @param string $label + * The block type label. + * + * @return \Drupal\block_content\Entity\BlockContentType + * Created custom block type. + */ + protected function createBlockContentType($label) { + $bundle = entity_create('block_content_type', array( + 'id' => $label, + 'label' => $label, + 'revision' => FALSE + )); + $bundle->save(); + return $bundle; + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php b/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php new file mode 100644 index 0000000..35cf5ec --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentTranslationUITest.php @@ -0,0 +1,140 @@ + 'Custom Block translation UI', + 'description' => 'Tests the node translation UI.', + 'group' => 'Custom Block', + ); + } + + /** + * Overrides \Drupal\simpletest\WebTestBase::setUp(). + */ + public function setUp() { + $this->entityTypeId = 'block_content'; + $this->bundle = 'basic'; + $this->name = drupal_strtolower($this->randomName()); + $this->testLanguageSelector = FALSE; + parent::setUp(); + } + + /** + * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getTranslatorPermission(). + */ + public function getTranslatorPermissions() { + return array_merge(parent::getTranslatorPermissions(), array( + 'translate any entity', + 'access administration pages', + 'administer blocks', + 'administer block_content fields' + )); + } + + /** + * Creates a custom block. + * + * @param string $title + * (optional) Title of block. When no value is given uses a random name. + * Defaults to FALSE. + * @param 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->randomName()); + $bundle = ($bundle ? : $this->bundle); + $block_content = entity_create('block_content', array( + 'info' => $title, + 'type' => $bundle, + 'langcode' => 'en' + )); + $block_content->save(); + return $block_content; + } + + /** + * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues(). + */ + protected function getNewEntityValues($langcode) { + return array('info' => $this->name) + 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; + } + + /** + * 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->randomName(); + $bundle = entity_create('block_content_type', array( + 'id' => $disabled_bundle, + 'label' => $disabled_bundle, + 'revision' => FALSE + )); + $bundle->save(); + + // Create a node 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 + // {content_translation} table. + $rows = db_query('SELECT * FROM {content_translation}')->fetchAll(); + $this->assertEqual(1, count($rows)); + $this->assertEqual($enabled_block_content->id(), reset($rows)->entity_id); + } + +} diff --git a/core/modules/block_content/src/Tests/BlockContentTypeTest.php b/core/modules/block_content/src/Tests/BlockContentTypeTest.php new file mode 100644 index 0000000..fc20f0c --- /dev/null +++ b/core/modules/block_content/src/Tests/BlockContentTypeTest.php @@ -0,0 +1,214 @@ + 'Custom Block types', + 'description' => 'Ensures that custom block type functions work correctly.', + 'group' => 'Custom Block', + ); + } + + /** + * Tests creating a block type programmatically and via a form. + */ + public function testBlockContentTypeCreation() { + // Create a block type programmaticaly. + $type = $this->createBlockContentType('other'); + + $block_type = entity_load('block_content_type', 'other'); + $this->assertTrue($block_type, 'The new block type has been created.'); + + // Login a test user. + $this->drupalLogin($this->adminUser); + + $this->drupalGet('block/add/' . $type->id()); + $this->assertResponse(200, 'The new block type can be accessed at bloack/add.'); + + // Create a block type via the user interface. + $edit = array( + 'id' => 'foo', + 'label' => 'title for foo', + ); + $this->drupalPostForm('admin/structure/block/block-content/types/add', $edit, t('Save')); + $block_type = entity_load('block_content_type', 'foo'); + $this->assertTrue($block_type, 'The new block type has been created.'); + + // Check that the block type was created in site default language. + $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->id; + $this->assertEqual($block_type->langcode, $default_langcode); + } + + /** + * Tests editing a block type using the UI. + */ + public function testBlockContentTypeEditing() { + $this->drupalLogin($this->adminUser); + // We need two block types to prevent /block/add redirecting. + $this->createBlockContentType('other'); + + $field_definition = \Drupal::entityManager()->getFieldDefinitions('block_content', 'other')['body']; + $this->assertEqual($field_definition->getLabel(), 'Body', 'Body field was found.'); + + // Verify that title and body fields are displayed. + $this->drupalGet('block/add/basic'); + $this->assertRaw('Block description', 'Block info field was found.'); + $this->assertRaw('Body', 'Body field was found.'); + + // Change the block type name. + $edit = array( + 'label' => 'Bar', + ); + $this->drupalPostForm('admin/structure/block/block-content/manage/basic', $edit, t('Save')); + \Drupal::entityManager()->clearCachedFieldDefinitions(); + + $this->drupalGet('block/add'); + $this->assertRaw('Bar', 'New name was displayed.'); + $this->clickLink('Bar'); + $this->assertEqual(url('block/add/basic', array('absolute' => TRUE)), $this->getUrl(), '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')); + // Resave the settings for this type. + $this->drupalPostForm('admin/structure/block/block-content/manage/basic', array(), t('Save')); + // Check that the body field doesn't exist. + $this->drupalGet('block/add/basic'); + $this->assertNoRaw('Body', 'Body field was not found.'); + } + + /** + * Tests deleting a block type that still has content. + */ + public function testBlockContentTypeDeletion() { + // Create a block type programmatically. + $type = $this->createBlockContentType('foo'); + + $this->drupalLogin($this->adminUser); + + // Add a new block of this type. + $block = $this->createBlockContent(FALSE, 'foo'); + // 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())), + 'The block type will not be deleted until all blocks of that type are removed.' + ); + $this->assertNoText(t('This action cannot be undone.'), 'The node type deletion confirmation form is not available.'); + + // Delete the block. + $block->delete(); + // 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 %type?', array('%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.'); + } + + /** + * Tests that redirects work as expected when multiple block types exist. + */ + public function testsBlockContentAddTypes() { + $this->drupalLogin($this->adminUser); + // Create two block types programmatically. + $type = $this->createBlockContentType('foo'); + $type = $this->createBlockContentType('bar'); + + // Get the custom block storage. + $storage = $this->container + ->get('entity.manager') + ->getStorage('block_content'); + + // Enable all themes. + theme_enable(array('bartik', 'seven')); + $themes = array('bartik', 'seven', 'stark'); + $theme_settings = $this->container->get('config.factory')->get('system.theme'); + foreach ($themes as $default_theme) { + // Change the default theme. + $theme_settings->set('default', $default_theme)->save(); + \Drupal::service('router.builder')->rebuild(); + + // For each enabled theme, go to its block page and test the redirects. + $themes = array('bartik', 'stark', 'seven'); + foreach ($themes as $theme) { + // Test that adding a block from the 'place blocks' form sends you to the + // block configure form. + $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/$theme"; + $this->drupalGet($path); + $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(url('block/add/foo', $options)); + $this->drupalGet('block/add/foo', $options); + } + else { + $this->clickLink('foo'); + } + // Create a new block. + $edit = array('info[0][value]' => $this->randomName(8)); + $this->drupalPostForm(NULL, $edit, t('Save')); + $blocks = $storage->loadByProperties(array('info' => $edit['info[0][value]'])); + if (!empty($blocks)) { + $block = reset($blocks); + $destination = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . $theme; + $this->assertUrl(url($destination, array('absolute' => TRUE))); + $this->drupalPostForm(NULL, array(), t('Save block')); + $this->assertUrl(url("admin/structure/block/list/$theme", array('absolute' => TRUE, 'query' => array('block-placement' => drupal_html_class($edit['info[0][value]']))))); + } + else { + $this->fail('Could not load created block.'); + } + } + } + + // Test that adding a block from the 'custom blocks list' doesn't send you + // to the block configure form. + $this->drupalGet('admin/structure/block/block-content'); + $this->clickLink(t('Add custom block')); + $this->clickLink('foo'); + $edit = array('info[0][value]' => $this->randomName(8)); + $this->drupalPostForm(NULL, $edit, t('Save')); + $blocks = $storage->loadByProperties(array('info' => $edit['info[0][value]'])); + if (!empty($blocks)) { + $destination = 'admin/structure/block/block-content'; + $this->assertUrl(url($destination, array('absolute' => TRUE))); + } + else { + $this->fail('Could not load created block.'); + } + } + +} diff --git a/core/modules/block_content/src/Tests/PageEditTest.php b/core/modules/block_content/src/Tests/PageEditTest.php new file mode 100644 index 0000000..3c35125 --- /dev/null +++ b/core/modules/block_content/src/Tests/PageEditTest.php @@ -0,0 +1,77 @@ + 'Custom Block edit', + 'description' => 'Create a block and test block edit functionality.', + 'group' => 'Custom 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 = array(); + $edit['info[0][value]'] = drupal_strtolower($this->randomName(8)); + $edit[$body_key] = $this->randomName(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 = entity_load('block_content', 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 = array(); + $edit[$title_key] = $this->randomName(8); + $edit[$body_key] = $this->randomName(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 = array(); + $edit['info[0][value]'] = $this->randomName(8); + $edit[$body_key] = $this->randomName(16); + $edit['revision'] = TRUE; + $this->drupalPostForm(NULL, $edit, t('Save')); + + // Ensure that the block revision has been created. + $revised_block = entity_load('block_content', $block->id(), TRUE); + $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 !label?', array('!label' => $revised_block->label()))); + } + +} diff --git a/core/modules/block_content/templates/block-content-add-list.html.twig b/core/modules/block_content/templates/block-content-add-list.html.twig new file mode 100644 index 0000000..e5a5d97 --- /dev/null +++ b/core/modules/block_content/templates/block-content-add-list.html.twig @@ -0,0 +1,24 @@ +{# +/** + * @file + * Default theme implementation to present a list of custom block types. + * + * Available variables: + * - types: A collection of all the available custom block types. + * Each block type contains the following: + * - link: A link to add a block of this type. + * - description: A description of this custom block type. + * + * @see template_preprocess_block_content_add_list() + * + * @ingroup themeable + */ +#} +{% spaceless %} +
+ {% for type in types %} +
{{ type.link }}
+
{{ type.description }}
+ {% endfor %} +
+{% endspaceless %} diff --git a/core/modules/block_content/tests/modules/block_content_test/block_content_test.info.yml b/core/modules/block_content/tests/modules/block_content_test/block_content_test.info.yml new file mode 100644 index 0000000..747efa4 --- /dev/null +++ b/core/modules/block_content/tests/modules/block_content_test/block_content_test.info.yml @@ -0,0 +1,6 @@ +name: "Custom Block module tests" +type: module +description: "Support module for custom block related testing." +package: Testing +version: VERSION +core: 8.x diff --git a/core/modules/block_content/tests/modules/block_content_test/block_content_test.module b/core/modules/block_content/tests/modules/block_content_test/block_content_test.module new file mode 100644 index 0000000..d714cb2 --- /dev/null +++ b/core/modules/block_content/tests/modules/block_content_test/block_content_test.module @@ -0,0 +1,68 @@ + 'Yowser', + ); +} + +/** + * Implements hook_block_content_presave(). + */ +function block_content_test_block_content_presave(BlockContent $block_content) { + if ($block_content->label() == 'testing_block_content_presave') { + $block_content->setInfo($block_content->label() .'_presave'); + } + // Determine changes. + if (!empty($block_content->original) && $block_content->original->label() == 'test_changes') { + if ($block_content->original->label() != $block_content->label()) { + $block_content->setInfo($block_content->label() .'_presave'); + // Drupal 1.0 release. + $block_content->changed = 979534800; + } + } +} + +/** + * Implements hook_block_content_update(). + */ +function block_content_test_block_content_update(BlockContent $block_content) { + // Determine changes on update. + if (!empty($block_content->original) && $block_content->original->label() == 'test_changes') { + if ($block_content->original->label() != $block_content->label()) { + $block_content->setInfo($block_content->label() .'_update'); + } + } +} + +/** + * Implements hook_block_content_insert(). + * + * This tests saving a block_content on block_content insert. + * + * @see \Drupal\block_content\Tests\BlockContentSaveTest::testBlockContentSaveOnInsert() + */ +function block_content_test_block_content_insert(BlockContent $block_content) { + // Set the block_content title to the block_content ID and save. + if ($block_content->label() == 'new') { + $block_content->setInfo('BlockContent ' . $block_content->id()); + $block_content->save(); + } + if ($block_content->label() == 'fail_creation') { + throw new Exception('Test exception for rollback.'); + } +} diff --git a/core/modules/block_content/tests/modules/block_content_test/block_content_test.routing.yml b/core/modules/block_content/tests/modules/block_content_test/block_content_test.routing.yml new file mode 100644 index 0000000..c25abf9 --- /dev/null +++ b/core/modules/block_content/tests/modules/block_content_test/block_content_test.routing.yml @@ -0,0 +1,6 @@ +block_content_test.block_content_view: + path: '/block-content/{block_content}' + defaults: + _entity_view: 'block_content' + requirements: + _entity_access: 'block_content.view' diff --git a/core/modules/block_content/tests/src/Menu/BlockContentLocalTasksTest.php b/core/modules/block_content/tests/src/Menu/BlockContentLocalTasksTest.php new file mode 100644 index 0000000..c989278 --- /dev/null +++ b/core/modules/block_content/tests/src/Menu/BlockContentLocalTasksTest.php @@ -0,0 +1,94 @@ + 'Custom Block local tasks test', + 'description' => 'Test block_content local tasks.', + 'group' => 'Block', + ); + } + + public function setUp() { + $this->directoryList = array( + 'block' => 'core/modules/block', + 'block_content' => 'core/modules/block_content', + ); + parent::setUp(); + + $config_factory = $this->getConfigFactoryStub(array('system.theme' => array( + 'default' => 'test_c', + ))); + + $themes = array(); + $themes['test_a'] = (object) array( + 'status' => 0, + ); + $themes['test_b'] = (object) array( + 'status' => 1, + 'info' => array( + 'name' => 'test_b', + ), + ); + $themes['test_c'] = (object) array( + 'status' => 1, + 'info' => array( + 'name' => 'test_c', + ), + ); + $theme_handler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface'); + $theme_handler->expects($this->any()) + ->method('listInfo') + ->will($this->returnValue($themes)); + + $container = new ContainerBuilder(); + $container->set('config.factory', $config_factory); + $container->set('theme_handler', $theme_handler); + \Drupal::setContainer($container); + } + + /** + * Checks block_content listing local tasks. + * + * @dataProvider getBlockContentListingRoutes + */ + public function testBlockContentListLocalTasks($route) { + $this->assertLocalTasks($route, array( + 0 => array( + 'block.admin_display', + 'block_content.list', + ), + 1 => array( + 'block_content.list_sub', + 'block_content.type_list', + ), + )); + } + + /** + * Provides a list of routes to test. + */ + public function getBlockContentListingRoutes() { + return array( + array('block_content.list', 'block_content.type_list'), + ); + } + +} diff --git a/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php b/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php index acb5646..116275b 100644 --- a/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php +++ b/core/modules/config_translation/src/Tests/ConfigTranslationListUiTest.php @@ -27,7 +27,7 @@ class ConfigTranslationListUiTest extends WebTestBase { 'block', 'config_translation', 'contact', - 'custom_block', + 'block_content', 'field', 'field_ui', 'menu_ui', @@ -62,7 +62,7 @@ public function setUp() { 'administer blocks', 'administer contact forms', 'administer content types', - 'administer custom_block fields', + 'administer block_content fields', 'administer filters', 'administer menu', 'administer node fields', @@ -187,20 +187,20 @@ protected function doVocabularyListTest() { /** * Tests the custom block listing for the translate operation. */ - public function doCustomBlockTypeListTest() { + public function doCustomContentTypeListTest() { // Create a test custom block type to decouple looking for translate // operations link so this does not test more than necessary. - $custom_block_type = entity_create('custom_block_type', array( + $block_content_type = entity_create('block_content_type', array( 'id' => Unicode::strtolower($this->randomName(16)), 'label' => $this->randomName(), 'revision' => FALSE )); - $custom_block_type->save(); + $block_content_type->save(); // Get the custom block type listing. - $this->drupalGet('admin/structure/block/custom-blocks/types'); + $this->drupalGet('admin/structure/block/block-content/types'); - $translate_link = 'admin/structure/block/custom-blocks/manage/' . $custom_block_type->id() . '/translate'; + $translate_link = 'admin/structure/block/block-content/manage/' . $block_content_type->id() . '/translate'; // Test if the link to translate the custom block type is on the page. $this->assertLinkByHref($translate_link); @@ -404,8 +404,8 @@ public function doFieldListTest() { 'field' => 'node.' . $content_type->id() . '.body', ), array( - 'list' => 'admin/structure/block/custom-blocks/manage/basic/fields', - 'field' => 'custom_block.basic.body', + 'list' => 'admin/structure/block/block-content/manage/basic/fields', + 'field' => 'block_content.basic.body', ), ); @@ -466,7 +466,7 @@ public function testTranslateOperationInListUi() { $this->doBlockListTest(); $this->doMenuListTest(); $this->doVocabularyListTest(); - $this->doCustomBlockTypeListTest(); + $this->doCustomContentTypeListTest(); $this->doContactFormsListTest(); $this->doContentTypeListTest(); $this->doFormatsListTest(); diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_custom_block.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_custom_block.yml index 709d1ea..c7dd4ab 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_custom_block.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_custom_block.yml @@ -14,7 +14,7 @@ process: source: format 'body.value': body destination: - plugin: entity:custom_block + plugin: entity:block_content migration_dependencies: required: - d6_filter_format diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/BlockPluginId.php b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/BlockPluginId.php index 3f205b2..663b9e6 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/BlockPluginId.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/process/d6/BlockPluginId.php @@ -32,14 +32,14 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI /** * @var \Drupal\Core\Entity\EntityStorageInterface */ - protected $customBlockStorage; + protected $blockContentStorage; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, array $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, MigratePluginManager $process_plugin_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->customBlockStorage = $storage; + $this->blockContentStorage = $storage; $this->migration = $migration; $this->processPluginManager = $process_plugin_manager; } @@ -54,7 +54,7 @@ public static function create(ContainerInterface $container, array $configuratio $plugin_id, $plugin_definition, $migration, - $entity_manager->getDefinition('custom_block') ? $entity_manager->getStorage('custom_block') : NULL, + $entity_manager->getDefinition('block_content') ? $entity_manager->getStorage('block_content') : NULL, $container->get('plugin.manager.migrate.process') ); } @@ -80,11 +80,11 @@ public function transform($value, MigrateExecutable $migrate_executable, Row $ro $value = "system_menu_block:$delta"; break; case 'block': - if ($this->customBlockStorage) { + if ($this->blockContentStorage) { $block_ids = $this->processPluginManager ->createInstance('migration', array('migration' => 'd6_custom_block'), $this->migration) ->transform($delta, $migrate_executable, $row, $destination_property); - $value = 'custom_block:' . $this->customBlockStorage->load($block_ids[0])->uuid(); + $value = 'block_content:' . $this->blockContentStorage->load($block_ids[0])->uuid(); } else { throw new MigrateSkipRowException(); diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockContentTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockContentTest.php new file mode 100644 index 0000000..4c78605 --- /dev/null +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockContentTest.php @@ -0,0 +1,75 @@ + 'Migrate custom blocks.', + 'description' => 'Upgrade custom blocks.', + 'group' => 'Migrate Drupal', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + $this->prepareIdMappings(array( + 'd6_filter_format' => array( + array(array(2), array('full_html')) + ) + )); + /** @var \Drupal\migrate\entity\Migration $migration */ + $migration = entity_load('migration', 'd6_custom_block'); + $dumps = array( + $this->getDumpDirectory() . '/Drupal6Box.php', + ); + $this->prepare($migration, $dumps); + $executable = new MigrateExecutable($migration, $this); + $executable->import(); + } + + /** + * Tests the Drupal 6 custom block to Drupal 8 migration. + */ + public function testBlockMigration() { + /** @var BlockContent $block */ + $block = entity_load('block_content', 1); + $this->assertEqual('My block 1', $block->label()); + $this->assertEqual(1, $block->getRevisionId()); + $this->assertTrue(REQUEST_TIME <= $block->getChangedTime() && $block->getChangedTime() <= time()); + $this->assertEqual(Language::LANGCODE_NOT_SPECIFIED, $block->language()->id); + $this->assertEqual('

My first custom block body

', $block->body->value); + $this->assertEqual('full_html', $block->body->format); + + $block = entity_load('block_content', 2); + $this->assertEqual('My block 2', $block->label()); + $this->assertEqual(2, $block->getRevisionId()); + $this->assertTrue(REQUEST_TIME <= $block->getChangedTime() && $block->getChangedTime() <= time()); + $this->assertEqual(Language::LANGCODE_NOT_SPECIFIED, $block->language()->id); + $this->assertEqual('

My second custom block body

', $block->body->value); + $this->assertEqual('full_html', $block->body->format); + } + +} diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockTest.php index bb79dc6..800e784 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateBlockTest.php @@ -25,7 +25,7 @@ class MigrateBlockTest extends MigrateDrupalTestBase { 'views', 'comment', 'menu_ui', - 'custom_block', + 'block_content', 'node', ); @@ -48,8 +48,8 @@ public function setUp() { $entities = array( entity_create('menu', array('id' => 'primary-links')), entity_create('menu', array('id' => 'secondary-links')), - entity_create('custom_block', array('id' => 1, 'type' => 'basic', 'info' => $this->randomName(8))), - entity_create('custom_block', array('id' => 2, 'type' => 'basic', 'info' => $this->randomName(8))), + entity_create('block_content', array('id' => 1, 'type' => 'basic', 'info' => $this->randomName(8))), + entity_create('block_content', array('id' => 2, 'type' => 'basic', 'info' => $this->randomName(8))), ); foreach ($entities as $entity) { $entity->enforceIsNew(TRUE); diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateCustomBlockTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateCustomBlockTest.php deleted file mode 100644 index d48acaf..0000000 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateCustomBlockTest.php +++ /dev/null @@ -1,75 +0,0 @@ - 'Migrate custom blocks.', - 'description' => 'Upgrade custom blocks.', - 'group' => 'Migrate Drupal', - ); - } - - /** - * {@inheritdoc} - */ - public function setUp() { - parent::setUp(); - $this->prepareIdMappings(array( - 'd6_filter_format' => array( - array(array(2), array('full_html')) - ) - )); - /** @var \Drupal\migrate\entity\Migration $migration */ - $migration = entity_load('migration', 'd6_custom_block'); - $dumps = array( - $this->getDumpDirectory() . '/Drupal6Box.php', - ); - $this->prepare($migration, $dumps); - $executable = new MigrateExecutable($migration, $this); - $executable->import(); - } - - /** - * Tests the Drupal 6 custom block to Drupal 8 migration. - */ - public function testBlockMigration() { - /** @var CustomBlock $block */ - $block = entity_load('custom_block', 1); - $this->assertEqual('My block 1', $block->label()); - $this->assertEqual(1, $block->getRevisionId()); - $this->assertTrue(REQUEST_TIME <= $block->getChangedTime() && $block->getChangedTime() <= time()); - $this->assertEqual(Language::LANGCODE_NOT_SPECIFIED, $block->language()->id); - $this->assertEqual('

My first custom block body

', $block->body->value); - $this->assertEqual('full_html', $block->body->format); - - $block = entity_load('custom_block', 2); - $this->assertEqual('My block 2', $block->label()); - $this->assertEqual(2, $block->getRevisionId()); - $this->assertTrue(REQUEST_TIME <= $block->getChangedTime() && $block->getChangedTime() <= time()); - $this->assertEqual(Language::LANGCODE_NOT_SPECIFIED, $block->language()->id); - $this->assertEqual('

My second custom block body

', $block->body->value); - $this->assertEqual('full_html', $block->body->format); - } - -} diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php index adcf35b..79f11da 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php @@ -26,7 +26,7 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase { 'book', 'comment', 'contact', - 'custom_block', + 'block_content', 'datetime', 'dblog', 'file', @@ -235,7 +235,7 @@ protected function getTestClassesList() { __NAMESPACE__ . '\MigrateCommentVariableInstance', __NAMESPACE__ . '\MigrateContactCategoryTest', __NAMESPACE__ . '\MigrateContactConfigsTest', - __NAMESPACE__ . '\MigrateCustomBlockTest', + __NAMESPACE__ . '\MigrateBlockContentTest', __NAMESPACE__ . '\MigrateDateFormatTest', __NAMESPACE__ . '\MigrateDblogConfigsTest', __NAMESPACE__ . '\MigrateFieldConfigsTest', diff --git a/core/modules/quickedit/js/quickedit.js b/core/modules/quickedit/js/quickedit.js index 9244694..98a7e27 100644 --- a/core/modules/quickedit/js/quickedit.js +++ b/core/modules/quickedit/js/quickedit.js @@ -434,7 +434,7 @@ * @param Object contextualLink * An object with the following properties: * - String entityID: a Quick Edit entity identifier, e.g. "node/1" or - * "custom_block/5". + * "block_content/5". * - String entityInstanceID: a Quick Edit entity instance identifier, * e.g. 0, 1 or n (depending on whether it's the first, second, or n+1st * instance of this entity). diff --git a/core/profiles/standard/standard.info.yml b/core/profiles/standard/standard.info.yml index 3f8116b..7029739 100644 --- a/core/profiles/standard/standard.info.yml +++ b/core/profiles/standard/standard.info.yml @@ -15,7 +15,7 @@ dependencies: - contextual - contact - datetime - - custom_block + - block_content - quickedit - editor - entity_reference diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme index c3e7a32..34c165d 100644 --- a/core/themes/seven/seven.theme +++ b/core/themes/seven/seven.theme @@ -136,11 +136,11 @@ function seven_node_add_list($variables) { } /** - * Overrides theme_custom_block_add_list(). + * Overrides theme_block_content_add_list(). * * Displays the list of available custom block types for creation. */ -function seven_custom_block_add_list($variables) { +function seven_block_content_add_list($variables) { $output = ''; if (!empty($variables['types'])) { $output = '';