Index: panels.install =================================================================== RCS file: /cvs/drupal/contributions/modules/panels/panels.install,v retrieving revision 1.1.6.11 diff -u -F^f -r1.1.6.11 panels.install --- panels.install 8 Jul 2007 04:46:55 -0000 1.1.6.11 +++ panels.install 14 Aug 2007 21:10:47 -0000 @@ -38,7 +38,8 @@ function panels_install() { CREATE TABLE {panels_display} ( did INT(10) NOT NULL DEFAULT 0 PRIMARY KEY, layout VARCHAR(32), - layout_settings longtext + layout_settings longtext, + panel_settings longtext ) /*!40100 DEFAULT CHARACTER SET utf8 */ EOT ); @@ -140,3 +141,9 @@ function panels_update_1002() { $ret[] = update_sql("ALTER TABLE {panels_page} ADD COLUMN css longtext AFTER css_id"); return $ret; } + +// Create a field for the panel settings. +function panels_update_1003() { + $ret[] = update_sql("ALTER TABLE {panels_display} ADD COLUMN panel_settings longtext"); + return $ret; +} Index: panels.module =================================================================== RCS file: /cvs/drupal/contributions/modules/panels/panels.module,v retrieving revision 1.10.4.33 diff -u -F^f -r1.10.4.33 panels.module --- panels.module 23 Jul 2007 16:15:58 -0000 1.10.4.33 +++ panels.module 14 Aug 2007 21:10:48 -0000 @@ -1349,12 +1349,12 @@ function panels_load_display($did, $cont */ function panels_save_display(&$display) { if ($display->did && $display->did != 'new') { - db_query("UPDATE {panels_display} SET layout = '%s', layout_settings = '%s' WHERE did = %d", $display->layout, $display->layout_settings, $display->did); + db_query("UPDATE {panels_display} SET layout = '%s', layout_settings = '%s', panel_settings = '%s' WHERE did = %d", $display->layout, $display->layout_settings, $display->panel_settings, $display->did); db_query("DELETE FROM {panels_pane} WHERE did = %d", $display->did); } else { $display->did = db_next_id("{panels_display}_id"); - db_query("INSERT INTO {panels_display} (did, layout, layout_settings) VALUES (%d, '%s', '%s')", $display->did, $display->layout, $display->layout_settings); + db_query("INSERT INTO {panels_display} (did, layout, layout_settings, panel_settings) VALUES (%d, '%s', '%s', '%s')", $display->did, $display->layout, $display->layout_settings, $display->panel_settings); } // update all the panes @@ -1463,26 +1463,53 @@ function panels_sanitize_display(&$displ */ function panels_render_display(&$display) { $layout = panels_get_layout($display->layout); - if (!$layout) { return NULL; } panels_sanitize_display($display); - foreach ($display->content as $pid => $pane) { - if ($result = panels_get_pane_content($pane, $display->args, $display->context, $display->incoming_content)) { - if (!empty($content[$pane->panel])) { - $content[$pane->panel] .= theme('panels_separator', $display); - } - if (panels_pane_access($pane)) { - $content[$pane->panel] .= theme('panels_pane', $result, $display); - } + // Loop through all panels, put all panes that belong to the current panel + // in an array, then render the panel. + foreach ($display->panels as $panel_name => $panes) { + $panes_in_panel = array_intersect_key($display->content, array_flip($panes)); + $content[$panel_name] = panels_render_panel($panes_in_panel, $display); + } + + return panels_render_layout($layout, $content, $display->css_id, unserialize($display->layout_settings)); +} + +/** + * Render a panel, by storing the content of each pane in an appropriate array + * and then passing through to the theme function that will render the panel + * in the configured panel style. + * + * @param $panes + * An array of panes that are assigned to the panel that's being rendered. + * @param $display + * A display object. + * @return + * The rendered HTML for a panel. + */ +function panels_render_panel($panes_in_panel, $display) { + $panel_settings = unserialize($display->panel_settings); + $style = (is_array($panel_settings)) ? panels_get_panel_style($panel_settings['style']) : array('name' => 'default', 'module' => 'panels'); + + // Store all panes in an array, sorted by their position in the panel. + foreach ($panes_in_panel as $pane_id => $pane) { + if (panels_pane_access($pane)) { + $panes[$pane->position] = panels_get_pane_content($pane, $display->args, $display->context, $display->incoming_content); } } - $output = panels_render_layout($layout, $content, $display->css_id, unserialize($display->layout_settings)); - return $output; + // Retrieve the pid (can be a panel page id, a mini panel id, etc.), this + // might be used (or even necessary) for some panel display styles. + $pid = 0; + if (isset($display->owner) && is_object($display->owner) && isset($display->owner->pid)) { + $panel_id = $display->owner->pid; + } + + return module_invoke($style['module'], 'panels_panel_style_render', $display, $style['name'], $panel_id, $panes); } // --------------------------------------------------------------------------- @@ -1534,6 +1561,51 @@ function panels_get_layouts($layout = NU return $layouts; } +/** + * Collate information about a specific panel style. + * + * @param $style + * Name of a panel style. + * @return + * An array with information about the requested panel style. + */ +function panels_get_panel_style($style) { + return panels_get_panel_styles($style); +} + +/** + * Collate information about all available panel styles. + * + * @param $style + * Name of a panel style. + * @return + * An array of arrays with information about all available panel styles. If + * the $style parameter specified an available panel style, only this array + * would be returned. + */ +function panels_get_panel_styles($style = NULL) { + static $styles; + + if (!isset($styles)) { + foreach (module_list() as $module) { + $module_panel_styles = module_invoke($module, 'panels_panel_style_info'); + if ($module_panel_styles) { + foreach ($module_panel_styles as $name => $panel_style_info) { + $styles[$name] = $panel_style_info; + $styles[$name]['name'] = $name; + $styles[$name]['module'] = $module; + } + } + } + } + + if ($style) { + return isset($styles[$style]) ? $styles[$style] : NULL; + } + + return $styles; +} + function panels_get_content_type($content_type) { return panels_get_content_types($content_type); } @@ -1580,6 +1652,38 @@ function _panels_js_files() { } // --------------------------------------------------------------------------- +// Panels hooks + +/** + * Implementation of hook_panels_panel_style_info(). + */ +function panels_panels_panel_style_info() { + return array( + 'default' => array( + 'label' => t('Default'), + 'panels implementations' => array(), + ), + 'list' => array( + 'label' => t('List'), + 'panels implementations' => array(), + ), + ); +} + +/** + * Implementation of hook_panels_panel_style_render(). + */ +function panels_panels_panel_style_render($display, $style, $panel_id, $panes) { + switch ($style) { + case 'default': + return theme('panels_panel_default', $display, $panel_id, $panes); + + case 'list': + return theme('panels_panel_list', $display, $panel_id, $panes); + } +} + +// --------------------------------------------------------------------------- // Panels theming functions function theme_panels_dnd($content) { @@ -1623,10 +1727,6 @@ function theme_panels_pane_collapsible($ return $output; } -function theme_panels_separator($display) { - return '
'; -} - /** * Print the layout link. Sends out to a theme function. */ @@ -1701,6 +1801,33 @@ function theme_panels_hidden() { } /** + * Panel style: default (panes separated by whitespace). + */ +function theme_panels_panel_default($display, $panel_id, $panes) { + $output = ''; + + foreach ($panes as $pane) { + if (isset($output)) { + $output .= ''; + } + $output .= theme('panels_pane', $pane, $display); + } + return $output; +} + +/** + * Panel style: list of panes (panes are items in an unordered list). + */ +function theme_panels_panel_list($display, $panel_id, $panes) { + $items = array(); + + foreach ($panes as $pane_id => $pane) { + $items[] = theme('panels_pane', $pane, $display); + } + return theme('item_list', $items); +} + +/** * Helper function for autocompletion of node titles. * This is mostly stolen from clipper. */ @@ -1753,3 +1880,35 @@ function panels_title_sort($a, $b) { } return ($a['weight'] < $b['weight']) ? -1 : 1; } + +/** + * For PHP 4 compatibility. The array_intersect_key is used in the + * panels_render_display function. + * + * Borrowed from http://php.net/manual/en/function.array-intersect-key.php#74956. + */ +if (!function_exists('array_intersect_key')) { + function array_intersect_key($isec, $keys) { + $argc = func_num_args(); + if ($argc > 2) { + for ($i = 1; !empty($isec) && $i < $argc; $i++) { + $arr = func_get_arg($i); + foreach (array_keys($isec) as $key) { + if (!isset($arr[$key])) { + unset($isec[$key]); + } + } + } + return $isec; + } + else { + $res = array(); + foreach (array_keys($isec) as $key) { + if (isset($keys[$key])) { + $res[$key] = $isec[$key]; + } + } + return $res; + } + } +} Index: panels_common.inc =================================================================== RCS file: /cvs/drupal/contributions/modules/panels/Attic/panels_common.inc,v retrieving revision 1.1.2.3 diff -u -F^f -r1.1.2.3 panels_common.inc --- panels_common.inc 7 Jul 2007 21:17:36 -0000 1.1.2.3 +++ panels_common.inc 14 Aug 2007 21:10:48 -0000 @@ -128,3 +128,112 @@ function panels_common_get_allowed_types } return $content_types; } + +/** + * The layout information fieldset displayed at admin/build/panel-%implementation%/add/%layout%. + */ +function panels_common_get_layout_information($panel_implementation) { + $form = array(); + $layout = panels_get_layout($panel_implementation->display->layout); + + $form = array( + '#type' => 'fieldset', + '#title' => t('Layout'), + ); + + $form['layout-icon'] = array( + '#value' => panels_print_layout_icon($panel_implementation->display->layout, $layout), + ); + + $form['layout-display'] = array( + '#value' => check_plain($layout['title']), + ); + $content = 'Mini panels are the small variants of panel pages. Instead of pages, they define blocks.
'); + } +} + +/** + * 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/build/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/build/panel-mini/list', + 'title' => t('List'), + 'access' => $access, + 'callback' => 'panels_mini_list_page', + 'weight' => -10, + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items[] = array( + 'path' => 'admin/build/panel-mini/add', + 'title' => t('Add'), + 'access' => $access, + 'callback' => 'panels_mini_add_page', + 'type' => MENU_LOCAL_TASK, + ); + $items[] = array( + 'path' => 'admin/build/panel-mini/settings', + 'title' => t('Settings'), + 'access' => $access, + 'callback' => 'panels_mini_settings', + 'type' => MENU_LOCAL_TASK, + ); + } + else { + $result = db_query("SELECT * FROM {panels_mini}"); + while ($panel_mini = db_fetch_object($result)) { + panels_mini_menu_items($items, "admin/build/panel-mini/$panel_mini->pid", $panel_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('Edit'), + 'access' => $access, + 'callback' => 'panels_mini_edit', + 'callback arguments' => array($panel_mini->pid), + 'weight' => -5, + 'type' => MENU_CALLBACK, + ); + $items[] = array( + 'path' => $base .'/edit', + 'title' => t('Edit'), + 'access' => $access, + 'callback' => 'panels_mini_edit', + 'callback arguments' => array($panel_mini->pid), + 'weight' => -5, + 'type' => MENU_LOCAL_TASK, + ); + $items[] = array( + 'path' => $base .'/edit/general', + 'title' => t('General'), + 'access' => $access, + 'callback' => 'panels_mini_edit', + 'callback arguments' => array($panel_mini->pid), + 'weight' => -5, + '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->pid), + 'weight' => -3, + 'type' => MENU_LOCAL_TASK, + ); + + $display = panels_load_display($panel_mini->did); + $layout = panels_get_layout($display->layout); + if (!empty($layout['settings form'])) { + $items[] = array( + 'path' => $base .'/edit/settings', + 'title' => t('Layout settings'), + 'access' => $access, + 'callback' => 'panels_mini_edit_layout_settings', + 'callback arguments' => array($panel_mini->pid), + 'weight' => -3, + '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->pid), + 'weight' => -1, + '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->pid), + 'type' => MENU_CALLBACK, + ); + } +} + +// --------------------------------------------------------------------------- +// Mini panel administrative pages. + +/** + * Settings for mini panels. + */ +function panels_mini_settings() { + require_once drupal_get_path('module', 'panels') .'/panels_common.inc'; + 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() { + $result = db_query("SELECT * FROM {panels_mini} ORDER BY title"); + + while ($panel_mini = db_fetch_object($result)) { + $item = array(); + $item[] = check_plain($panel_mini->title); + $item[] = implode(' | ', array( + l(t('Edit'), "admin/build/panel-mini/$panel_mini->pid/edit"), + l(t('Delete'), "admin/build/panel-mini/$panel_mini->pid/delete"), + )); + $items[] = $item; + } + $header = array( + t('Title'), + t('Operations'), + ); + + $output = theme('table', $header, $items); + + 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/build/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($formid, $form) { + if ($form['confirm']) { + panels_mini_delete((object) $form); + return 'admin/build/panel-mini'; + } +} + +/** + * Handle the add mini panel page. + */ +function panels_mini_add_page($layout = NULL) { + $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->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); + } + return drupal_get_form('panels_mini_edit_form', $panel_mini); +} + +/** + * The form to edit the settings of a mini panel. + */ +function panels_mini_edit_form($panel_mini) { + require_once drupal_get_path('module', 'panels') .'/panels_common.inc'; + 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' => '