disabled) && empty($mini->requiredcontext)) { $blocks[$panel_mini->pid] = array( 'info' => t('Mini panel: "@title"', array('@title' => $panel_mini->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->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($subtype, $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->subject = filter_xss_admin($mini->title); $block->content = panels_render_display($mini->display); 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($subtype, $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($mini) { foreach (array('contexts', 'relationships', 'requiredcontexts') as $id) { if (!isset($mini->$id) || !is_array($mini->$id)) { $mini->$id = array(); } } return $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 ($mini = db_fetch_object($result)) { $mini->contexts = (!empty($mini->contexts)) ? unserialize($mini->contexts) : array(); $mini->requiredcontexts = (!empty($mini->requiredcontexts)) ? unserialize($mini->requiredcontexts) : array(); $mini->relationships = (!empty($mini->relationships)) ? unserialize($mini->relationships) : array(); $mini->category = (!empty($mini->category)) ? $mini->category : 'Mini panels'; $mini->type = t('Local'); $panels[$mini->name] = panels_mini_sanitize($mini); } $status = variable_get('panel_mini_defaults', array()); foreach (panels_mini_default_panels() as $mini) { // Determine if default panel is enabled or disabled. if (isset($status[$mini->name])) { $mini->disabled = $status[$mini->name]; } if (!empty($panels[$mini->name])) { $panels[$mini->name]->type = t('Overridden'); } else { $mini->type = t('Default'); $panels[$mini->name] = $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]; } $where = is_numeric($pid) ? 'pid = %d' : "name = '%s'"; $panel_mini = db_fetch_object(db_query("SELECT * FROM {panels_mini} 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(); $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) { // Build the query adding the new primary key and the did. $sql = 'INSERT INTO {panels_mini} (' . implode(', ', $fields) . ', did) VALUES (' . implode(', ', $types) . ', %d)'; $values[] = $display->did; db_query($sql, $values); // Determine the new primary key. $mini_clone->pid = db_last_insert_id('panels_mini', 'pid'); } 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. */ 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; } } /** * Menu callback to check to see if a mini panel is valid as part * of a path, and if it is, return the mini. */ function panels_mini_admin_load($name) { $mini = panels_mini_load($name); if ($mini && empty($mini->disabled)) { return $mini; } }