'panels/node/autocomplete', 'title' => t('Autocomplete node'), 'callback' => 'panels_node_autocomplete', 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'panels/ajax', 'title' => t('ajax'), 'callback' => 'panels_ajax', 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'panels/ajax/add-content', 'title' => t('ajax'), 'callback' => 'panels_ajax_add_content', 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'panels/ajax/add-config', 'title' => t('ajax'), 'callback' => 'panels_ajax_add_config', 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'panels/ajax/configure', 'title' => t('ajax'), 'callback' => 'panels_ajax_configure', 'access' => user_access('access content'), 'type' => MENU_CALLBACK ); } return $items; } /** * panels path helper function */ function panels_get_path($file, $base_path = false, $module = 'panels') { if ($base_path) { $output = base_path(); } return $output . drupal_get_path('module', $module) . '/' . $file; } // --------------------------------------------------------------------------- // panels custom image button /** * Custom form element to do our nice images. */ function panels_elements() { $type['panels_imagebutton'] = array('#input' => TRUE, '#button_type' => 'submit',); return $type; } /** * Theme our image button. */ function theme_panels_imagebutton($element) { return '\n"; } function panels_imagebutton_value() { // null function guarantees default_value doesn't get moved to #value. } /** * Add a single button to a form. */ function panels_add_button($image, $name, $text, $class, $id = NULL) { return array( '#type' => 'panels_imagebutton', '#image' => panels_get_path('images/' . $image, true), '#title' => $text, '#default_value' => $name, '#class' => $class, '#id' => $id, ); } // --------------------------------------------------------------------------- // session handling stuff for display editing function panels_cache_get($did) { static $cache = array(); if (!array_key_exists($did, $cache)) { $data = cache_get(session_id() . ':' . $did, 'cache'); $cache[$did] = unserialize($data->data); } return $cache[$did]; } function panels_cache_set($did, $cache) { cache_set(session_id() . ':' . $did, 'cache', serialize($cache), time() + 86400); } function panels_cache_clear($did) { cache_clear_all(session_id() . ':' . $did, 'cache'); } // non-session globals function panels_set($var, $value = NULL) { static $vars = array(); if ($value !== NULL) { $vars[$var] = $value; } return $vars[$var]; } function panels_get($var) { return panels_set($var); } // --------------------------------------------------------------------------- // panels display editing /** * Main API entry point to edit a panel display. */ function panels_edit($display, $destination, $content_types = NULL) { $did = $display->did; if (!$did) { $display->did = $did = 'new'; } if (!empty($_POST) && is_object($cache = panels_cache_get($did))) { $display = $cache->display; } else { panels_cache_clear($did); $cache = new stdClass(); $cache->display = $display; $cache->highest = 0; $cache->content_types = $content_types; panels_cache_set($did, $cache); } $output = drupal_get_form('panels_edit_display', $display, $destination); $hidden = theme('panels_hidden'); return $output . $hidden; } function panels_edit_display($display, $destination) { $form['did'] = array( '#type' => 'hidden', '#value' => $display->did, '#id' => 'panel-did', ); $form['op'] = array( '#type' => 'hidden', '#id' => 'panel-op', ); $form['panels_display'] = array( '#type' => 'value', '#value' => $display ); $form['destination'] = array( '#type' => 'value', '#value' => $destination ); $form['button']['#tree'] = TRUE; foreach ($display->content as $pid => $panel) { $form['button'][$pid]['#tree'] = TRUE; $form['button'][$pid]['configure'] = panels_add_button('configure.gif', t('Configure'), t('Configure this pane'), 'pane-configure'); $form['button'][$pid]['delete'] = panels_add_button('close.gif', t('Delete'), t('Remove this pane'), 'pane-delete'); } $layout = panels_get_layout($display->layout); foreach ($layout['panels'] as $id => $name) { $form['panels'][$id]['add'] = panels_add_button('add.gif', t('Add content'), t('Add content to this panel'), 'pane-add', "pane-add-$id"); } $form['panel'] = array('#tree' => TRUE); $form['panel']['pane'] = array('#tree' => TRUE); foreach ($layout['panels'] as $panel_id => $title) { $form['panel']['pane'][$panel_id] = array( '#type' => 'hidden', '#default_value' => implode(',', (array) $display->panels[$panel_id]), ); } $form['submit'] = array( '#type' => 'submit', '#value' => t('Save'), '#id' => 'panels-dnd-save', ); $form['cancel'] = array( '#type' => 'submit', '#value' => t('Cancel'), ); $form['hide'] = array( '#prefix' => '', '#suffix' => '', ); $form['hide']['hide-all'] = array( '#type' => 'submit', '#value' => t('Hide all'), '#id' => 'panels-hide-all', ); $form['hide']['show-all'] = array( '#type' => 'submit', '#value' => t('Show all'), '#id' => 'panels-show-all', ); if ($submit) { // The caller wants their own submit. $form['#submit'] = array($submit => array()); } return $form; } function theme_panels_edit_display($form) { _panels_js_files(); $display = $form['panels_display']['#value']; $layout = panels_get_layout($display->layout); $save_buttons = drupal_render($form['submit']) . drupal_render($form['cancel']); foreach ($layout['panels'] as $panel_id => $title) { foreach ((array) $display->panels[$panel_id] as $pid) { $pane = $display->content[$pid]; $left_buttons = NULL; $buttons = drupal_render($form['button'][$pid]['configure']); $buttons .= drupal_render($form['button'][$pid]['delete']); $content[$pane->panel] .= panels_show_pane($pane, $left_buttons, $buttons); } $content[$panel_id] = theme('panels_panel_dnd', $content[$panel_id], $panel_id, $title, drupal_render($form['panels'][$panel_id]['add'])); } $output .= drupal_render($form); $output .= theme('panels_dnd', panels_render_layout($layout, $content)); $output .= $save_buttons; return $output; } function panels_edit_display_submit($form_id, $form_values) { $display = $form_values['panels_display']; if ($form_values['op'] == t('Save')) { $old_content = $display->content; $display->content = array(); foreach ($form_values['panel']['pane'] as $panel_id => $panes) { $display->panels[$panel_id] = array(); if ($panes) { $pids = explode(',', $panes); foreach ($pids as $pid) { if ($old_content[$pid]) { $display->panels[$panel_id][] = $pid; $old_content[$pid]->panel = $panel_id; $display->content[$pid] = $old_content[$pid]; } } } } drupal_set_message(t('Panel content has been updated.')); panels_save_display($display); } panels_cache_clear($display->did); return $form_values['destination']; } /** * Shortcut to the panels layout editor */ function panels_edit_layout($display, $finish, $destination) { return drupal_get_form('panels_choose_layout', $display, $finish, $destination); } /** * Form to change the layout of a display. */ function panels_choose_layout($display, $finish, $destination) { $layouts = panels_get_layouts(); foreach ($layouts as $id => $layout) { $options[$id] = panels_print_layout_icon($id, $layout, check_plain($layout['title'])); } $form['layout'] = array( '#type' => 'radios', '#title' => t('Choose layout'), '#options' => $options, '#default_value' => $display->layout, ); $form['clearer'] = array( '#value' => '
', ); $form['variables'] = array( '#type' => 'value', '#value' => array($display, $finish, $destination), ); if ($_POST['op'] && $_POST['op'] != t('Back') && $display->content) { $form['#post'] = $_POST; $form = form_builder('panels_choose_layout', $form); unset($form['#post']); $form['layout']['#type'] = 'hidden'; panels_change_layout($form, $display, $form['layout']['#value']); } if (($_POST['op'] && $_POST['op'] != t('Back')) || !$display->content) { $form['submit'] = array( '#type' => 'submit', '#value' => $finish, ); } else { $form['submit'] = array( '#type' => 'submit', '#value' => t('Next'), ); } $form['#token'] = FALSE; // no token please return $form; } function panels_choose_layout_submit($form_id, $form_values) { list($display, $finish, $destination) = $form_values['variables']; $new_layout_id = $form_values['layout']; if ($form_values['op'] == $finish) { foreach ($form_values['old'] as $id => $new_id) { $content[$new_id] = (array) $content[$new_id] + $display->panels[$id]; foreach($content[$new_id] as $pid) { $display->content[$pid]->panel = $new_id; } } $display->panels = $content; $display->layout = $new_layout_id; // save it back to our session. panels_save_display($display); return $destination; } return FALSE; } function panels_change_layout(&$form, $display, $new_layout_id) { $new_layout = panels_get_layout($new_layout_id); $options = $new_layout['panels']; $keys = array_keys($options); $default = $options[0]; $old_layout = panels_get_layout($display->layout); $form['container'] = array( '#prefix' => '
', '#suffix' => '
', ); $form['container']['old_layout'] = array( '#value' => panels_print_layout_icon($display->layout, $old_layout, check_plain($old_layout['title'])), ); $form['container']['right_arrow'] = array( '#value' => theme('image', drupal_get_path('module', 'panels') . '/images/go-right.png'), ); $form['container']['new_layout'] = array( '#value' => panels_print_layout_icon($new_layout_id, $new_layout, check_plain($new_layout['title'])), ); $form['container-clearer'] = array( '#value' => '
', ); $form['old'] = array( '#tree' => true, ); foreach ($display->panels as $id => $content) { $form['old'][$id] = array( '#type' => 'select', '#title' => t('Move content in @layout to', array('@layout' => $old_layout['panels'][$id])), '#options' => $options, '#default_value' => array_key_exists($id, $options) ? $id : $default, ); } $form['back'] = array( '#type' => 'submit', '#value' => t('Back'), ); return $form; } // ------------------------------------------------------------------ // Functions to provide information about a content type function panels_ct_function($type, $name) { if (is_object($type)) { $content_type = $type; } else { $content_type = panels_get_content_type($type); } $function = $content_type[$name]; if (function_exists($function)) { return $function; } } function panels_ct_get_content($type, $conf, $args, $context, $incoming_content) { if ($function = panels_ct_function($type, 'render callback')) { return $function($conf, $args, $context, $incoming_content); } } function panels_ct_get_title($type, $conf) { if ($function = panels_ct_function($type, 'title callback')) { return $function($conf); } } function panels_ct_get_add_form($type, $id, $parents) { if ($function = panels_ct_function($type, 'add callback')) { return $function($id, $parents); } } function panels_ct_get_edit_form($type, $conf, $parents) { if ($function = panels_ct_function($type, 'edit callback')) { return $function($conf, $parents); } } function panels_ct_validate_form($type, $form, $form_values) { if ($function = panels_ct_function($type, 'validate callback')) { return $function($form, $form_values); } } function panels_ct_get_types($type) { if (is_array($type)) { $content_type = $type; } else { $content_type = panels_get_content_type($type); } $function = $content_type['content_types']; if (is_array($function)) { return $function; } if (function_exists($function)) { return $function($conf); } } /** * Get an array of all available content types that can be fed into the * display editor for the add content list. */ function panels_get_available_content_types($context = NULL, $has_content = FALSE) { $content_types = panels_get_content_types(); uasort($content_types, 'panels_title_sort'); $available = array(); foreach ($content_types as $id => $type) { // exclude items that require content if we're saying we don't // provide it. if (!empty($type['requires content']) && !$has_content) { continue; } // Check to see if the content type can be used in this context. if (!isset($type['required context']) || (is_array($type['required_context']) && in_array($context, $type['required_context'])) || ($type['required_context'] == $context)) { $available[$id] = panels_ct_get_types($type); } } return $available; } // ------------------------------------------------------------------ // Functions to provide information about a panel or part of a panel. function panels_get_pane_content($pane, $args = array(), $context = NULL, $incoming_content = '') { if (!$context) { $context = new panels_context; } if (!$incoming_content === '') { $incoming_content = t('Incoming content will be displayed here.'); } return panels_ct_get_content($pane->type, $pane->configuration, $args, $context, $incoming_content); } function panels_get_pane_title($pane) { return panels_ct_get_title($pane->type, $pane->configuration); } function panels_get_pane_edit_form($pane, $parents) { return panels_ct_get_edit_form($pane->type, $pane->configuration, $parents); } function panels_show_pane($pane, $left_buttons, $buttons, $skin = TRUE) { $block = panels_get_pane_content($pane); $title = panels_get_pane_title($pane); $output = theme('panels_pane_dnd', $block, $pane->pid, $title, $left_buttons, $buttons); if ($skin) { $output = '
' . $output . '
'; } return $output; } // --------------------------------------------------------------------------- // panels ajax stuff (part of editing) /** * Simple render function to make sure output is what we want. */ function panels_ajax_render($output = NULL, $title = NULL) { if (!is_object($output)) { $temp = new stdClass(); $temp->output = $output; $temp->type = 'display'; $temp->title = $title; $output = $temp; } if (!$output->output || !$output->type) { $output->output = t('The input was invalid'); $output->type = 'display'; $output->title = t('Error'); } print drupal_to_js($output); exit; } /** * entry point into all the ajax stuff */ function panels_ajax($op = NULL, $did = NULL, $pid = NULL) { switch ($op) { case 'submit-form': if ((is_numeric($did) || $did == 'new') && $cache = panels_cache_get($did)) { $output = panels_edit_submit_subform($cache->display); } break; } panels_ajax_render($output); } function panels_ajax_add_content($did = NULL, $panel_id = NULL) { if ((is_numeric($did) || $did == 'new') && $cache = panels_cache_get($did)) { $display = $cache->display; $layout = panels_get_layout($display->layout); if ($layout && array_key_exists($panel_id, $layout['panels'])) { $output->output = panels_add_content($cache, $panel_id); $output->type = 'display'; $output->title = t('Add content to !s', array('!s' => $layout['panels'][$panel_id])); } } panels_ajax_render($output); } function panels_add_content($cache, $panel_id) { $return->type = 'display'; $return->title = t('Choose type'); panels_set('return', $return); if (!isset($cache->content_types)) { $cache->content_types = panels_get_available_content_types(); } foreach ($cache->content_types as $id => $types) { if (is_array($types)) { foreach ($types as $content_id => $info) { if (isset($info['icon'])) { $icon = $info['icon']; if (isset($info['path'])) { $path = $info['path']; } else { $path = panels_get_path("content_types/$id"); } } else { $icon = 'no-icon.png'; $path = panels_get_path('images'); } $title = filter_xss_admin($info['title']); if (isset($info['description'])) { $description = $info['description']; } else { $description = $title; } $output .= '
'; $link_text = theme('image', $path . '/' . $icon, $description, $description); $output .= l($link_text, 'javascript: void()', array('class' => 'panels-modal-add-config', 'id' => $id . '-' . $panel_id . '-' . $content_id), NULL, NULL, NULL, TRUE); $output .= "
$title
"; $output .= '
'; } } } if (!$output) { $output = t('There are no content types you may add to this display.'); } return $output; } function panels_ajax_add_config($did = NULL, $pid = NULL) { if ((is_numeric($did) || $did == 'new') && $cache = panels_cache_get($did)) { $display = $cache->display; list($content_type_id, $panel_id, $type) = explode('-', $pid, 3); $conf = panels_ct_get_add_form($content_type_id, $type, array('configuration')); $types = panels_ct_get_types($content_type_id); $title = $types[$type]['title']; $cache->add_config = array($content_type_id, $conf, $panel_id, $title); panels_cache_set($display->did, $cache); $text = drupal_get_form('panels_add_content_config_form', $cache, $content_type_id, $conf, $panel_id, $title); $output = panels_get('return'); $output->output = $text; } panels_ajax_render($output); } function panels_add_content_config_form($display, $content_type_id = NULL, $conf = NULL, $panel_id = NULL, $title = NULL) { if (empty($content_type_id)) { $cache = panels_cache_get($display->did); if (isset($cache->add_config)) { list($content_type_id, $conf, $panel_id, $title) = $cache->add_config; } } $form['start_form'] = array('#value' => ''); $form['next'] = array( '#type' => 'submit', '#value' => t('Add pane'), ); $return->type = 'display'; $return->title = t('Configure !s', array('!s' => $title)); panels_set('return', $return); return $form; } function panels_add_content_config_form_validate($form_id, $form_values, $form) { panels_ct_validate_form($form_values['type'], $form['configuration'], $form_values['configuration']); } function panels_add_content_config_form_submit($form_id, $form) { $cache = panels_cache_get($form['did']); // keep an incrementing counter, add the data to the display. $pid = ++$cache->highest; $form['pid'] = "new-$pid"; $cache->display->content[$form['pid']] = (object) $form; $cache->display->panels[$form['panel']][] = $form['pid']; panels_cache_set($form['did'], $cache); $return->type = 'add'; $return->area = $form['panel']; $return->id = $form['pid']; // we need to fake the buttons a little. $buttons['configure'] = panels_add_button('configure.gif', t('Configure'), t('Configure this pane'), 'pane-configure'); $buttons['configure']['#parents'] = array('button', $form['pid'], 'configure'); $buttons['delete'] = panels_add_button('close.gif', t('Delete'), t('Remove this pane'), 'pane-delete'); $buttons['delete']['#parents'] = array('button', $form['pid'], 'delete'); $buttons = form_builder('dummy', $buttons); $return->output = panels_show_pane($cache->display->content[$form['pid']], NULL, drupal_render($buttons)); panels_set('return', $return); return FALSE; } function panels_ajax_configure($did = NULL, $pid = NULL) { if ((is_numeric($did) || $did == 'new') && $cache = panels_cache_get($did)) { $text = drupal_get_form('panels_edit_pane_config_form', $cache->display, $pid); $output = panels_get('return'); $output->output = $text; } panels_ajax_render($output); } function panels_edit_pane_config_form($display, $pid = NULL) { $cache = panels_cache_get($display->did); if ($pid === NULL) { if (isset($cache->pid)) { $pid = $cache->pid; } else { return array(); } } else { $cache->pid = $pid; panels_cache_set($display->did, $cache); } $pane = $display->content[$pid]; $form['start_form'] = array('#value' => ''); $form['next'] = array( '#type' => 'submit', '#value' => t('Save'), ); return $form; } function panels_edit_pane_config_form_submit($form_id, $form) { // save the new configuration. $cache = panels_cache_get($form['did']); $cache->display->content[$form['pid']]->configuration = $form['configuration']; panels_cache_set($form['did'], $cache); $return->type = 'replace'; $return->id = $form['pid']; $block = panels_get_pane_content($cache->display->content[$form['pid']]); if (!$block->subject) { $block->subject = t('No title'); } $return->output = theme('panels_pane', $block, $cache->display); panels_set('return', $return); return FALSE; } function panels_edit_submit_subform($display) { $valid_forms = array('panels_add_content_config_form', 'panels_edit_pane_config_form'); $form_id = $_POST['form_id']; if (!in_array($form_id, $valid_forms)) { return panels_ajax_render(); } // TODO: protect form_id to make sure it can only get panels forms. $output = drupal_get_form($form_id, $display); $next = panels_get('next'); if ($next) { $output = drupal_get_form($next['form'], $display, $next['data']); $return = panels_get('return'); if (!$return->output) { $return->output = $output; } } else { if (!($return = panels_get('return'))) { $return->type = 'display'; $return->output = $output; } else if ($return->type == 'display' && !$return->output) { $return->output = $output; } } if ($return->type == 'display') { $return->output = theme('status_messages') . $return->output; } return $return; } // End of ajax functions // --------------------- /* TODO: Integrate this back in */ /* function panels_edit_display_validate($form_id, $form_values, $form) { foreach ($form_values['content'] as $area => $content) { foreach ($content as $id => $item) { if (is_numeric($id)) { panels_ct_validate($item['type'], $item['configuration'], $form['content'][$area][$id]['configuration']); } } } } */ /** * move an item in an array to the top */ function panels_move_top(&$array, &$position) { $value = $array[$position]; unset($array[$position]); array_unshift($array, $value); // reindex the array now $array = array_values($array); } /** * move an item in an array to the bottom */ function panels_move_bottom(&$array, &$position) { $value = $array[$position]; unset($array[$position]); $array[] = $value; // reindex the array now $array = array_values($array); } /** * move an item in an array up one position */ function panels_move_up(&$array, &$position) { $value = $array[$position]; $array[$position] = $array[$position - 1]; $array[$position - 1] = $value; } /** * move an item in an array up one position */ function panels_move_down(&$array, &$position) { $value = $array[$position]; $array[$position] = $array[$position + 1]; $array[$position + 1] = $value; } /** * Remove an item from an array */ function panels_move_delete(&$array, &$position) { unset($array[$position]); // reindex the array now $array = array_values($array); } // --------------------------------------------------------------------------- // panels database functions class panels_display { var $args = array(); var $incoming_content = NULL; var $context = NULL; var $css_id = NULL; function panels_display($context = NULL) { if (!isset($context)) { $this->context = new panels_context(); } } } function panels_new_display($context = NULL) { $display = new panels_display($context); $display->did = 'new'; return $display; } function panels_load_display($did, $context = NULL) { $display = new panels_display($context); $obj = db_fetch_array(db_query("SELECT * FROM {panels_display} WHERE did = %d", $did)); foreach ($obj as $key => $value) { $display->$key = $value; } if (!$display) { return NULL; } $result = db_query("SELECT * FROM {panels_pane} WHERE did = %d ORDER BY panel, position", $did); $display->panels = $display->content = array(); while ($pane = db_fetch_object($result)) { $pane->configuration = unserialize($pane->configuration); $display->panels[$pane->panel][] = $pane->pid; $display->content[$pane->pid] = $pane; } return $display; } function panels_save_display(&$display) { if ($display->did && $display->did != 'new') { db_query("UPDATE {panels_display} SET layout = '%s' WHERE did = %d", $display->layout, $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) VALUES (%d, '%s')", $display->did, $display->layout); } // update all the panes foreach ($display->panels as $id => $panes) { $position = 0; $new_panes = array(); foreach ((array) $panes as $pid) { $pane = $display->content[$pid]; $pane->position = $position++; if (!is_numeric($pid)) { unset($display->content[$pid]); $pane->pid = db_next_id("{panels_pane}_pid"); } db_query("INSERT INTO {panels_pane} (pid, did, panel, type, configuration, position) VALUES (%d, %d, '%s', '%s', '%s', %d)", $pane->pid, $display->did, $pane->panel, $pane->type, serialize($pane->configuration), $pane->position); // and put it back so our pids and positions can be used $display->content[$pid] = $pane; $new_panes[] = $pid; } $display->panels[$id] = $panes; } return $display; // to be nice, even tho we have a reference. } function panels_delete_display($display) { db_query("DELETE FROM {panels_display} WHERE did = %d", $display->did); db_query("DELETE FROM {panels_pane} WHERE did = %d", $display->did); } /** * For external use: Given a layout ID and a $content array, return the * panel display. */ function panels_print_layout($id, $content) { $layout = panels_get_layout($id); if (!$layout) { return; } return panels_render_layout($layout, $content); } /** * Given a full layout structure and a content array, render a panel display. */ function panels_render_layout($layout, $content, $css_id = NULL) { $output = theme($layout['theme'], check_plain($css_id), $content); if ($output) { if (file_exists(path_to_theme() . '/' . $layout['css'])) { drupal_add_css(path_to_theme() . '/' . $layout['css']); } else { drupal_add_css(panels_get_path($layout['css'], false, $layout['module'])); } } return $output; } class panels_context { var $type = NULL; var $data = NULL; function panels_context($type = 'none', $data = NULL) { $this->type = $type; $this->data = $data; } } function panels_sanitize_display(&$display) { if (!isset($display->args)) { $display->args = array(); } if (!isset($display->incoming_content)) { $display->incoming_content = NULL; } if (!isset($display->context)) { $display->context = new panels_context(); } if (!isset($display->css_id)) { $display->css_id = NULL; } } /** * Render a display by loading the content into an appropriate * array and then passing through to panels_render_layout. * * if $incoming_content is NULL, default content will be applied. Use * an empty string to indicate no content. */ 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); } $content[$pane->panel] .= theme('panels_pane', $result, $display); } } $output = panels_render_layout($layout, $content, $display->css_id); return $output; } // --------------------------------------------------------------------------- // panels data loading function panels_load_includes($directory, $callback, $file = NULL) { // Load all our module 'on behalfs'. $path = panels_get_path($directory); $files = drupal_system_listing("$file" . '.inc$', $path, 'name', 0); foreach($files as $file) { require_once('./' . $file->filename); } $output = module_invoke_all($callback); foreach ($files as $file) { $function = 'panels_' . $file->name . '_' . $callback; if (function_exists($function)) { $result = $function(); if (isset($result) && is_array($result)) { $output = array_merge($output, $result); } } } return $output; } function panels_get_layout($layout) { return panels_get_layouts($layout); } function panels_get_layouts($layout = NULL) { static $layouts = array(); static $all_layouts = FALSE; if (!$all_layouts) { if (!$layout) { $layouts = panels_load_includes('layouts', 'panels_layouts'); $all_layouts = TRUE; } else if (!array_key_exists($layout, $layouts)) { $temp_layouts = panels_load_includes('layouts', 'panels_layouts', $layout); if (isset($temp_layouts[$layout])) { $layouts[$layout] = $temp_layouts[$layout]; } } } if ($layout) { return isset($layouts[$layout]) ? $layouts[$layout] : NULL; } return $layouts; } function panels_get_content_type($content_type) { return panels_get_content_types($content_type); } function panels_get_content_types($content_type = NULL) { static $content_types = array(); static $all_content_types = FALSE; if (!$all_content_types) { if (!$content_type) { $content_types = panels_load_includes('content_types', 'panels_content_types'); $all_content_types = TRUE; } else if (!array_key_exists($content_type, $content_types)) { $temp_content_types = panels_load_includes('content_types', 'panels_content_types', $content_type); if (isset($temp_content_types[$content_type])) { $content_types[$content_type] = $temp_content_types[$content_type]; } } } if ($content_type) { return isset($content_types[$content_type]) ? $content_types[$content_type] : NULL; } return $content_types; } /** * Includes required JavaScript libraries: * jQuery, iutil, idrag, idrop, isortables * In addition to panels.js. */ function _panels_js_files() { // while we don't use this directly some of our forms do. drupal_add_js('misc/collapse.js'); drupal_add_js('misc/autocomplete.js'); drupal_add_js(panels_get_path('js/lib/dimensions.js')); drupal_add_js(panels_get_path('js/lib/mc.js')); drupal_add_js(panels_get_path('js/lib/form.js')); drupal_add_js(array('panelsAjaxURL' => url('panels/ajax', NULL, NULL, TRUE)), 'setting'); drupal_add_js(panels_get_path('js/display_editor.js')); drupal_add_css(panels_get_path('css/panels_dnd.css')); drupal_add_css(panels_get_path('css/panels_admin.css')); } // --------------------------------------------------------------------------- // Panels theming functions function theme_panels_dnd($content) { $output = "
$content
"; return $output; } function theme_panels_panel_dnd($content, $area, $label, $footer) { return "
$footer

$label

$content
"; } function theme_panels_pane_dnd($block, $id, $label, $left_buttons = NULL, $buttons = NULL) { if (!$block->subject) { $block->subject = t('No title'); } static $count = 0; $output .= "
"; if ($buttons) { $output .= "$buttons"; } if ($left_buttons) { $output .= "$left_buttons"; } $output .= "$label
"; $output .= '
'; $output .= theme('panels_pane_collapsible', $block); $output .= '
'; return $output; } function theme_panels_pane($block, $display) { $output = '
'; $output .= theme('block', $block); $output .= '
'; return $output; } function theme_panels_pane_collapsible($block) { $output .= '

' . $block->subject . '

'; $output .= '
' . filter_xss_admin($block->content) . '
'; return $output; } function theme_panels_separator($display) { return '
'; } /** * Print the layout link. Sends out to a theme function. */ function panels_print_layout_link($id, $layout, $link) { drupal_add_css(panels_get_path('css/panels_admin.css')); $file = panels_get_path($layout['icon'], false, $layout['module']); $image = l(theme('image', $file), $link, NULL, NULL, NULL, NULL, TRUE); $title = l($layout['title'], $link); return theme('panels_layout_link', $title, $id, $image, $link); } function panels_print_layout_icon($id, $layout, $title = NULL) { drupal_add_css(panels_get_path('css/panels_admin.css')); $file = panels_get_path($layout['icon'], false, $layout['module']); return theme('panels_layout_icon', $id, theme('image', $file), $title); } /** * Theme the layout link image */ function theme_panels_layout_link($title, $id, $image, $link) { $output .= ''; return $output; } /** * Theme the layout icon image */ function theme_panels_layout_icon($id, $image, $title = NULL) { $output .= '
'; $output .= $image; if ($title) { $output .= '
' . $title . '
'; } $output .= '
'; return $output; } /** * This is separate because it must be outside the
to work, and * everything in the form theme is inside the form. */ function theme_panels_hidden() { // TODO: Move this to a theme function. $close_text = t('Close Window'); $close_image = theme('image', panels_get_path('images/close.gif'), t('Close window'), t('Close window')); $throbber_image = theme('image', panels_get_path('images/throbber.gif'), t('Loading...'), t('Loading')); $output = <<\n
\n
\n \n \n
\n
\n
\n
$throbber_image\n
\n \n EOF; return $output; } /** * Helper function for autocompletion of node titles. * This is mostly stolen from clipper. */ function panels_node_autocomplete($string) { if ($string != '') { // if there are node_types passed, we'll use those in a MySQL IN query. $result = db_query_range(db_rewrite_sql('SELECT n.title, u.name FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE LOWER(title) LIKE LOWER("%%%s%%")'), $string, 0, 10); $prefix = count($array) ? implode(', ', $array) .', ' : ''; $matches = array(); while ($node = db_fetch_object($result)) { $n = $node->title; // Commas and quotes in terms are special cases, so encode 'em. if (preg_match('/,/', $node->title) || preg_match('/"/', $node->title)) { $n = '"'. preg_replace('/"/', '""', $node->title) .'"'; } $matches[$prefix . $n] = ''. check_plain($node->title) .' ('. t('by %user', array('%user' => check_plain($node->name))) .')'; } print drupal_to_js($matches); exit(); } } /** * function for uasort to do title sorting. */ function panels_title_sort($a, $b) { if (!isset($a['weight'])) { $a['weight'] = 0; } if (!isset($b['weight'])) { $b['weight'] = 0; } if (!isset($a['title'])) { $a['title'] = NULL; } if (!isset($b['title'])) { $b['title'] = NULL; } if ($a['weight'] == $b['weight']) { if ($a['title'] < $b['title']) { return -1; } else if (drupal_strtolower($a['title']) > drupal_strtolower($b['title'])) { return 1; } else { return 0; } } return ($a['weight'] < $b['weight']) ? -1 : 1; }