block.inc
Provide Drupal blocks as content.
Since blocks don't provide all of the features we do, we have to do a little extra work, including providing icons and categories for core blocks. Blocks from contrib modules get to provide their own stuff, or get relegated to the old "Miscellaneous" category.
File
-
plugins/
content_types/ block/ block.inc
View source
<?php
/**
* @file
* Provide Drupal blocks as content.
*
* Since blocks don't provide all of the features we do, we have to do a little
* extra work, including providing icons and categories for core blocks. Blocks
* from contrib modules get to provide their own stuff, or get relegated to
* the old "Miscellaneous" category.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
// And this is just the administrative title.
// All our callbacks are named according to the standard pattern and can be deduced.
'title' => t('Block'),
'content type' => 'ctools_block_content_type_content_type',
);
/**
* Return the block content types with the specified $subtype_id.
*/
function ctools_block_content_type_content_type($subtype_id) {
list($module, $delta) = explode('-', $subtype_id, 2);
$module_blocks = module_invoke($module, 'block_info');
if (isset($module_blocks[$delta])) {
return _ctools_block_content_type_content_type($module, $delta, $module_blocks[$delta]);
}
}
/**
* Return all block content types available.
*
* Modules wanting to make special adjustments the way that CTools handles their blocks
* can implement an extension to the hook_block() family, where the function name is
* of the form "$module . '_ctools_block_info'".
*/
function ctools_block_content_type_content_types() {
$types =& drupal_static(__FUNCTION__);
if (isset($types)) {
return $types;
}
$types = array();
foreach (module_implements('block_info') as $module) {
$module_blocks = module_invoke($module, 'block_info');
if ($module_blocks) {
foreach ($module_blocks as $delta => $block) {
$info = _ctools_block_content_type_content_type($module, $delta, $block);
// This check means modules can remove their blocks; particularly useful
// if they offer the block some other way (like we do for views)
if ($info) {
$types["{$module}-{$delta}"] = $info;
}
}
}
}
return $types;
}
/**
* Return an info array for a specific block.
*/
function _ctools_block_content_type_content_type($module, $delta, $block) {
// strip_tags used because it goes through check_plain and that
// just looks bad.
$info = array(
'title' => strip_tags($block['info']),
);
// Ask around for further information by invoking the hook_block() extension.
$function = $module . '_ctools_block_info';
if (!function_exists($function)) {
$function = 'ctools_default_block_info';
}
$function($module, $delta, $info);
return $info;
}
/**
* Load block info from the database.
*
* This is copied from _block_load_blocks(). It doesn't use that
* function because _block_load_blocks sorts by region, and it
* doesn't cache its results anyway.
*/
function _ctools_block_load_blocks() {
if (!module_exists('block')) {
return array();
}
$blocks =& drupal_static(__FUNCTION__, NULL);
if (!isset($blocks)) {
global $theme_key;
$query = db_select('block', 'b');
$result = $query->fields('b')
->condition('b.theme', $theme_key)
->orderBy('b.region')
->orderBy('b.weight')
->orderBy('b.module')
->addTag('block_load')
->addTag('translatable')
->execute();
$block_info = $result->fetchAllAssoc('bid');
// Allow modules to modify the block list.
drupal_alter('block_list', $block_info);
$blocks = array();
foreach ($block_info as $block) {
$blocks["{$block->module}_{$block->delta}"] = $block;
}
}
return $blocks;
}
/**
* Fetch the stored info for a block.
*
* The primary reason to use this is so that modules which perform alters
* can have their alters make it to the block.
*/
function _ctools_get_block_info($module, $delta) {
$blocks = _ctools_block_load_blocks();
$key = $module . '_' . $delta;
if (isset($blocks[$key])) {
return $blocks[$key];
}
}
/**
* Output function for the 'block' content type. Outputs a block
* based on the module and delta supplied in the configuration.
*/
function ctools_block_content_type_render($subtype, $conf) {
list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
$info = _ctools_get_block_info($module, $delta);
$block = module_invoke($module, 'block_view', $delta);
if (!empty($info)) {
// Valid PHP function names cannot contain hyphens.
$block_delta = str_replace('-', '_', $delta);
// Allow modules to modify the block before it is viewed, via either
// hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
drupal_alter(array(
'block_view',
"block_view_{$module}_{$block_delta}",
), $block, $info);
}
if (empty($block)) {
return;
}
$block = (object) $block;
$block->module = $module;
$block->delta = $delta;
if (!isset($block->title)) {
if ($module == 'block' && !empty($info) && isset($info->title)) {
$block->title = $info->title;
}
elseif (isset($block->subject)) {
$block->title = $block->subject;
}
else {
$block->title = NULL;
}
}
if (module_exists('block') && user_access('administer blocks')) {
$block->admin_links = array(
array(
'title' => t('Configure block'),
'href' => "admin/structure/block/manage/{$module}/{$delta}/configure",
'query' => drupal_get_destination(),
),
);
}
return $block;
}
/**
* Empty form so we can have the default override title.
*/
function ctools_block_content_type_edit_form($form, &$form_state) {
// Does nothing!
return $form;
}
/**
* Submit function to fix the subtype for really old panel panes.
*/
function ctools_block_content_type_edit_form_submit($form, &$form_state) {
if (empty($form_state['subtype']) && isset($form_state['pane'])) {
$form_state['pane']->subtype = $form_state['conf']['module'] . '-' . $form_state['conf']['delta'];
unset($form_state['conf']['module']);
unset($form_state['conf']['delta']);
}
}
/**
* Returns the administrative title for a type.
*/
function ctools_block_content_type_admin_title($subtype, $conf) {
list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
$block = module_invoke($module, 'block_info');
if (empty($block) || empty($block[$delta])) {
return t('Deleted/missing block @module-@delta', array(
'@module' => $module,
'@delta' => $delta,
));
}
// The block description reported by hook_block() is plain text, but the title
// reported by this hook should be HTML.
$title = check_plain($block[$delta]['info']);
return $title;
}
/**
* Output function for the 'block' content type. Outputs a block
* based on the module and delta supplied in the configuration.
*/
function ctools_block_content_type_admin_info($subtype, $conf) {
list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
$block = (object) module_invoke($module, 'block_view', $delta);
if (!empty($block)) {
// Sanitize the block because <script> tags can hose javascript up:
if (!empty($block->content)) {
$block->content = filter_xss_admin(render($block->content));
}
if (!empty($block->subject)) {
$block->title = $block->subject;
}
elseif (empty($block->title)) {
$block->title = t('No title');
}
return $block;
}
}
function _ctools_block_get_module_delta($subtype, $conf) {
if (strpos($subtype, '-')) {
return explode('-', $subtype, 2);
}
else {
return array(
$conf['module'],
$conf['delta'],
);
}
}
/**
* Provide default icon and categories for blocks when modules don't do this
* for us.
*/
function ctools_default_block_info($module, $delta, &$info) {
$core_modules = array(
'aggregator',
'block',
'blog',
'blogapi',
'book',
'color',
'comment',
'contact',
'drupal',
'filter',
'forum',
'help',
'legacy',
'locale',
'menu',
'node',
'path',
'ping',
'poll',
'profile',
'search',
'statistics',
'taxonomy',
'throttle',
'tracker',
'upload',
'user',
'watchdog',
'system',
);
if (in_array($module, $core_modules)) {
$info['icon'] = 'icon_core_block.png';
$info['category'] = t('Miscellaneous');
}
else {
$info['icon'] = 'icon_contrib_block.png';
$info['category'] = t('Miscellaneous');
}
}
/**
* These are all on behalf of modules that don't implement ctools but that
* we care about.
*/
function menu_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_block_menu.png';
$info['category'] = t('Menus');
if ($delta == 'primary-links' || $delta == 'secondary-links') {
$info['icon'] = 'icon_core_primarylinks.png';
}
}
function forum_ctools_block_info($module, $delta, &$info) {
$info['category'] = t('Activity');
switch ($delta) {
case 'active':
$info['icon'] = 'icon_core_activeforumtopics.png';
break;
case 'new':
$info['icon'] = 'icon_core_newforumtopics.png';
break;
default:
// Safety net.
ctools_default_block_info($module, $delta, $info);
}
}
function profile_ctools_block_info($module, $delta, &$info) {
// Hide the author information block which isn't as rich as what we can
// do with context.
$info = NULL;
}
function book_ctools_block_info($module, $delta, &$info) {
$info['title'] = t('Book navigation menu');
$info['icon'] = 'icon_core_block_menu.png';
$info['category'] = t('Node');
}
function blog_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_recentblogposts.png';
$info['category'] = t('Activity');
}
function poll_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_recentpoll.png';
$info['category'] = t('Activity');
}
function comment_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_recentcomments.png';
$info['category'] = t('Activity');
}
function search_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_searchform.png';
$info['category'] = t('Widgets');
}
function node_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_syndicate.png';
$info['category'] = t('Widgets');
}
function aggregator_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_syndicate.png';
$info['category'] = t('Feeds');
}
function block_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_block_empty.png';
$info['category'] = t('Custom blocks');
// The title of custom blocks from the block module is stored in the
// {block} table. Look for it in the default theme as a reasonable
// default value for the title.
$block_info_cache =& drupal_static(__FUNCTION__);
if (!isset($block_info_cache)) {
$block_info_cache = db_select('block', 'b')->fields('b')
->condition('b.module', 'block')
->condition('b.theme', variable_get('theme_default', 'bartik'))
->addTag('block_load')
->addTag('translatable')
->execute()
->fetchAllAssoc('delta');
}
if (isset($block_info_cache[$delta])) {
$info['defaults'] = array(
'override_title' => TRUE,
'override_title_text' => $block_info_cache[$delta]->title,
);
}
}
function user_ctools_block_info($module, $delta, &$info) {
$info['category'] = t('Activity');
switch ($delta) {
case 'login':
$info['icon'] = 'icon_core_userlogin.png';
$info['category'] = t('Widgets');
// Provide a custom render callback, because the default login block
// will not render on /user, /user/login, or any other URL beginning
// /user (unless it's a user-specific page such as /user/123).
$info['render callback'] = 'ctools_user_login_pane_render';
break;
case 'new':
$info['icon'] = 'icon_core_whosnew.png';
break;
case 'online':
$info['icon'] = 'icon_core_whosonline.png';
break;
default:
// Safety net.
ctools_default_block_info($module, $delta, $info);
}
}
function locale_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_languageswitcher.png';
$info['category'] = t('Widgets');
}
function statistics_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_core_popularcontent.png';
$info['category'] = t('Activity');
}
function system_ctools_block_info($module, $delta, &$info) {
// Remove the main content fake block.
if ($delta == 'main') {
$info = NULL;
return;
}
$menus = array(
'main-menu',
'management',
'navigation',
'user-menu',
);
if (in_array($delta, $menus)) {
$info['icon'] = 'icon_core_block_menu.png';
$info['category'] = t('Menus');
if ($delta == 'navigation') {
$info['icon'] = 'icon_core_navigation.png';
}
return;
}
$info['icon'] = 'icon_core_drupal.png';
if ($delta == 'help') {
$info['category'] = t('Page elements');
return;
}
$info['category'] = t('Widgets');
}
function ctools_user_login_pane_render($subtype, $conf, $panel_args, $contexts) {
list($module, $delta) = _ctools_block_get_module_delta($subtype, $conf);
// The login form is only visible to anonymous users.
global $user;
if ($user->uid) {
return;
}
$info = new stdClass();
$info->module = $module;
$info->delta = $delta;
$block = array();
$block['subject'] = t('User login');
// Manually set the content (rather than invoking block_view) because the
// block implementation won't render on certain URLs.
$block['content'] = drupal_get_form('user_login_block');
// Allow modules to modify the block before it is viewed, via either
// hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter().
drupal_alter(array(
'block_view',
"block_view_{$module}_{$delta}",
), $block, $info);
$block = (object) $block;
if (empty($block)) {
return;
}
$block->module = $module;
$block->delta = $delta;
// $block->title is not set for the blocks returned by block_block() (the
// Block module adds the title in block_list() instead), so we look it up
// manually, unless the title is overridden and does not use the %title
// placeholder.
if ($module == 'block') {
$block->title = $info->title;
}
elseif (isset($block->subject)) {
$block->title = $block->subject;
}
else {
$block->title = NULL;
}
if (isset($block->subject)) {
$block->title = $block->subject;
}
else {
$block->title = NULL;
}
if (user_access('administer blocks')) {
$block->admin_links = array(
array(
'title' => t('Configure block'),
'href' => "admin/structure/block/manage/{$module}/{$delta}/configure",
'query' => drupal_get_destination(),
),
);
}
return $block;
}
Functions
Title | Deprecated | Summary |
---|---|---|
aggregator_ctools_block_info | ||
block_ctools_block_info | ||
blog_ctools_block_info | ||
book_ctools_block_info | ||
comment_ctools_block_info | ||
ctools_block_content_type_admin_info | Output function for the 'block' content type. Outputs a block based on the module and delta supplied in the configuration. | |
ctools_block_content_type_admin_title | Returns the administrative title for a type. | |
ctools_block_content_type_content_type | Return the block content types with the specified $subtype_id. | |
ctools_block_content_type_content_types | Return all block content types available. | |
ctools_block_content_type_edit_form | Empty form so we can have the default override title. | |
ctools_block_content_type_edit_form_submit | Submit function to fix the subtype for really old panel panes. | |
ctools_block_content_type_render | Output function for the 'block' content type. Outputs a block based on the module and delta supplied in the configuration. | |
ctools_default_block_info | Provide default icon and categories for blocks when modules don't do this for us. | |
ctools_user_login_pane_render | ||
forum_ctools_block_info | ||
locale_ctools_block_info | ||
menu_ctools_block_info | These are all on behalf of modules that don't implement ctools but that we care about. | |
node_ctools_block_info | ||
poll_ctools_block_info | ||
profile_ctools_block_info | ||
search_ctools_block_info | ||
statistics_ctools_block_info | ||
system_ctools_block_info | ||
user_ctools_block_info | ||
_ctools_block_content_type_content_type | Return an info array for a specific block. | |
_ctools_block_get_module_delta | ||
_ctools_block_load_blocks | Load block info from the database. | |
_ctools_get_block_info | Fetch the stored info for a block. |