reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Controller/CustomBlockController.php @@ -0,0 +1,115 @@ +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())); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockAccessController.php @@ -0,0 +1,29 @@ +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'], + ))); + } + } + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockInterface.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/custom-blocks'; + } + return $operations; + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTranslationHandler.php @@ -0,0 +1,43 @@ + '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())); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeForm.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\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'; + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeInterface.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'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockViewBuilder.php @@ -0,0 +1,33 @@ +isNew() && $view_mode == 'full') { + $build['#contextual_links']['custom_block'] = array( + 'route_parameters' => array('custom_block' => $entity->id()), + 'metadata' => array('changed' => $entity->getChangedTime()), + ); + } + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.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' => '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; + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlockType.php @@ -0,0 +1,86 @@ +isSyncing()) { + if (!$this->isSyncing()) { + custom_block_add_body_field($this->id); + } + } + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockDeleteForm.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('custom_block', 'Custom block %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); + $form_state['redirect_route'] = new Url('custom_block.list'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.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('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(); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Block/CustomBlockBlock.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['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') + ); + } + } +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php @@ -0,0 +1,28 @@ +derivatives[$custom_block->uuid()] = $base_plugin_definition; + $this->derivatives[$custom_block->uuid()]['admin_label'] = $custom_block->label(); + } + return parent::getDerivativeDefinitions($base_plugin_definition); + } +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Menu/LocalAction/CustomBlockAddLocalAction.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) == '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; + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockCacheTagsTest.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', + ), + )); + $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'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockCreationTest.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 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'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.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->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'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.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'))); + $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.')); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockPageViewTest.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->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'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockRevisionsTest.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->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.'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockSaveTest.php @@ -0,0 +1,117 @@ + '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.'); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTestBase.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\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; + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTranslationUITest.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 = '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); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php @@ -0,0 +1,214 @@ + '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')); + field_info_cache_clear(); + + $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.'); + } + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/lib/Drupal/custom_block/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('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()))); + } + +} reverted: --- /dev/null +++ a/core/modules/block/custom_block/tests/Drupal/custom_blocks/Tests/Menu/CustomBlockLocalTasksTest.php @@ -0,0 +1,64 @@ + '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'), + ); + } + +} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/BlockContentAccessController.php +++ /dev/null @@ -1,29 +0,0 @@ -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'], - ))); - } - } - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/BlockContentInterface.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/block-content'; - } - return $operations; - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/BlockContentTranslationHandler.php +++ /dev/null @@ -1,43 +0,0 @@ - '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())); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/BlockContentTypeForm.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\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'; - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/BlockContentTypeInterface.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'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/BlockContentViewBuilder.php +++ /dev/null @@ -1,33 +0,0 @@ -isNew() && $view_mode == 'full') { - $build['#contextual_links']['block_content'] = array( - 'route_parameters' => array('block_content' => $entity->id()), - 'metadata' => array('changed' => $entity->getChangedTime()), - ); - } - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Controller/BlockContentController.php +++ /dev/null @@ -1,115 +0,0 @@ -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())); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Entity/BlockContent.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' => '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; - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Entity/BlockContentType.php +++ /dev/null @@ -1,101 +0,0 @@ -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()); - } - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Form/BlockContentDeleteForm.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('block_content', 'Custom block %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); - $form_state['redirect_route'] = new Url('block_content.list'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Form/BlockContentTypeDeleteForm.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('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(); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Plugin/Block/BlockContentBlock.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['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') - ); - } - } -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Plugin/Derivative/BlockContent.php +++ /dev/null @@ -1,28 +0,0 @@ -derivatives[$block_content->uuid()] = $base_plugin_definition; - $this->derivatives[$block_content->uuid()]['admin_label'] = $block_content->label(); - } - return parent::getDerivativeDefinitions($base_plugin_definition); - } -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Plugin/Menu/LocalAction/BlockContentAddLocalAction.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) == '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; - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentCacheTagsTest.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', - ), - )); - $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'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentCreationTest.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 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'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentFieldTest.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->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'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentListTest.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'))); - $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.')); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentPageViewTest.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->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'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentRevisionsTest.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->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.'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentSaveTest.php +++ /dev/null @@ -1,117 +0,0 @@ - '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.'); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentTestBase.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\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; - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentTranslationUITest.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 = '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); - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/Tests/BlockContentTypeTest.php +++ /dev/null @@ -1,214 +0,0 @@ - 'BlockContent 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')); - field_info_cache_clear(); - - $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.'); - } - } - -} reverted: --- b/core/modules/block_content/lib/Drupal/block_content/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('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()))); - } - -} reverted: --- b/core/modules/block_content/tests/Drupal/block_content/Tests/Menu/BlockContentLocalTasksTest.php +++ /dev/null @@ -1,94 +0,0 @@ - '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'), - ); - } - -} reverted: --- b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUiTest.php +++ a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationListUiTest.php @@ -27,7 +27,7 @@ 'block', 'config_translation', 'contact', + 'custom_block', - 'block_content', 'field', 'field_ui', 'menu_ui', @@ -62,7 +62,7 @@ '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 @@ /** * 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 @@ '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 @@ $this->doBlockListTest(); $this->doMenuListTest(); $this->doVocabularyListTest(); + $this->doCustomBlockTypeListTest(); - $this->doCustomContentTypeListTest(); $this->doContactFormsListTest(); $this->doContentTypeListTest(); $this->doFormatsListTest(); reverted: --- b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/BlockPluginId.php +++ a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/process/d6/BlockPluginId.php @@ -32,14 +32,14 @@ /** * @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 @@ $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 @@ $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(); reverted: --- b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateBlockTest.php +++ a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateBlockTest.php @@ -25,7 +25,7 @@ 'views', 'comment', 'menu_ui', + 'custom_block', - 'block_content', 'node', ); @@ -48,8 +48,8 @@ $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); reverted: --- b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateCustomBlockTest.php +++ a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateCustomBlockTest.php @@ -2,22 +2,22 @@ /** * @file + * Contains \Drupal\migrate_drupal\Tests\d6\MigrateCustomBlockTest. - * Contains \Drupal\migrate_drupal\Tests\d6\MigrateBlockContentTest. */ namespace Drupal\migrate_drupal\Tests\d6; use Drupal\Core\Language\Language; +use Drupal\custom_block\Entity\CustomBlock; -use Drupal\block_content\Entity\BlockContent; use Drupal\migrate\MigrateExecutable; use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase; /** * Tests the Drupal 6 custom block to Drupal 8 migration. */ +class MigrateCustomBlockTest extends MigrateDrupalTestBase { -class MigrateBlockContentTest extends MigrateDrupalTestBase { + static $modules = array('block', 'custom_block'); - static $modules = array('block', 'block_content'); /** * {@inheritdoc} @@ -54,8 +54,8 @@ * Tests the Drupal 6 custom block to Drupal 8 migration. */ public function testBlockMigration() { + /** @var CustomBlock $block */ + $block = entity_load('custom_block', 1); - /** @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()); @@ -63,7 +63,7 @@ $this->assertEqual('

My first custom block body

', $block->body->value); $this->assertEqual('full_html', $block->body->format); + $block = entity_load('custom_block', 2); - $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()); reverted: --- b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateDrupal6Test.php +++ a/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateDrupal6Test.php @@ -26,7 +26,7 @@ 'book', 'comment', 'contact', + 'custom_block', - 'block_content', 'datetime', 'dblog', 'file', @@ -235,7 +235,7 @@ __NAMESPACE__ . '\MigrateCommentVariableInstance', __NAMESPACE__ . '\MigrateContactCategoryTest', __NAMESPACE__ . '\MigrateContactConfigsTest', + __NAMESPACE__ . '\MigrateCustomBlockTest', - __NAMESPACE__ . '\MigrateBlockContentTest', __NAMESPACE__ . '\MigrateDateFormatTest', __NAMESPACE__ . '\MigrateDblogConfigsTest', __NAMESPACE__ . '\MigrateFieldConfigsTest', only in patch2: unchanged: --- 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())); - } - -} only in patch2: unchanged: --- 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'], - ))); - } - } - } - -} only in patch2: unchanged: --- 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; - } - -} only in patch2: unchanged: --- 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())); - } - -} only in patch2: unchanged: --- 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'; - } - -} only in patch2: unchanged: --- 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'); - } - -} only in patch2: unchanged: --- 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()), - ); - } - } - -} only in patch2: unchanged: --- 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; - } - -} only in patch2: unchanged: --- 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); - } - } - } - -} only in patch2: unchanged: --- 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'); - } - -} only in patch2: unchanged: --- 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(); - } - -} only in patch2: unchanged: --- 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') - ); - } - } -} only in patch2: unchanged: --- 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); - } -} only in patch2: unchanged: --- 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; - } - -} only in patch2: unchanged: --- 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'); - } - -} only in patch2: unchanged: --- 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'); - } - -} only in patch2: unchanged: --- 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'); - } - -} only in patch2: unchanged: --- 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'))); - $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.')); - } - -} only in patch2: unchanged: --- 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'); - } - -} only in patch2: unchanged: --- 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.'); - } - -} only in patch2: unchanged: --- 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.'); - } - -} only in patch2: unchanged: --- 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; - } - -} only in patch2: unchanged: --- 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); - } - -} only in patch2: unchanged: --- 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.'); - } - } - -} only in patch2: unchanged: --- 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()))); - } - -} only in patch2: unchanged: --- 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'), - ); - } - -} only in patch2: unchanged: --- /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'], + ))); + } + } + } + +} only in patch2: unchanged: --- /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; + } + +} only in patch2: unchanged: --- /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())); + } + +} only in patch2: unchanged: --- /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'; + } + +} only in patch2: unchanged: --- /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'); + } + +} only in patch2: unchanged: --- /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()), + ); + } + } + +} only in patch2: unchanged: --- /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())); + } + +} only in patch2: unchanged: --- /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; + } + +} only in patch2: unchanged: --- /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()); + } + } + +} only in patch2: unchanged: --- /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'); + } + +} only in patch2: unchanged: --- /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(); + } + +} only in patch2: unchanged: --- /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') + ); + } + } +} only in patch2: unchanged: --- /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); + } +} only in patch2: unchanged: --- /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; + } + +} only in patch2: unchanged: --- /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'); + } + +} only in patch2: unchanged: --- /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'); + } + +} only in patch2: unchanged: --- /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'); + } + +} only in patch2: unchanged: --- /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'))); + $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.')); + } + +} only in patch2: unchanged: --- /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'); + } + +} only in patch2: unchanged: --- /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.'); + } + +} only in patch2: unchanged: --- /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.'); + } + +} only in patch2: unchanged: --- /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; + } + +} only in patch2: unchanged: --- /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); + } + +} only in patch2: unchanged: --- /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.'); + } + } + +} only in patch2: unchanged: --- /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()))); + } + +} only in patch2: unchanged: --- /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'), + ); + } + +} only in patch2: unchanged: --- 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(); only in patch2: unchanged: --- 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(); only in patch2: unchanged: --- 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); only in patch2: unchanged: --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateCustomBlockTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCustomBlockTest.php @@ -2,22 +2,22 @@ /** * @file - * Contains \Drupal\migrate_drupal\Tests\d6\MigrateCustomBlockTest. + * Contains \Drupal\migrate_drupal\Tests\d6\MigrateBlockContentTest. */ namespace Drupal\migrate_drupal\Tests\d6; use Drupal\Core\Language\Language; -use Drupal\custom_block\Entity\CustomBlock; +use Drupal\block_content\Entity\BlockContent; use Drupal\migrate\MigrateExecutable; use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase; /** * Tests the Drupal 6 custom block to Drupal 8 migration. */ -class MigrateCustomBlockTest extends MigrateDrupalTestBase { +class MigrateBlockContentTest extends MigrateDrupalTestBase { - static $modules = array('block', 'custom_block'); + static $modules = array('block', 'block_content'); /** * {@inheritdoc} @@ -54,8 +54,8 @@ public function setUp() { * Tests the Drupal 6 custom block to Drupal 8 migration. */ public function testBlockMigration() { - /** @var CustomBlock $block */ - $block = entity_load('custom_block', 1); + /** @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()); @@ -63,7 +63,7 @@ public function testBlockMigration() { $this->assertEqual('

My first custom block body

', $block->body->value); $this->assertEqual('full_html', $block->body->format); - $block = entity_load('custom_block', 2); + $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()); only in patch2: unchanged: --- 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',