Commit b2320bc9 authored by Dries's avatar Dries

Issue #1871772 by larowlan, EclipseGc: Convert custom blocks to content entities.

parent 9e49307d
......@@ -200,6 +200,9 @@ Contact module
Contextual module
- Daniel F. Kudwien 'sun' http://drupal.org/user/54136
Custom block module
- Lee Rowlands 'larowlan' http://drupal.org/user/395439
Database Logging module
- Khalid Baheyeldin 'kbahey' http://drupal.org/user/4063
......
......@@ -4,6 +4,7 @@
* @file
* Install, update and uninstall functions for the block module.
*/
use Drupal\Component\Uuid\Uuid;
/**
* Implements hook_schema().
......@@ -42,7 +43,7 @@ function block_update_dependencies() {
);
// Migrate users.data after User module prepared the tables.
$dependencies['block'][8005] = array(
'user' => 8011,
'user' => 8016,
);
return $dependencies;
}
......@@ -193,6 +194,246 @@ function block_update_8006() {
update_module_enable(array('custom_block'));
}
/**
* Migrate {block_custom} to {custom_block}.
*
* Note this table now resides in custom_block_schema() but for 7.x to 8.x
* upgrades, changes must be made from block module as custom_block module is
* only enabled during upgrade process.
*/
function block_update_8007() {
// Add the {custom_block} table.
db_create_table('custom_block', array(
'description' => 'Stores contents of custom-made blocks.',
'fields' => array(
'id' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => "The block's {custom_block}.id.",
),
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
),
'info' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => 'Block description.',
),
// Defaults to NULL in order to avoid a brief period of potential
// deadlocks on the index.
'revision_id' => array(
'description' => 'The current {block_custom_revision}.revision_id version identifier.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE,
'default' => NULL,
),
'type' => array(
'description' => 'The type of this custom block.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
),
'langcode' => array(
'description' => 'The {language}.langcode of this node.',
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array('id'),
'indexes' => array(
'block_custom_type' => array(array('type', 4)),
),
'unique keys' => array(
'revision_id' => array('revision_id'),
'uuid' => array('uuid'),
'info' => array('info'),
),
'foreign keys' => array(
'custom_block_revision' => array(
'table' => 'custom_block_revision',
'columns' => array('revision_id' => 'revision_id'),
),
),
));
// Add the {custom_block_revision} table.
db_create_table('custom_block_revision', array(
'description' => 'Stores contents of custom-made blocks.',
'fields' => array(
'id' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => "The block's {custom_block}.id.",
),
// Defaults to NULL in order to avoid a brief period of potential
// deadlocks on the index.
'revision_id' => array(
'description' => 'The current version identifier.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'log' => array(
'description' => 'The log entry explaining the changes in this version.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
),
'info' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => 'Block description.',
),
),
'primary key' => array('revision_id'),
));
// Populate the {custom_block} and {custom_block_revision} table.
$results = db_select('block_custom', 'bc')->fields('bc')->execute();
$uuid = new Uuid();
$execute = FALSE;
$block_insert = db_insert('custom_block')->fields(array(
'id',
'uuid',
'info',
'revision_id',
'langcode',
'type'
));
$revision_insert = db_insert('custom_block_revision')->fields(array(
'id',
'revision_id',
'log',
'info'
));
foreach ($results as $block) {
$custom_block = array(
'id' => $block->bid,
'uuid' => $uuid->generate(),
'info' => $block->info,
'revision_id' => $block->bid,
'langcode' => LANGUAGE_NOT_SPECIFIED,
'type' => 'basic'
);
$revision = array(
'id' => $block->bid,
'revision_id' => $block->bid,
'info' => $block->info,
'log' => 'Initial value from 7.x to 8.x upgrade'
);
$block_insert->values($custom_block);
$revision_insert->values($revision);
// We have something to execute.
$execute = TRUE;
}
if ($execute) {
$block_insert->execute();
$revision_insert->execute();
}
}
/**
* Migrate {block_custom}.body and {block_custom}.format to block_body field.
*/
function block_update_8008() {
$sandbox['#finished'] = 0;
if (!isset($sandbox['total'])) {
// Initial invocation.
// First, create the body field.
$body_field = array(
'field_name' => 'block_body',
'type' => 'text_with_summary',
'entity_types' => array('custom_block'),
'module' => 'text',
'cardinality' => 1,
);
_update_7000_field_create_field($body_field);
$instance = array(
'field_name' => 'block_body',
'entity_type' => 'custom_block',
'bundle' => 'basic',
'label' => 'Block body',
'widget' => array('type' => 'text_textarea_with_summary'),
'settings' => array('display_summary' => FALSE),
);
_update_7000_field_create_instance($body_field, $instance);
// Initialize state for future calls.
$sandbox['last'] = 0;
$sandbox['count'] = 0;
$query = db_select('block_custom', 'bc');
$sandbox['total'] = $query->countQuery()->execute()->fetchField();
$sandbox['body_field_id'] = $body_field['id'];
}
else {
// Subsequent invocations.
$found = FALSE;
if ($sandbox['total']) {
// Operate on each block in turn.
$batch_size = 200;
$query = db_select('block_custom', 'bc');
$query
->fields('bc', array('bid', 'body', 'format'))
->condition('bc.bid', $sandbox['last'], '>')
->orderBy('bc.bid', 'ASC')
->range(0, $batch_size);
$blocks = $query->execute();
// Load the block, set up 'body' and save the field data.
foreach ($blocks as $block) {
$found = TRUE;
$data = array(
LANGUAGE_NOT_SPECIFIED => array(
array(
'format' => $block->format,
'value' => $block->body
)
)
);
// This is a core update and no contrib modules are enabled yet, so
// we can assume default field storage for a faster update.
_update_7000_field_sql_storage_write('custom_block', 'basic', $block->bid, $block->bid, 'block_body', $data);
$sandbox['last'] = $block->bid;
$sandbox['count'] += 1;
}
$sandbox['#finished'] = min(0.99, $sandbox['count'] / $sandbox['total']);
}
if (!$found) {
// All blocks are processed.
// Remove the now-obsolete body info from block_custom.
db_drop_field('block_custom', 'body');
db_drop_field('block_custom', 'format');
// We're done.
$sandbox['#finished'] = 1;
}
}
}
/**
* @} End of "addtogroup updates-7.x-to-8.x".
* The next series of updates should start at 9000.
......
id: basic
label: Basic block
revision: '0'
description: A basic block contains a title and a body.
<?php
/**
* @file
* Admin page callbacks for the custom block module.
*/
use Drupal\custom_block\Plugin\Core\Entity\CustomBlockType;
/**
* Page callback: Lists custom block types.
*
* @return array
* A build array in the format expected by drupal_render().
*
* @see custom_block_menu()
*/
function custom_block_type_list() {
return drupal_container()->get('plugin.manager.entity')->getListController('custom_block_type')->render();
}
/**
* Page callback: Presents the custom block type creation form.
*
* @return array
* A form array as expected by drupal_render().
*
* @see custom_block_menu()
*/
function custom_block_type_add() {
$block_type = entity_create('custom_block_type', array());
return entity_get_form($block_type);
}
/**
* Page callback: Presents the custom block type edit form.
*
* @param \Drupal\custom_block\Plugin\Core\Entity\CustomBlockType $block_type
* The custom block type to edit.
*
* @return array
* A form array as expected by drupal_render().
*
* @see custom_block_menu()
*/
function custom_block_type_edit(CustomBlockType $block_type) {
return entity_get_form($block_type);
}
/**
* Page callback: Form constructor for the custom block type deletion form.
*
* @param \Drupal\custom_block\Plugin\Core\Entity\CustomBlockType $block_type
* The custom block type to be deleted.
*
* @see custom_block_menu()
* @see custom_block_type_delete_form_submit()
*
* @ingroup forms
*/
function custom_block_type_delete_form($form, &$form_state, CustomBlockType $block_type) {
$form_state['custom_block_type'] = $block_type;
$form['id'] = array(
'#type' => 'value',
'#value' => $block_type->id(),
);
$message = t('Are you sure you want to delete %label?', array('%label' => $block_type->label()));
$blocks = entity_query('custom_block')->condition('type', $block_type->id())->execute();
if (!empty($blocks)) {
drupal_set_title($message, PASS_THROUGH);
$caption = '<p>' . 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' => $block_type->label())) . '</p>';
$form['description'] = array('#markup' => $caption);
return $form;
}
return confirm_form(
$form,
$message,
'admin/structure/custom-blocks',
t('This action cannot be undone.'),
t('Delete')
);
}
/**
* Form submission handler for custom_block_type_delete_form().
*/
function custom_block_type_delete_form_submit($form, &$form_state) {
$block_type = $form_state['custom_block_type'];
$block_type->delete();
drupal_set_message(t('Custom block type %label has been deleted.', array('%label' => $block_type->label())));
watchdog('custom_block', 'Custom block type %label has been deleted.', array('%label' => $block_type->label()), WATCHDOG_NOTICE);
$form_state['redirect'] = 'admin/structure/custom-blocks';
}
......@@ -4,3 +4,4 @@ package = Core
version = VERSION
core = 8.x
dependencies[] = block
dependencies[] = text
......@@ -10,21 +10,20 @@
*/
function custom_block_schema() {
$schema = array();
$schema['block_custom'] = array(
$schema['custom_block'] = array(
'description' => 'Stores contents of custom-made blocks.',
'fields' => array(
'bid' => array(
'id' => array(
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
'description' => "The block's {block}.bid.",
'description' => "The block's {custom_block}.id.",
),
'body' => array(
'type' => 'text',
'uuid' => array(
'description' => 'Unique Key: Universally unique identifier for this entity.',
'type' => 'varchar',
'length' => 128,
'not null' => FALSE,
'size' => 'big',
'description' => 'Block contents.',
'translatable' => TRUE,
),
'info' => array(
'type' => 'varchar',
......@@ -33,17 +32,80 @@ function custom_block_schema() {
'default' => '',
'description' => 'Block description.',
),
'format' => array(
'type' => 'varchar',
'length' => 255,
// Defaults to NULL in order to avoid a brief period of potential
// deadlocks on the index.
'revision_id' => array(
'description' => 'The current {block_custom_revision}.revision_id version identifier.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE,
'description' => 'The {filter_format}.format of the block body.',
'default' => NULL,
),
'type' => array(
'description' => 'The type of this custom block.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
),
'langcode' => array(
'description' => 'The {language}.langcode of this node.',
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
),
),
'primary key' => array('id'),
'indexes' => array(
'block_custom_type' => array(array('type', 4)),
),
'unique keys' => array(
'revision_id' => array('revision_id'),
'uuid' => array('uuid'),
'info' => array('info'),
),
'primary key' => array('bid'),
'foreign keys' => array(
'custom_block_revision' => array(
'table' => 'custom_block_revision',
'columns' => array('revision_id' => 'revision_id'),
),
),
);
$schema['custom_block_revision'] = array(
'description' => 'Stores contents of custom-made blocks.',
'fields' => array(
'id' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => "The block's {custom_block}.id.",
),
// Defaults to NULL in order to avoid a brief period of potential
// deadlocks on the index.
'revision_id' => array(
'description' => 'The current version identifier.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'log' => array(
'description' => 'The log entry explaining the changes in this version.',
'type' => 'text',
'not null' => TRUE,
'size' => 'big',
),
'info' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => 'Block description.',
),
),
'primary key' => array('revision_id'),
);
return $schema;
}
/**
* @file
* Defines Javascript behaviors for the custom_block module.
*/
(function ($) {
"use strict";
Drupal.behaviors.customBlockDetailsSummaries = {
attach: function (context) {
var $context = $(context);
$context.find('.custom-block-form-revision-information').drupalSetSummary(function (context) {
var $context = $(context);
var revisionCheckbox = $context.find('.form-item-revision input');
// Return 'New revision' if the 'Create new revision' checkbox is checked,
// or if the checkbox doesn't exist, but the revision log does. For users
// without the "Administer content" permission the checkbox won't appear,
// but the revision log will if the content type is set to auto-revision.
if (revisionCheckbox.is(':checked') || (!revisionCheckbox.length && $context.find('.form-item-log textarea').length)) {
return Drupal.t('New revision');
}
return Drupal.t('No revision');
});
$context.find('fieldset.custom-block-translation-options').drupalSetSummary(function (context) {
var $context = $(context);
var translate;
var $checkbox = $context.find('.form-item-translation-translate input');
if ($checkbox.size()) {
translate = $checkbox.is(':checked') ? Drupal.t('Needs to be updated') : Drupal.t('Does not need to be updated');
}
else {
$checkbox = $context.find('.form-item-translation-retranslate input');
translate = $checkbox.is(':checked') ? Drupal.t('Flag other translations as outdated') : Drupal.t('Do not flag other translations as outdated');
}
return translate;
});
}
};
})(jQuery);
<?php
/**
* @file
* Provides page callbacks for custom blocks.
*/
use Drupal\custom_block\Plugin\Core\Entity\CustomBlockType;
use Drupal\custom_block\Plugin\Core\Entity\CustomBlock;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Page callback: Displays add custom block links for available types.
*
* @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.
*
* @see custom_block_menu()
*/
function custom_block_add_page() {
$options = array();
$request = drupal_container()->get('request');
if (($theme = $request->attributes->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.
$options = array(
'query' => array('theme' => $theme)
);
}
$types = entity_load_multiple('custom_block_type');
if ($types && count($types) == 1) {
$type = reset($types);
return custom_block_add($type);
}
return array('#theme' => 'custom_block_add_list', '#content' => $types);
}
/**
* Returns HTML for a list of available custom block types for block creation.
*
* @param $variables
* An associative array containing:
* - content: An array of block types.
*
* @see custom_block_add_page()
*
* @ingroup themeable
*/
function theme_custom_block_add_list($variables) {
$content = $variables['content'];
$output = '';
if ($content) {
$output = '<dl class="node-type-list">';
foreach ($content as $type) {
$output .= '<dt>' . l($type->label(), 'block/add/' . $type->id()) . '</dt>';
$output .= '<dd>' . filter_xss_admin($type->description) . '</dd>';
}
$output .= '</dl>';
}
return $output;
}
/**
* Page callback: Presents the custom block creation form.
*
* @param Drupal\custom_block\Plugin\Core\Entity\CustomBlockType $block_type
* The custom block type to add.
*
* @return array
* A form array as expected by drupal_render().
*
* @see custom_block_menu()
*/
function custom_block_add(CustomBlockType $block_type) {
drupal_set_title(t('Add %type custom block', array(
'%type' => $block_type->label()
)), PASS_THROUGH);
$block = entity_create('custom_block', array(
'type' => $block_type->id()
));
$options = array();
$request = drupal_container()->get('request');
if (($theme = $request->attributes->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 entity_get_form($block);
}
/**
* Page callback: Presents the custom block edit form.
*
* @param Drupal\custom_block\Plugin\Core\Entity\CustomBlock $block
* The custom block to edit.
*
* @return array
* A form array as expected by drupal_render().
*
* @see custom_block_menu()
*/
function custom_block_edit(CustomBlock $block) {
drupal_set_title(t('Edit custom block %label', array('%label' => $block->label())), PASS_THROUGH);
return entity_get_form($block);
}
/**
* Page callback: Form constructor for the custom block deletion form.
*
* @param Drupal\custom_block\Plugin\Core\Entity\CustomBlock $block
* The custom block to be deleted.
*
* @see custom_block_menu()
* @see custom_block_delete_form_submit()
*
* @ingroup forms
*/
function custom_block_delete_form($form, &$form_state, CustomBlock $block) {
$form_state['custom_block'] = $block;
$form['id'] = array(
'#type' => 'value',
'#value' => $block->id(),
);
return confirm_form(
$form,
t('Are you sure you want to delete %label?', array('%label' => $block->label())),
'admin/structure/block',
t('This action cannot be undone.'),
t('Delete')
);
}
/**
* Form submission handler for custom_block_delete_form().
*/
function custom_block_delete_form_submit($form, &$form_state) {
// @todo Delete all configured instances of the block.
$block = $form_state['custom_block'];
$block->delete();
drupal_set_message(t('Custom block %label has been deleted.', array('%label' => $block->label())));
watchdog('custom_block', 'Custom block %label has been deleted.', array('%label' => $block->label()), WATCHDOG_NOTICE);
$form_state['redirect'] = 'admin/structure/block';
}
<?php
/**
* @file
* Contains \Drupal\custom_block\CustomBlockAccessController.