panels_mini.module in Panels 7.3
Same filename and directory in other branches
This module provides mini panels which are basically panels that can be used within blocks or other panels.
File
panels_mini/panels_mini.moduleView source
<?php
/**
* @file
* panels_mini.module
*
* This module provides mini panels which are basically panels that can be
* used within blocks or other panels.
*/
/**
* Implementation of hook_permission().
*/
function panels_mini_permission() {
return array(
'create mini panels' => array(
'title' => t('Create mini panels'),
'description' => t('Create new mini panels'),
),
'administer mini panels' => array(
'title' => t('Administer mini panels'),
'description' => t('Edit and delete mini panels'),
),
);
}
/**
* Implementation of hook_menu().
*/
function panels_mini_menu() {
// Safety: go away if CTools is not at an appropriate version.
if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) {
return array();
}
$items['admin/structure/mini-panels/settings'] = array(
'title' => 'Settings',
'page callback' => 'panels_mini_settings',
'access arguments' => array(
'create mini panels',
),
'type' => MENU_LOCAL_TASK,
);
// Also provide settings on the main panel UI.
$items['admin/structure/panels/settings/panels-mini'] = array(
'title' => 'Mini panels',
'page callback' => 'panels_mini_settings',
'access arguments' => array(
'create mini panels',
),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Settings for mini panels.
*/
function panels_mini_settings() {
ctools_include('common', 'panels');
return drupal_get_form('panels_common_settings', 'panels_mini');
}
// ---------------------------------------------------------------------------
// Allow the rest of the system access to mini panels.
/**
* Implementation of hook_block_info().
*/
function panels_mini_block_info() {
// Safety: go away if CTools is not at an appropriate version.
if (!defined('PANELS_REQUIRED_CTOOLS_API') || !module_invoke('ctools', 'api_version', PANELS_REQUIRED_CTOOLS_API)) {
return array();
}
$blocks = array();
$minis = panels_mini_load_all();
foreach ($minis as $panel_mini) {
if (empty($panel_mini->disabled) && (module_exists('page_manager') || empty($panel_mini->requiredcontexts))) {
$blocks[$panel_mini->name] = array(
'info' => t('Mini panel: "@title"', array(
'@title' => $panel_mini->admin_title,
)),
'cache' => DRUPAL_NO_CACHE,
);
}
}
return $blocks;
}
/**
* Implementation of hook_block_view().
*
* @see panels_mini_panels_mini_content_type_render()
*/
function panels_mini_block_view($delta = 0) {
// Static recursion protection.
static $viewing = array();
if (!empty($viewing[$delta])) {
return;
}
$viewing[$delta] = TRUE;
$panel_mini = panels_mini_load($delta);
if (empty($panel_mini)) {
// Bail out early if the specified mini panel doesn't exist.
return;
}
ctools_include('context');
$contexts = array();
if (module_exists('page_manager') && ($current_page = page_manager_get_current_page())) {
if (!empty($current_page['contexts'])) {
$contexts = ctools_context_match_required_contexts($panel_mini->requiredcontexts, $current_page['contexts']);
}
}
drupal_alter('panels_mini_block_contexts', $contexts, $panel_mini);
$panel_mini->context = $panel_mini->display->context = ctools_context_load_contexts($panel_mini, FALSE, $contexts);
$panel_mini->display->css_id = panels_mini_get_id($panel_mini->name);
$panel_mini->display->owner = $panel_mini;
$block = array();
$block['content'] = panels_render_display($panel_mini->display);
$block['subject'] = $panel_mini->display
->get_title();
unset($viewing[$delta]);
return $block;
}
/**
* Implementation of hook_block_configure().
*/
function panels_mini_block_configure($delta = 0) {
return array(
'admin_shortcut' => array(
'#markup' => l(t('Manage this mini-panel'), 'admin/structure/mini-panels/list/' . $delta . '/edit'),
),
);
}
/**
* Implements hook_block_list_alter().
*
* Remove the block if the required contexts are not available.
*/
function panels_mini_block_list_alter(&$blocks) {
$keys_to_cache = array();
$has_cache_hit = FALSE;
foreach ($blocks as $key => $block) {
if ($block->module != 'panels_mini') {
// Ignore anything that is not a mini panel.
continue;
}
$result = cache_get('panels_mini_block_list_alter:' . $key, 'cache_panels');
if (empty($result->data)) {
// If not a cache hit, queue it for caching.
$keys_to_cache[] = $key;
}
else {
// If a cache hit, return the cached result and indicate we had a hit.
$blocks[$key] = $result->data;
$has_cache_hit = TRUE;
}
}
// If we don't need to cache anything, exit out of the function.
if (empty($keys_to_cache)) {
return;
}
$current_page = FALSE;
if (module_exists('page_manager')) {
$current_page = page_manager_get_current_page();
}
// If we didn't have any cache hits, load all at once to save time.
if (!$has_cache_hit) {
panels_mini_load_all();
}
// Iterate through all non-cached keys.
foreach ($keys_to_cache as $key) {
$block = $blocks[$key];
if ($block->module != 'panels_mini') {
// This block was added by a contrib module, leave it in the list.
continue;
}
$panel_mini = panels_mini_load($block->delta);
if (empty($panel_mini)) {
// Bail out early if the specified mini panel doesn't exist.
unset($blocks[$key]);
continue;
}
if (!empty($panel_mini->requiredcontexts)) {
if (!$current_page || empty($current_page['contexts'])) {
unset($blocks[$key]);
continue;
}
else {
$required = array();
foreach ($panel_mini->requiredcontexts as $context) {
$info = ctools_get_context($context['name']);
$required[] = new ctools_context_required($context['identifier'], $info['context name']);
}
if (!ctools_context_match_requirements($current_page['contexts'], $required)) {
unset($blocks[$key]);
continue;
}
}
}
// Cache our results.
cache_set('panels_mini_block_list_alter:' . $key, $blocks[$key], 'cache_panels', CACHE_TEMPORARY);
}
}
/**
* Implements hook_get_pane_links_alter().
*/
function panels_mini_get_pane_links_alter(&$links, $pane, $content_type) {
if ($pane->type == 'panels_mini') {
$links['top']['edit_panels_mini'] = array(
'title' => t('Edit mini panel'),
'href' => url('admin/structure/mini-panels/list/' . $pane->subtype . '/edit/content', array(
'absolute' => TRUE,
)),
'attributes' => array(
'target' => array(
'_blank',
),
),
);
}
}
/**
* Implements hook_contextual_links_view_alter().
*/
function panels_mini_contextual_links_view_alter(&$element, $items) {
// Add contextual links to all mini panel blocks with bid property.
if (isset($element['#element']['#block']) && isset($element['#element']['#block']->bid) && strpos((string) $element['#element']['#block']->bid, 'panels_mini') === 0) {
$admin_pages = array(
t('Configure mini panel settings') => 'basic',
t('Configure mini panel context') => 'context',
t('Configure mini panel layout') => 'layout',
t('Configure mini panel content') => 'content',
);
foreach ($admin_pages as $title => $tail) {
$element['#links']['mini-panels-' . $tail] = array(
'title' => $title,
'href' => 'admin/structure/mini-panels/list/' . $element['#element']['#block']->delta . '/edit/' . $tail,
'query' => drupal_get_destination(),
);
}
}
}
/**
* Statically store all used IDs to ensure all mini panels get a unique id.
*/
function panels_mini_get_id($name) {
$id_cache =& drupal_static(__FUNCTION__, array());
$id = 'mini-panel-' . $name;
if (!empty($id_cache[$name])) {
$id .= "-" . $id_cache[$name]++;
}
else {
$id_cache[$name] = 1;
}
return $id;
}
// ---------------------------------------------------------------------------
// Database functions.
/**
* Create a new page with defaults appropriately set from schema.
*/
function panels_mini_new($set_defaults = TRUE) {
ctools_include('export');
return ctools_export_new_object('panels_mini', $set_defaults);
}
/**
* Load a single mini panel.
*/
function panels_mini_load($name) {
$cache =& drupal_static('panels_mini_load_all', array());
// We use array_key_exists because failed loads will be NULL and
// isset() will try to load it again.
if (!array_key_exists($name, $cache)) {
$cid = 'panels_mini_load:' . $name;
$result = cache_get($cid, 'cache_panels');
if (!empty($result->data)) {
$cache[$name] = $result->data;
}
else {
ctools_include('export');
$result = ctools_export_load_object('panels_mini', 'names', array(
$name,
));
if (isset($result[$name])) {
if (empty($result[$name]->display)) {
$result[$name]->display = panels_load_display($result[$name]->did);
if (!empty($result[$name]->title) && empty($result[$name]->display->title)) {
$result[$name]->display->title = $result[$name]->title;
}
}
$cache[$name] = $result[$name];
if (!empty($result[$name]->title) && empty($result[$name]->admin_title)) {
$cache[$name]->admin_title = $result[$name]->title;
}
cache_set($cid, $cache[$name], 'cache_panels', CACHE_TEMPORARY);
}
else {
$cache[$name] = NULL;
}
}
}
if (isset($cache[$name])) {
return $cache[$name];
}
}
/**
* Load all mini panels.
*/
function panels_mini_load_all($reset = FALSE) {
$cache =& drupal_static('panels_mini_load_all', array());
static $all_loaded = FALSE;
// We check our own private static because individual minis could have
// been loaded prior to load all and we need to know that.
if (!$all_loaded || $reset) {
$all_loaded = TRUE;
if ($reset) {
$cache = array();
}
else {
$panel_names = db_select('panels_mini', 'pm')
->fields('pm', array(
'name',
))
->execute();
$cids = array();
foreach ($panel_names as $name) {
$cids[] = 'panels_mini_load:' . $name->name;
}
$output = cache_get_multiple($cids, 'cache_panels');
foreach ($output as $mini) {
if (!empty($mini->data)) {
$mini = $mini->data;
$cache[$mini->name] = $mini;
}
}
}
ctools_include('export');
$minis = ctools_export_load_object('panels_mini');
$dids = array();
foreach ($minis as $mini) {
if (empty($cache[$mini->name])) {
if (!empty($mini->did)) {
$dids[$mini->did] = $mini->name;
}
else {
// Translate old style titles into new titles.
if (!empty($mini->title) && empty($mini->display->title)) {
$mini->display->title = $mini->title;
}
}
// Translate old style titles into new titles.
if (isset($mini->title) && empty($mini->admin_title)) {
$mini->admin_title = $mini->title;
}
$cache[$mini->name] = $mini;
}
}
$displays = panels_load_displays(array_keys($dids));
foreach ($displays as $did => $display) {
if (!empty($cache[$dids[$did]]->title) && empty($display->title)) {
$display->title = $cache[$dids[$did]]->title;
}
$cache[$dids[$did]]->display = $display;
}
}
// Strip out NULL entries that may have been added by panels_mini_load().
return array_filter($cache);
}
/**
* Write a mini panel to the database.
*/
function panels_mini_save(&$mini) {
if (!empty($mini->display)) {
$mini->display->storage_id = $mini->name;
$display = panels_save_display($mini->display);
$mini->did = $display->did;
}
// Clear the panels_mini_load cache.
cache_clear_all('panels_mini_load:', 'cache_panels', TRUE);
cache_clear_all('panels_mini_block_list_alter:', 'cache_panels', TRUE);
$update = isset($mini->pid) && $mini->pid != 'new' ? array(
'pid',
) : array();
drupal_write_record('panels_mini', $mini, $update);
return $mini;
}
/**
* Remove a mini panel.
*/
function panels_mini_delete($mini) {
db_delete('panels_mini')
->condition('name', $mini->name)
->execute();
if (db_table_exists('block') && $mini->type != t('Overridden')) {
// Also remove from block table as long as there isn't a default that may appear.
db_delete('block')
->condition('delta', $mini->name)
->condition('module', 'panels_mini')
->execute();
}
return panels_delete_display($mini->did);
}
/**
* Export a mini panel.
*/
function panels_mini_export($mini, $indent = '') {
ctools_include('export');
$output = ctools_export_object('panels_mini', $mini, $indent);
// Export the primary display.
$display = !empty($mini->display) ? $mini->display : panels_load_display($mini->did);
$output .= panels_export_display($display, $indent);
$output .= $indent . '$mini->display = $display' . ";\n";
return $output;
}
/**
* Remove the block version of mini panels from being available content types.
*/
function panels_mini_ctools_block_info($module, $delta, &$info) {
$info = NULL;
}
/**
* Implementation of hook_ctools_plugin_directory() to let the system know
* we implement task and task_handler plugins.
*/
function panels_mini_ctools_plugin_directory($module, $plugin) {
if ($module == 'ctools' && ($plugin == 'content_types' || $plugin == 'export_ui')) {
return 'plugins/' . $plugin;
}
if ($module == 'panels' && $plugin == 'panels_storage') {
return 'plugins/' . $plugin;
}
}
/**
* Implements hook_default_panels_mini_alter().
*
* If a default Panels display has no storage type, set it.
*/
function panels_default_panels_mini_alter(&$mini_panels) {
foreach ($mini_panels as &$mini_panel) {
$display =& $mini_panel->display;
if (empty($display->storage_type)) {
$display->storage_type = 'panels_mini';
$display->storage_id = $mini_panel->name;
}
}
}
/**
* Get the display cache for the panels_mini plugin.
*/
function _panels_mini_panels_cache_get($key) {
ctools_include('export-ui');
$plugin = ctools_get_export_ui('panels_mini');
$handler = ctools_export_ui_get_handler($plugin);
if (!$handler) {
return;
}
$item = $handler
->edit_cache_get($key);
if (!$item) {
$item = ctools_export_crud_load($handler->plugin['schema'], $key);
}
return array(
$handler,
$item,
);
}
/**
* Get display edit cache for the panels mini export UI.
*
* The key is the second half of the key in this form:
* panels_mini:TASK_NAME:HANDLER_NAME;
*/
function panels_mini_panels_cache_get($key) {
ctools_include('common', 'panels');
list($handler, $item) = _panels_mini_panels_cache_get($key);
if (isset($item->mini_panels_display_cache)) {
return $item->mini_panels_display_cache;
}
$cache = new stdClass();
$cache->display = $item->display;
$cache->display->context = ctools_context_load_contexts($item);
$cache->display->cache_key = 'panels_mini:' . $key;
$cache->display->storage_type = 'panels_mini';
// Temporary storage id that's replaced in panels_mini_save().
$cache->display->storage_id = 'panels_mini';
$cache->content_types = panels_common_get_allowed_types('panels_mini', $cache->display->context);
$cache->display_title = TRUE;
// @TODO support locking
$cache->locked = FALSE;
return $cache;
}
/**
* Store a display edit in progress in the page cache.
*/
function panels_mini_panels_cache_set($key, $cache) {
list($handler, $item) = _panels_mini_panels_cache_get($key);
$item->mini_panels_display_cache = $cache;
$handler
->edit_cache_set_key($item, $key);
}
/**
* Save all changes made to a display using the panels mini UI cache.
*/
function panels_mini_panels_cache_clear($key, $cache) {
list($handler, $item) = _panels_mini_panels_cache_get($key);
$handler
->edit_cache_clear($item);
}
/**
* Save all changes made to a display using the panels mini UI cache.
*/
function panels_mini_panels_cache_save($key, $cache) {
list($handler, $item) = _panels_mini_panels_cache_get($key);
$item->display = $cache->display;
panels_mini_save($item);
$handler
->edit_cache_clear($item);
}
/**
* Break the lock on a panels mini page.
*/
function panels_mini_panels_cache_break_lock($key, $cache) {
}
/**
* Implements hook_panels_pre_render().
*/
function panels_mini_panels_pre_render($display, $renderer) {
if (isset($display->owner->table) && $display->owner->table == 'panels_mini' && $renderer instanceof panels_renderer_standard) {
$renderer->show_empty_layout = FALSE;
}
}
/**
* Implementation of hook_panels_dashboard_blocks().
*
* Adds mini panels information to the Panels dashboard.
*/
function panels_mini_panels_dashboard_blocks(&$vars) {
$vars['links']['panels_mini'] = array(
'title' => l(t('Mini panel'), 'admin/structure/mini-panels/add'),
'description' => t('Mini panels are small content areas exposed as blocks, for when you need to have complex block layouts or layouts within layouts.'),
'weight' => -1,
);
// Load all mini panels and their displays.
$panel_minis = panels_mini_load_all();
$count = 0;
$rows = array();
foreach ($panel_minis as $panel_mini) {
$rows[] = array(
check_plain($panel_mini->admin_title),
array(
'data' => l(t('Edit'), "admin/structure/mini-panels/list/{$panel_mini->name}/edit"),
'class' => 'links',
),
);
// Only show 10.
if (++$count >= 10) {
break;
}
}
if ($rows) {
$content = theme('table', array(
'rows' => $rows,
'attributes' => array(
'class' => 'panels-manage',
),
));
}
else {
$content = '<p>' . t('There are no mini panels.') . '</p>';
}
$vars['blocks']['panels_mini'] = array(
'weight' => -100,
'title' => t('Manage mini panels'),
'link' => l(t('Go to list'), 'admin/structure/mini-panels'),
'content' => $content,
'class' => 'dashboard-mini-panels',
'section' => 'left',
);
}
/**
* Implements template_preprocess_ctools_wizard_trail().
*
* Customize the divider used in the CTools wizard to build the edit pages for
* Mini Panels as a stop-gap measure until the UX can be completely re-done.
*/
function panels_mini_preprocess_ctools_wizard_trail(&$variables) {
$variables['divider'] = ' | ';
drupal_add_css(drupal_get_path('module', 'panels_mini') . '/panels_mini.css');
}
Functions
Name![]() |
Description |
---|---|
panels_default_panels_mini_alter | Implements hook_default_panels_mini_alter(). |
panels_mini_block_configure | Implementation of hook_block_configure(). |
panels_mini_block_info | Implementation of hook_block_info(). |
panels_mini_block_list_alter | Implements hook_block_list_alter(). |
panels_mini_block_view | Implementation of hook_block_view(). |
panels_mini_contextual_links_view_alter | Implements hook_contextual_links_view_alter(). |
panels_mini_ctools_block_info | Remove the block version of mini panels from being available content types. |
panels_mini_ctools_plugin_directory | Implementation of hook_ctools_plugin_directory() to let the system know we implement task and task_handler plugins. |
panels_mini_delete | Remove a mini panel. |
panels_mini_export | Export a mini panel. |
panels_mini_get_id | Statically store all used IDs to ensure all mini panels get a unique id. |
panels_mini_get_pane_links_alter | Implements hook_get_pane_links_alter(). |
panels_mini_load | Load a single mini panel. |
panels_mini_load_all | Load all mini panels. |
panels_mini_menu | Implementation of hook_menu(). |
panels_mini_new | Create a new page with defaults appropriately set from schema. |
panels_mini_panels_cache_break_lock | Break the lock on a panels mini page. |
panels_mini_panels_cache_clear | Save all changes made to a display using the panels mini UI cache. |
panels_mini_panels_cache_get | Get display edit cache for the panels mini export UI. |
panels_mini_panels_cache_save | Save all changes made to a display using the panels mini UI cache. |
panels_mini_panels_cache_set | Store a display edit in progress in the page cache. |
panels_mini_panels_dashboard_blocks | Implementation of hook_panels_dashboard_blocks(). |
panels_mini_panels_pre_render | Implements hook_panels_pre_render(). |
panels_mini_permission | Implementation of hook_permission(). |
panels_mini_preprocess_ctools_wizard_trail | Implements template_preprocess_ctools_wizard_trail(). |
panels_mini_save | Write a mini panel to the database. |
panels_mini_settings | Settings for mini panels. |
_panels_mini_panels_cache_get | Get the display cache for the panels_mini plugin. |