';
$output .= t('You can edit existing mini panels, or click add to create a new one.');
$output .= '
';
break;
case 'admin/panels/panel-mini/add':
$output = '';
$output .= t('Mini panels are the small variants of panel pages. Instead of pages, they define blocks.');
$output .= '
';
break;
}
return $output;
}
/**
* Implementation of hook_perm().
*/
function panels_mini_perm() {
return array('create mini panels', 'administer mini panels');
}
/**
* Implementation of hook_menu().
*/
function panels_mini_menu($may_cache) {
if ($may_cache) {
$access = user_access('create mini panels');
$items[] = array(
'path' => 'admin/panels/panel-mini',
'title' => t('Mini panels'),
'access' => $access,
'callback' => 'panels_mini_list_page',
'description' => t('Create and administer mini panels (panels exposed as blocks).'),
);
$items[] = array(
'path' => 'admin/panels/panel-mini/list',
'title' => t('List'),
'access' => $access,
'callback' => 'panels_mini_list_page',
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/panels/panel-mini/add',
'title' => t('Add'),
'access' => $access,
'callback' => 'panels_mini_add_page',
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/panels/panel-mini/import',
'title' => t('Import'),
'access' => $access,
'callback' => 'panels_mini_import_mini',
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/panels/panel-mini/settings',
'title' => t('Settings'),
'access' => $access,
'callback' => 'panels_mini_settings',
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/panels/panel-mini/disable',
'access' => $access,
'callback' => 'panels_mini_disable_page',
'weight' => -1,
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/panels/panel-mini/enable',
'access' => $access,
'callback' => 'panels_mini_enable_page',
'weight' => -1,
'type' => MENU_CALLBACK,
);
}
else {
if (arg(0) == 'admin' && arg(1) == 'panels' && arg(2) == 'panel-mini') {
$mini = panels_mini_load(arg(3));
if ($mini && empty($mini->disabled)) {
$items = array();
panels_mini_menu_items($items, "admin/panels/panel-mini/$mini->name", $mini);
}
}
}
return $items;
}
function panels_mini_menu_items(&$items, $base, $panel_mini) {
$access = user_access('administer mini panels');
if ($access) {
$items[] = array(
'path' => $base,
'title' => t('Preview'),
'access' => $access,
'callback' => 'panels_mini_preview_panel',
'callback arguments' => array($panel_mini),
'weight' => -10,
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => $base . '/preview',
'title' => t('Preview'),
'access' => $access,
'callback' => 'panels_mini_preview_panel',
'callback arguments' => array($panel_mini),
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => $base .'/edit/layout',
'title' => t('Layout'),
'access' => $access,
'callback' => 'panels_mini_edit_layout',
'callback arguments' => array($panel_mini),
'weight' => -9,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => $base .'/edit/general',
'title' => t('Settings'),
'access' => $access,
'callback' => 'panels_mini_edit',
'callback arguments' => array($panel_mini),
'weight' => -5,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => $base .'/edit/settings',
'title' => t('Layout settings'),
'access' => $access,
'callback' => 'panels_mini_edit_layout_settings',
'callback arguments' => array($panel_mini),
'weight' => -3,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => $base . '/edit/context',
'title' => t('Context'),
'access' => $access,
'callback' => 'panels_mini_edit_context',
'callback arguments' => array($panel_mini),
'weight' => -2,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => $base .'/edit/content',
'title' => t('Content'),
'access' => $access,
'callback' => 'panels_mini_edit_content',
'callback arguments' => array($panel_mini),
'weight' => -1,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => $base . '/export',
'title' => t('Export'),
'access' => $access,
'callback' => 'drupal_get_form',
'callback arguments' => array('panels_mini_edit_export', $panel_mini),
'weight' => 0,
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => $base .'/delete',
'title' => t('Delete mini panel'),
'access' => user_access('create mini panels'),
'callback' => 'drupal_get_form',
'callback arguments' => array('panels_mini_delete_confirm', $panel_mini),
'type' => MENU_CALLBACK,
);
}
}
// ---------------------------------------------------------------------------
// Mini panel administrative pages.
/**
* Settings for mini panels.
*/
function panels_mini_settings() {
panels_load_include('common');
return drupal_get_form('panels_common_settings', 'panels_mini');
}
/**
* Provide a list of mini panels, with links to edit or delete them.
*/
function panels_mini_list_page() {
panels_load_include('plugins');
$layouts = panels_get_layouts();
$items = array();
$sorts = array();
$header = array(
array('data' => t('Title'), 'field' => 'title'),
array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'),
array('data' => t('Type'), 'field' => 'type'),
t('Layout'),
t('Operations'),
);
// Load all mini panels and their displays.
$panel_minis = panels_mini_load_all();
$dids = array();
foreach ($panel_minis as $panel_mini) {
if (empty($panel_mini->display)) {
$dids[] = $panel_mini->did;
}
}
$displays = panels_load_displays($dids);
foreach ($panel_minis as $panel_mini) {
$ops = array();
if (empty($panel_mini->disabled)) {
$ops[] = l(t('Edit'), "admin/panels/panel-mini/$panel_mini->name/edit/general");
$ops[] = l(t('Export'), "admin/panels/panel-mini/$panel_mini->name/export");
}
if ($panel_mini->type != t('Default')) {
$text = ($panel_mini->type == t('Overridden')) ? t('Revert') : t('Delete');
$ops[] = l($text, "admin/panels/panel-mini/$panel_mini->name/delete");
}
else {
if (empty($panel_mini->disabled)) {
$ops[] = l(t('Disable'), "admin/panels/panel-mini/disable/$panel_mini->name", NULL, drupal_get_destination());
}
else {
$ops[] = l(t('Enable'), "admin/panels/panel-mini/enable/$panel_mini->name", NULL, drupal_get_destination());
}
}
$item = array();
$item[] = check_plain($panel_mini->title);
$item[] = check_plain($panel_mini->name);
// this is safe as it's always programmatic
$item[] = $panel_mini->type;
if (empty($panel_mini->display)) {
$panel_mini->display = $displays[$panel_mini->did];
}
$item[] = check_plain($layouts[$panel_mini->display->layout]['title']);
$item[] = implode(' | ', $ops);
$items[] = $item;
$ts = tablesort_init($header);
switch ($ts['sql']) {
case 'title':
$sorts[] = $item[0];
break;
case 'name':
default:
$sorts[] = $item[1];
break;
case 'type':
$sorts[] = $panel_mini->type . $item[0];
break;
}
}
if (drupal_strtolower($ts['sort']) == 'desc') {
arsort($sorts);
}
else {
asort($sorts);
}
$i = array();
foreach ($sorts as $id => $title) {
$i[] = $items[$id];
}
$output = theme('table', $header, $i);
return $output;
}
/**
* Provide a form to confirm deletion of a mini panel.
*/
function panels_mini_delete_confirm($panel_mini) {
if (!is_object($panel_mini)) {
$panel_mini = panels_mini_load($panel_mini);
}
$form['pid'] = array('#type' => 'value', '#value' => $panel_mini->pid);
$form['did'] = array('#type' => 'value', '#value' => $panel_mini->did);
return confirm_form($form,
t('Are you sure you want to delete the mini panel "@title"?', array('@title' => $panel_mini->title)),
$_GET['destination'] ? $_GET['destination'] : 'admin/panels/panel-mini',
t('This action cannot be undone.'),
t('Delete'), t('Cancel')
);
}
/**
* Handle the submit button to delete a mini panel.
*/
function panels_mini_delete_confirm_submit($form_id, $form) {
if ($form['confirm']) {
panels_mini_delete((object) $form);
return 'admin/panels/panel-mini';
}
}
/**
* Provide an administrative preview of a mini panel.
*/
function panels_mini_preview_panel($mini) {
$mini->display->args = array();
$mini->display->css_id = panels_mini_get_id($mini->name);
panels_load_include('plugins');
$mini->context = $mini->display->context = panels_context_load_contexts($mini);
drupal_set_title(filter_xss_admin($mini->title));
return panels_render_display($mini->display);
}
/**
* Page callback to export a mini panel to PHP code.
*/
function panels_mini_edit_export($panel_mini) {
if (!is_object($panel_mini)) {
$panel_mini = panels_mini_load($panel_mini);
}
drupal_set_title(check_plain($panel_mini->title));
$code = panels_mini_export($panel_mini);
$lines = substr_count($code, "\n");
$form['code'] = array(
'#type' => 'textarea',
'#title' => $panel_mini->title,
'#default_value' => $code,
'#rows' => $lines,
);
return $form;
}
/**
* Page callback to import a mini panel from PHP code.
*/
function panels_mini_import_mini() {
if ($_POST['form_id'] == 'panels_mini_edit_form') {
$panel_mini = unserialize($_SESSION['pm_import']);
drupal_set_title(t('Import panel mini "@s"', array('@s' => $panel_mini->title)));
return drupal_get_form('panels_mini_edit_form', $panel_mini);
}
return drupal_get_form('panels_mini_import_form');
}
/**
* Form for the mini panel import.
*/
function panels_mini_import_form() {
$form['panel_mini'] = array(
'#type' => 'textarea',
'#title' => t('Panel mini code'),
'#cols' => 60,
'#rows' => 15,
'#description' => t('Cut and paste the results of an exported mini panel here.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
$form['#redirect'] = NULL;
return $form;
}
/**
* Handle the submit button on importing a mini panel.
*/
function panels_mini_import_form_submit($form_id, $form) {
ob_start();
eval($form['panel_mini']);
ob_end_clean();
if (isset($mini)) {
drupal_set_title(t('Import mini panel "@s"', array('@s' => $mini->title)));
// As $mini contains non-stdClass objects,
// it needs to be serialized before being stored in the session variable.
$_SESSION['pm_import'] = serialize($mini);
$output = drupal_get_form('panels_mini_edit_form', $mini);
print theme('page', $output);
exit;
}
else {
drupal_set_message(t('Unable to get a mini panel out of that.'));
}
}
/**
* Handle the add mini panel page.
*/
function panels_mini_add_page($layout = NULL) {
panels_load_include('plugins');
$layouts = panels_get_layouts();
if ($layout === NULL) {
foreach ($layouts as $id => $layout) {
$output .= panels_print_layout_link($id, $layout, $_GET['q'] .'/'. $id);
}
return $output;
}
if (!$layouts[$layout]) {
return drupal_not_found();
}
$panel_mini = new stdClass();
$panel_mini->display = panels_new_display();
$panel_mini->display->layout = $layout;
$panel_mini->pid = 'new';
$panel_mini->did = 'new';
return panels_mini_edit($panel_mini);
}
/**
* Edit a mini panel.
*
* Called from both the add and edit points to provide for common flow.
*/
function panels_mini_edit($panel_mini) {
if (!is_object($panel_mini)) {
$panel_mini = panels_mini_load($panel_mini);
}
drupal_set_title(check_plain($panel_mini->title));
return drupal_get_form('panels_mini_edit_form', $panel_mini);
}
/**
* Form to edit the settings of a mini panel.
*/
function panels_mini_edit_form($panel_mini) {
panels_load_include('common');
drupal_add_css(panels_get_path('css/panels_admin.css'));
$form['pid'] = array(
'#type' => 'value',
'#value' => $panel_mini->pid,
);
$form['panel_mini'] = array(
'#type' => 'value',
'#value' => $panel_mini,
);
$form['right'] = array(
'#prefix' => '',
'#suffix' => '
',
);
$form['left'] = array(
'#prefix' => '',
'#suffix' => '
',
);
$form['left']['settings'] = array(
'#type' => 'fieldset',
'#title' => t('Settings'),
);
$form['left']['settings']['title'] = array(
'#type' => 'textfield',
'#size' => 24,
'#default_value' => $panel_mini->title,
'#title' => t('Mini panel title'),
'#description' => t('The title for this mini panel. It can be overridden in the block configuration.'),
);
$form['left']['settings']['name'] = array(
'#type' => 'textfield',
'#size' => 24,
'#default_value' => $panel_mini->name,
'#title' => t('Mini panel name'),
'#description' => t('A unique name used to identify this panel page internally. It must be only be alpha characters and underscores. No spaces, numbers or uppercase characters.'),
);
$form['left']['settings']['category'] = array(
'#type' => 'textfield',
'#size' => 24,
'#default_value' => $panel_mini->category,
'#title' => t('Mini panel category'),
'#description' => t("The category that this mini-panel will be grouped into on the Add Content form. Only upper and lower-case alphanumeric characters are allowed. If left blank, defaults to 'Mini panels'."),
);
panels_load_include('plugins');
$panel_mini->context = $panel_mini->display->context = panels_context_load_contexts($panel_mini);
$form['right']['layout'] = array(
'#type' => 'fieldset',
'#title' => t('Layout'),
);
$layout = panels_get_layout($panel_mini->display->layout);
$form['right']['layout']['layout-icon'] = array(
'#value' => panels_print_layout_icon($panel_mini->display->layout, $layout),
);
$form['right']['layout']['layout-display'] = array(
'#value' => check_plain($layout['title']),
);
$form['right']['layout']['layout-content'] = array(
'#value' => theme('panels_common_content_list', $panel_mini->display),
);
$contexts = theme('panels_common_context_list', $panel_mini);
if ($contexts) {
$form['right']['context'] = array(
'#type' => 'fieldset',
'#title' => t('Contexts'),
);
$form['right']['context']['context'] = array(
'#value' => $contexts,
);
}
$label = ($panel_mini->pid == 'new') ? t('Save and proceed') : t('Save');
$form['submit'] = array(
'#type' => 'submit',
'#value' => $label,
);
return $form;
}
/**
* Validate submission of the mini panel edit form.
*/
function panels_mini_edit_form_validate($form_id, $form_values, $form) {
// Test uniqueness of name:
if (!$form_values['name']) {
form_error($form['left']['settings']['name'], t('Panel mini name is required.'));
}
else if (preg_match("/[^A-Za-z0-9_]/", $form_values['name'])) {
form_error($form['left']['settings']['name'], t('Name must be alphanumeric or underscores only.'));
}
else if (preg_match("/[^A-Za-z0-9 ]/", $form_values['category'])) {
form_error($form['left']['settings']['category'], t('Categories may contain only alphanumerics or spaces.'));
}
else {
$query = "SELECT pid FROM {panels_mini} WHERE name = '%s'";
if (!empty($form_values['pid']) && is_numeric($form_values['pid'])) {
$query .= " AND pid != $form_values[pid]";
}
if (db_result(db_query($query, $form_values['name']))) {
form_error($form['left']['settings']['name'], t('Panel name must be unique.'));
}
}
}
/**
* Process submission of the mini panel edit form.
*/
function panels_mini_edit_form_submit($form_id, $form_values) {
$panel_mini = $form_values['panel_mini'];
if ($panel_mini->pid != 'new' && $panel_mini->name != $form_values['name']) {
// update all existing mini panels to point to this one appropriately.
db_query("UPDATE {blocks} b SET delta = '%s' WHERE b.module = 'panels_mini' AND b.delta = '%s'", $form_values['name'], $panel_mini->name);
// Above was blocks; these are actual panel panes.
$result = db_query("SELECT * FROM {panels_pane} WHERE type = 'panels_mini' and subtype = '%s'", $panel_mini->name);
while ($pane = db_fetch_object($result)) {
$conf = unserialize($pane->configuration);
$conf['name'] = $form_values['name'];
db_query("UPDATE {panels_pane} SET configuration = '%s', subtype = '%s' WHERE pid = %d", serialize($conf), $conf['name'], $pane->pid);
}
}
$panel_mini->title = $form_values['title'];
$panel_mini->name = $form_values['name'];
$panel_mini->category = empty($form_values['category']) ? '' : $form_values['category'];
if ($panel_mini->pid == 'new') {
unset($_SESSION['pm_import']);
drupal_set_message(t('Your new mini panel %title has been saved.', array('%title' => $panel_mini->title)));
panels_mini_save($panel_mini);
$GLOBALS['form_values']['pid'] = $panel_mini->pid;
$layout = panels_get_layout($panel_mini->display->layout);
if ($layout['settings form']) {
return "admin/panels/panel-mini/$panel_mini->name/edit/settings/next";
}
return "admin/panels/panel-mini/$panel_mini->name/edit/context/next";
}
else {
drupal_set_message(t('Your changes have been saved.'));
panels_mini_save($panel_mini);
}
}
/**
* Form to edit context features of a mini panel.
*/
function panels_mini_edit_context($panel_mini, $next = NULL) {
if (!empty($_POST)) {
$panel_mini = panels_common_cache_get('panel_object:panel_mini', $panel_mini->name);
}
else {
panels_common_cache_set('panel_object:panel_mini', $panel_mini->name, $panel_mini);
}
drupal_set_title(check_plain($panel_mini->title));
return drupal_get_form('panels_mini_context_form', $panel_mini, $next);
}
/**
* Form to edit the context settings of a mini panel.
*/
function panels_mini_context_form($panel_mini, $next = NULL) {
drupal_add_css(panels_get_path('css/panels_admin.css'));
panels_load_include('plugins');
$layout = panels_get_layout($panel_mini->display->layout);
$form['pid'] = array(
'#type' => 'value',
'#value' => $panel_mini->pid,
);
$form['panel_mini'] = array(
'#type' => 'value',
'#value' => $panel_mini,
);
$form['right'] = array(
'#prefix' => '',
'#suffix' => '
',
);
$form['left'] = array(
'#prefix' => '',
'#suffix' => '
',
);
panels_load_include('common');
$settings = panels_common_add_context_form('panel_mini', $form, $form['right']['contexts_table'], $panel_mini);
$settings += panels_common_add_required_context_form('panel_mini', $form, $form['left']['required_contexts_table'], $panel_mini);
$settings += panels_common_add_relationship_form('panel_mini', $form, $form['right']['relationships_table'], $panel_mini);
panels_common_add_context_js($settings);
$label = $next ? t('Save and proceed') : t('Save');
$form['submit'] = array(
'#type' => 'submit',
'#value' => $label,
);
return $form;
}
/**
* Process submission of the mini panel edit form.
*/
function panels_mini_context_form_submit($form_id, $form_values) {
$panel_mini = $form_values['panel_mini'];
// Organize these from the common form.
panels_common_save_context('context', $panel_mini->contexts, $form_values);
panels_common_save_context('requiredcontext', $panel_mini->requiredcontexts, $form_values);
panels_common_save_context('relationship', $panel_mini->relationships, $form_values);
drupal_set_message(t('Your changes have been saved.'));
panels_mini_save($panel_mini);
panels_common_cache_clear('panel_object:panel_mini', $panel_mini->name);
if ($form_values['submit'] == t('Save and proceed')) {
return "admin/panels/panel-mini/$panel_mini->name/edit/content";
}
}
/**
* Enable a default mini panel.
*/
function panels_mini_enable_page($name = NULL) {
$defaults = panels_mini_default_panels();
if (isset($defaults[$name])) {
$status = variable_get('panel_mini_defaults', array());
$status[$name] = FALSE;
variable_set('panel_mini_defaults', $status);
drupal_set_message(t('Panel mini enabled'));
}
drupal_goto();
}
/**
* Disable a default mini panel.
*/
function panels_mini_disable_page($name = NULL) {
$defaults = panels_mini_default_panels();
if (isset($defaults[$name])) {
$status = variable_get('panel_mini_defaults', array());
$status[$name] = TRUE;
variable_set('panel_mini_defaults', $status);
drupal_set_message(t('Panel mini disabled'));
}
drupal_goto();
}
/**
* Pass through to the panels content editor.
*/
function panels_mini_edit_content($panel_mini) {
if (!is_object($panel_mini)) {
$panel_mini = panels_mini_load($panel_mini);
}
panels_load_include('plugins');
// Collect a list of contexts required by the arguments on this page.
$panel_mini->display->context = $contexts = panels_context_load_contexts($panel_mini);
panels_load_include('common');
$content_types = panels_common_get_allowed_types('panels_mini', $contexts);
$output = panels_edit($panel_mini->display, NULL, $content_types);
if (is_object($output)) {
$panel_mini->display = $output;
$panel_mini->did = $output->did;
panels_mini_save($panel_mini);
drupal_goto("admin/panels/panel-mini/$panel_mini->name/edit/content");
}
// Print this with theme('page') so that blocks are disabled while editing a display.
// This is important because negative margins in common block layouts (i.e, Garland)
// messes up the drag & drop.
drupal_set_title(check_plain($panel_mini->title));
print theme('page', $output, FALSE);
}
/**
* Pass through to the panels layout editor.
*/
function panels_mini_edit_layout($panel_mini) {
if (!is_object($panel_mini)) {
$panel_mini = panels_mini_load($panel_mini);
}
$output = panels_edit_layout($panel_mini->display, t('Save'));
if (is_object($output)) {
$panel_mini->display = $output;
$panel_mini->did = $output->did;
panels_mini_save($panel_mini);
drupal_goto("admin/panels/panel-mini/$panel_mini->name/edit/layout");
}
drupal_set_title(check_plain($panel_mini->title));
return $output;
}
/**
* Pass through to the panels layout settings editor.
*/
function panels_mini_edit_layout_settings($panel_mini, $next = NULL) {
if (!is_object($panel_mini)) {
$panel_mini = panels_mini_load($panel_mini);
}
if (empty($next)) {
$button = t('Save');
$dest = "admin/panels/panel-mini/$panel_mini->name/edit/settings";
}
else {
$button = t('Save and proceed');
$dest = "admin/panels/panel-mini/$panel_mini->name/edit/context/next";
}
$output = panels_edit_layout_settings($panel_mini->display, $button, NULL, $panel_mini->title);
if (is_object($output)) {
$panel_mini->display = $output;
$panel_mini->did = $output->did;
panels_mini_save($panel_mini);
drupal_goto($dest);
}
drupal_set_title(check_plain($panel_mini->title));
return $output;
}
// ---------------------------------------------------------------------------
// Allow the rest of the system access to mini panels
/**
* Implementation of hook_block().
*
* Expose qualifying mini panels to Drupal's block system.
*/
function panels_mini_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks = array();
$minis = panels_mini_load_all();
foreach ($minis as $panel_mini) {
if (empty($panel_mini->disabled) && empty($panel_mini->requiredcontext)) {
$title = $panel_mini->hide_title ? t('Mini panel: %title (Title will be hidden)', array('%title' => $panel_mini->title)) : t('Mini panel: %title', array('%title' => $panel_mini->title));
$blocks[$panel_mini->pid] = array(
'info' => $title,
);
}
}
return $blocks;
}
elseif ($op == 'view') {
$panel_mini = panels_mini_load($delta);
panels_load_include('plugins');
$panel_mini->context = $panel_mini->display->context = panels_context_load_contexts($panel_mini);
$panel_mini->display->css_id = panels_mini_get_id($panel_mini->name);
$block = array(
'subject' => $panel_mini->hide_title ? '' : check_plain($panel_mini->title),
'content' => panels_render_display($panel_mini->display),
);
return $block;
}
}
/**
* Expose all mini panels to our own system.
*/
function panels_mini_panels_content_types() {
$items['panels_mini'] = array(
'title' => t('Mini panels'),
'content_types' => 'panels_mini_content_types',
'render callback' => 'panels_mini_content',
'add callback' => 'panels_mini_add_mini_panel',
'edit callback' => 'panels_mini_edit_mini_panel',
'title callback' => 'panels_mini_title_mini_panel',
);
return $items;
}
/**
* Return each available mini panel available as a subtype.
*/
function panels_mini_content_types() {
$types = array();
foreach (panels_mini_load_all() as $mini) {
if (!empty($mini->disabled)) {
continue;
}
$types[$mini->name] = array(
'title' => filter_xss_admin($mini->title),
// For now mini panels will just use the contrib block icon.
'icon' => 'icon_contrib_block.png',
'path' => panels_get_path("content_types/block"),
'description' => filter_xss_admin($mini->title),
'category' => array(!empty($mini->category) ? filter_xss_admin($mini->category) : t('Mini panel'), -8),
);
if (!empty($mini->requiredcontexts)) {
$types[$mini->name]['required context'] = array();
foreach ($mini->requiredcontexts as $context) {
$info = panels_get_context($context['name']);
// TODO: allow an optional setting
$types[$mini->name]['required context'][] = new panels_required_context($context['identifier'], $info['context name']);
}
}
}
return $types;
}
/**
* Statically store all used IDs to ensure all mini panels get a unique id.
*/
function panels_mini_get_id($name) {
static $id_cache = array();
$id = 'mini-panel-' . $name;
if (!empty($id_cache[$name])) {
$id .= "-" . $id_cache[$name]++;
}
else {
$id_cache[$name] = 1;
}
return $id;
}
/**
* Render a mini panel called from a panels display.
*/
function panels_mini_content($conf, $panel_args, &$contexts) {
$mini = panels_mini_load($conf['name']);
if (!$mini) {
return FALSE;
}
panels_load_include('plugins');
// Load up any contexts we might be using.
$context = panels_context_match_required_contexts($mini->requiredcontexts, $contexts);
$mini->context = $mini->display->context = panels_context_load_contexts($mini, FALSE, $context);
if (empty($mini) || !empty($mini->disabled)) {
return;
}
$mini->display->args = $panel_args;
$mini->display->css_id = panels_mini_get_id($conf['name']);
$mini->display->owner = $mini;
// unique ID of this mini.
$mini->display->owner->id = $mini->name;
$block = new stdClass();
$block->module = 'panels_mini';
$block->delta = $conf['name'];
$block->content = panels_render_display($mini->display);
if (!$mini->hide_title) {
$block->subject = filter_xss_admin($mini->title);
}
return $block;
}
/**
* Form to add a mini panel to a panel.
*/
function panels_mini_add_mini_panel($id, $parents, $conf = array()) {
$conf['name'] = $id;
return panels_mini_edit_mini_panel($id, $parents, $conf);
}
/**
* Returns an edit form for the mini panel.
*
* There isn't much here as most of this is set up at mini panel creation time.
*/
function panels_mini_edit_mini_panel($id, $parents, $conf) {
$form['name'] = array(
'#type' => 'value',
'#value' => $conf['name'],
);
return $form;
}
function panels_mini_title_mini_panel($conf) {
$mini = panels_mini_load($conf['name']);
if (!$mini) {
return t('Deleted/missing mini panel @name', array('@name' => $conf['name']));
}
$title = filter_xss_admin($mini->title);
if (empty($title)) {
$title = t('Untitled mini panel');
}
return $title;
}
// ---------------------------------------------------------------------------
// Database functions.
/**
* A list of the fields used in the panel_mini table.
*/
function panels_mini_fields() {
return array(
'name' => "'%s'",
'category' => "'%s'",
'title' => "'%s'",
'contexts' => "'%s'",
'requiredcontexts' => "'%s'",
'relationships' => "'%s'",
);
}
/**
* Sanitize a mini panel, to guarantee certain data is as we believe it will be.
*/
function panels_mini_sanitize($panel_mini) {
foreach (array('contexts', 'relationships', 'requiredcontexts') as $id) {
if (!is_array($panel_mini->$id)) {
$panel_mini->$id = array();
}
}
return $panel_mini;
}
/**
* Fetch all mini panels in the system.
*
* This function does not cache.
*/
function panels_mini_load_all($page_size = 0) {
static $results = array();
if (array_key_exists($page_size, $results)) {
return $results[$page_size];
}
$panels = $dids = array();
$query = "SELECT * FROM {panels_mini}";
if ($page_size) {
$result = pager_query($query, $page_size);
}
else {
$result = db_query($query);
}
while ($panel_mini = db_fetch_object($result)) {
$panel_mini->contexts = (!empty($panel_mini->contexts)) ? unserialize($panel_mini->contexts) : array();
$panel_mini->requiredcontexts = (!empty($panel_mini->requiredcontexts)) ? unserialize($panel_mini->requiredcontexts) : array();
$panel_mini->relationships = (!empty($panel_mini->relationships)) ? unserialize($panel_mini->relationships) : array();
$panel_mini->category = (!empty($panel_mini->category)) ? $panel_mini->category : 'Mini panels';
$panel_mini->hide_title = ((bool) db_result(db_query('SELECT hide_title FROM {panels_display} WHERE did = %d', $panel_mini->did)));
$panel_mini->type = t('Local');
$panels[$panel_mini->name] = panels_mini_sanitize($panel_mini);
}
$status = variable_get('panel_mini_defaults', array());
foreach (panels_mini_default_panels() as $panel_mini) {
// Determine if default panel is enabled or disabled.
if (isset($status[$panel_mini->name])) {
$panel_mini->disabled = $status[$panel_mini->name];
}
if (!empty($panels[$panel_mini->name])) {
$panels[$panel_mini->name]->type = t('Overridden');
}
else {
$panel_mini->type = t('Default');
$panels[$panel_mini->name] = $panel_mini;
}
}
$results[$page_size] = $panels;
return $results[$page_size];
}
/**
* Load a mini panel.
*/
function panels_mini_load($pid) {
static $cache = array();
if (array_key_exists($pid, $cache)) {
return $cache[$pid];
}
if (!is_numeric($pid)) {
$where = "name = '%s'";
}
else {
$where = 'pid = %d';
}
$panel_mini = db_fetch_object(db_query("SELECT m.*, d.hide_title FROM {panels_mini} AS m INNER JOIN {panels_display} AS d ON m.did = d.did WHERE $where", $pid));
if (!$panel_mini) {
$defaults = panels_mini_default_panels();
if (isset($defaults[$pid])) {
$panel_mini = $defaults[$pid];
$status = variable_get('panel_mini_defaults', array());
// Determine if default panel is enabled or disabled.
if (isset($status[$panel_mini->name])) {
$panel_mini->disabled = $status[$panel_mini->name];
}
$cache[$pid] = $panel_mini;
return $panel_mini;
}
return;
}
$panel_mini->contexts = (!empty($panel_mini->contexts)) ? unserialize($panel_mini->contexts) : array();
$panel_mini->requiredcontexts = (!empty($panel_mini->requiredcontexts)) ? unserialize($panel_mini->requiredcontexts) : array();
$panel_mini->relationships = (!empty($panel_mini->relationships)) ? unserialize($panel_mini->relationships) : array();
// $panel_mini->hide_title = ((bool) db_result(db_query('SELECT hide_title FROM {panels_display} WHERE did = %d', $panel_mini->did)));
$cache[$pid] = panels_mini_sanitize($panel_mini);
$cache[$pid]->display = panels_load_display($cache[$pid]->did);
return $cache[$pid];
}
/**
* Save a mini panel.
*/
function panels_mini_save(&$panel_mini) {
$fields = $types = $values = $pairs = array();
// Save the display if one was given to us.
if (!empty($panel_mini->display)) {
$display = panels_save_display($panel_mini->display);
}
// Ensure empty values get translated correctly.
// Also make sure we don't mess up the original.
$mini_clone = drupal_clone(panels_mini_sanitize($panel_mini));
// If pid is set to our "magic value", this is an insert, otherwise an update.
$insert = $mini_clone->pid && $mini_clone->pid == 'new';
// Build arrays of fields and types (resp. pairs of both) and of values.
foreach (panels_mini_fields() as $field => $type) {
// Skip empty values.
if (isset($mini_clone->$field)) {
if ($insert) {
$fields[] = $field;
$types[] = $type;
}
else {
$pairs[] = "$field = $type";
}
// Build the $values array, serializing some fields.
$serialize = in_array($field, array('contexts', 'requiredcontexts', 'relationships'));
$values[] = $serialize ? serialize($mini_clone->$field) : $mini_clone->$field;
}
}
if ($insert) {
// Determine the new primary key.
$mini_clone->pid = db_next_id('{panels_mini}_pid');
// Build the query adding the new primary key and the did.
$sql = 'INSERT INTO {panels_mini} (' . implode(', ', $fields) . ', did, pid) VALUES (' . implode(', ', $types) . ', %d, %d)';
$values[] = $display->did;
}
else {
// Build the query filtering by the primary key.
$sql = 'UPDATE {panels_mini} SET ' . implode(', ', $pairs) . ' WHERE pid = %d';
}
$values[] = $mini_clone->pid;
db_query($sql, $values);
return $mini_clone->pid;
}
/**
* Delete a mini panel.
*/
function panels_mini_delete($panel_mini) {
db_query("DELETE FROM {panels_mini} WHERE pid = %d", $panel_mini->pid);
db_query("DELETE FROM {blocks} WHERE module = 'panels_mini' AND delta = %d", $panel_mini->pid);
return panels_delete_display($panel_mini->did);
}
/**
* Export a mini panel into PHP code for use in import.
*
* The code returned from can be used directly in panels_mini_save().
*/
function panels_mini_export($panel_mini, $prefix = '') {
$output = '';
$fields = panels_mini_fields();
$output .= $prefix . '$mini = new stdClass()' . ";\n";
$output .= $prefix . '$mini->pid = \'new\'' . ";\n";
foreach ($fields as $field => $sub) {
$output .= $prefix . ' $mini->' . $field . ' = ' . panels_var_export($panel_mini->$field, ' ') . ";\n";
}
// Export the primary display
$display = !empty($panel_mini->display) ? $panel_mini->display : panels_load_display($panel_mini->did);
$output .= panels_export_display($display, $prefix);
$output .= $prefix . '$mini->display = $display' . ";\n";
return $output;
}
/**
* Get all 'default' mini panels.
*
* @ingroup HookInvokers
*/
function panels_mini_default_panels() {
$panels = module_invoke_all('default_panel_minis');
if (!is_array($panels)) {
$panels = array();
}
return $panels;
}
/**
* Remove the block version of mini panels from being available content types.
*/
function panels_mini_panels_block_info($module, $delta, &$info) {
$info = NULL;
}
/**
* Implementation of hook_panels_exportables().
*/
function panels_mini_panels_exportables($op = 'list', $panels = NULL, $name = 'foo') {
static $all_panels = NULL;
if ($op == 'list') {
if (empty($all_panels)) {
$all_panels = panels_mini_load_all();
}
foreach ($all_panels as $name => $panel) {
$return[$name] = check_plain($name) . ' (' . check_plain($panel->title) . ')';
}
return $return;
}
if ($op == 'export') {
$code = "/**\n";
$code .= " * Implementation of hook_default_panel_minis()\n";
$code .= " */\n";
$code .= "function " . $name . "_default_panel_minis() {\n";
foreach ($panels as $panel => $truth) {
$code .= panels_mini_export($all_panels[$panel], ' ');
$code .= ' $minis[\'' . check_plain($panel) . '\'] = $mini;' . "\n\n\n";
}
$code .= " return \$minis;\n";
$code .= "}\n";
return $code;
}
}