123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 |
- <?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;
- }
- else if (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 an edit form for a block.
- */
- //function ctools_block_content_type_edit_form($id, $parents, $conf) {
- // if (user_access('administer advanced pane settings')) {
- // $form['block_visibility'] = array(
- // '#type' => 'checkbox',
- // '#title' => t('Use block visibility settings (see block config)'),
- // '#default_value' => !empty($conf['block_visibility']),
- // '#description' => t('If checked, the block visibility settings for this block will apply to this block.'),
- // );
- // // Module-specific block configurations.
- // if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
- // // Specifically modify a couple of core block forms.
- // if ($module == 'block') {
- // unset($settings['submit']);
- // $settings['info']['#type'] = 'value';
- // $settings['info']['#value'] = $settings['info']['#default_value'];
- // }
- // ctools_admin_fix_block_tree($settings);
- // $form['block_settings'] = array(
- // '#type' => 'fieldset',
- // '#title' => t('Block settings'),
- // '#description' => t('Settings in this section are global and are for all blocks of this type, anywhere in the system.'),
- // '#tree' => FALSE,
- // );
- //
- //
- // $form['block_settings'] += $settings;
- // }
- // }
- //
- // return $form;
- //}
- //function ctools_admin_submit_block(&$form_values) {
- // if (!empty($form_values['block_settings'])) {
- // module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values['block_settings']);
- // }
- //}
- //
- ///**
- // * Because form api cannot collapse just part of a tree, and the block settings
- // * assume no tree, we have to collapse the tree ourselves.
- // */
- //function ctools_admin_fix_block_tree(&$form, $key = NULL) {
- // if ($key) {
- // if (!empty($form['#parents'])) {
- // $form['#parents'] = array_merge(array('configuration', 'block_settings'), $form['#parents']);
- // }
- // else if (empty($form['#tree'])) {
- // $form['#parents'] = array('configuration', 'block_settings', $key);
- // }
- // }
- //
- // if (isset($form['#type']) && $form['#type'] == 'textarea' && !empty($form['#rows']) && $form['#rows'] > 10) {
- // $form['#rows'] = 10;
- // }
- //
- // foreach (element_children($form) as $key) {
- // ctools_admin_fix_block_tree($form[$key], $key);
- // }
- //}
- /**
- * 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;
- }
- else if (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;
- }
|