'; $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; } }