';
}
$output .= drupal_render($form);
panels_load_include('display-render');
$output .= panels_render_dnd(panels_render_layout_admin($layout, $content, $display));
$output .= $save_buttons;
$output .= $preview;
return $output;
}
/**
* Get the links for a panel region.
*
* This is abstracted out for easy ajax replacement.
*/
function panels_edit_panel_get_links($display, $panel_id) {
$cache_key = $display->cache_key;
$links = array();
$links[] = array(
'title' => t('Add content'),
'href' => "panels/ajax/add-pane/$cache_key/$panel_id",
'attributes' => array(
'class' => 'ctools-use-modal',
),
);
$panel_settings = $display->panel_settings;
$style = panels_get_style((!empty($panel_settings[$panel_id]['style'])) ? $panel_settings[$panel_id]['style'] : '-1');
$style_title = isset($style['title']) ? $style['title'] : t('Default');
$links[] = array(
'title' => t('Region style: @style', array('@style' => $style_title)),
'href' => 'panels/ajax/style-type/panel/' . $cache_key . '/' . $panel_id,
'attributes' => array('class' => 'ctools-use-modal'),
);
if (panels_plugin_get_function('style', $style, 'settings form')) {
$links[] = array(
'title' => ' -- ' . t('Style settings'),
'href' => 'panels/ajax/style-settings/panel/' . $cache_key . '/' . $panel_id,
'attributes' => array('class' => 'ctools-use-modal'),
);
}
return theme('ctools_dropdown', theme('image', panels_get_path("images/icon-addcontent.png")), $links, TRUE, 'pane-add-link panels-region-links-' . $panel_id);
}
/**
* Handle form submission of the display content editor.
*
* This reads the location of the various panes from the form, which will
* have been modified from the ajax, rearranges them and then saves
* the display.
*/
function panels_edit_display_form_submit($form, &$form_state) {
$display = &$form_state['display'];
$old_content = $display->content;
$display->content = array();
if (!empty($form_state['values']['panel']['pane'])) {
foreach ($form_state['values']['panel']['pane'] as $panel_id => $panes) {
$display->panels[$panel_id] = array();
if ($panes) {
$pids = explode(',', $panes);
// need to filter the array, b/c passing it in a hidden field can generate trash
foreach (array_filter($pids) as $pid) {
if ($old_content[$pid]) {
$display->panels[$panel_id][] = $pid;
$old_content[$pid]->panel = $panel_id;
$display->content[$pid] = $old_content[$pid];
}
}
}
}
}
panels_edit_display_settings_form_submit($form, $form_state);
}
/**
* Submission of the preview button. Render the preview and put it into
* the preview widget area.
*/
function panels_edit_display_form_preview(&$form, &$form_state) {
$display = &$form_state['display'];
ctools_include('ajax');
$display->context = ctools_context_replace_placeholders($display->context, $form_state['values']['preview']);
$output = panels_render_display($display);
$commands = array();
$commands[] = array(
'command' => 'panel_preview',
'output' => $output,
);
ctools_ajax_render($commands);
}
/**
* Render a single pane in the edit environment.
*
* @param $pane
* The pane to render.
* @param $left_buttons
* Buttons that go on the left side of the pane.
* @param $buttons
* Buttons that go on the right side of the pane.
* @param $skin
* If true, provide the outside div. Used to provide an easy way to get
* just the innards for ajax replacement
*/
// TODO check and see if $skin is ever FALSE; pane show/hide setting is dependent on it being TRUE. can't imagine it could be...
function panels_show_pane($display, $pane, $skin = TRUE) {
$cache_key = $display->cache_key;
ctools_include('content');
$content_type = ctools_get_content_type($pane->type);
// This is just used for the title bar of the pane, not the content itself.
// If we know the content type, use the appropriate title for that type,
// otherwise, set the title using the content itself.
$title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $display->context);
if (!$title) {
$title = t('Deleted/missing content type @type', array('@type' => $pane->type));
}
$links = array();
if (!empty($pane->shown)) {
$links[] = array(
'title' => t('Disable this pane'),
'href' => "panels/ajax/hide/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-ajax'),
);
}
else {
$links[] = array(
'title' => t('Enable this pane'),
'href' => "panels/ajax/show/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-ajax'),
);
}
if (isset($display->title_pane) && $display->title_pane == $pane->pid) {
$links['panels-set-title'] = array(
'title' => t('✓Panel title'),
'html' => TRUE,
);
}
else {
$links['panels-set-title'] = array(
'title' => t('Panel title'),
'href' => "panels/ajax/panel-title/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-ajax'),
);
}
if (isset($content_type['edit form'])) {
$links[] = array(
'title' => t('Settings'),
'href' => "panels/ajax/configure/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-modal'),
);
}
if (user_access('administer advanced pane settings')) {
$links[] = array(
'title' => t('CSS properties'),
'href' => "panels/ajax/pane-css/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-modal'),
);
}
$links[] = array(
'title' => '',
'html' => TRUE,
);
$style = panels_get_style((!empty($pane->style['style'])) ? $pane->style['style'] : 'default');
$style_links[] = array(
'title' => $style['title'],
'attributes' => array('class' => 'panels-text'),
);
$style_links[] = array(
'title' => t('Change'),
'href' => 'panels/ajax/style-type/pane/' . $cache_key . '/' . $pane->pid,
'attributes' => array('class' => 'ctools-use-modal'),
);
if (panels_plugin_get_function('style', $style, 'pane settings form')) {
$style_links[] = array(
'title' => t('Settings'),
'href' => 'panels/ajax/style-settings/pane/' . $cache_key . '/' . $pane->pid,
'attributes' => array('class' => 'ctools-use-modal'),
);
}
$links[] = array(
'title' => '' . t('Style') . '' . theme_links($style_links),
'html' => TRUE,
'attributes' => array('class' => 'panels-sub-menu'),
);
if (user_access('administer pane access')) {
$links[] = array(
'title' => '',
'html' => TRUE,
);
$contexts = $display->context;
// Make sure we have the logged in user context
if (!isset($contexts['logged-in-user'])) {
$contexts['logged-in-user'] = ctools_access_get_loggedin_context();
}
$visibility_links = array();
if (!empty($pane->access['plugins'])) {
foreach ($pane->access['plugins'] as $id => $test) {
$plugin = ctools_get_access_plugin($test['name']);
$access_title = isset($plugin['title']) ? $plugin['title'] : t('Broken/missing access plugin %plugin', array('%plugin' => $test['name']));
$access_description = ctools_access_summary($plugin, $contexts, $test);
$visibility_links[] = array(
'title' => $access_description,
'href' => "panels/ajax/access-test/$cache_key/$pane->pid/$id",
'attributes' => array('class' => 'ctools-use-modal panels-italic'),
);
}
}
if (empty($visibility_links)) {
$visibility_links[] = array(
'title' => t('No rules'),
'attributes' => array('class' => 'panels-text'),
);
}
$visibility_links[] = array(
'title' => t('Add new rule'),
'href' => "panels/ajax/access-add/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-modal'),
);
$visibility_links[] = array(
'title' => t('Settings'),
'href' => "panels/ajax/access-settings/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-modal'),
);
$links[] = array(
'title' => '' . t('Visibility rules') . '' . theme_links($visibility_links),
'html' => TRUE,
'attributes' => array('class' => 'panels-sub-menu'),
);
}
if (panels_get_caches() && user_access('use panels caching features')) {
$links[] = array(
'title' => '',
'html' => TRUE,
);
$method = isset($pane->cache['method']) ? $pane->cache['method'] : 0;
$info = panels_get_cache($method);
$cache_method = isset($info['title']) ? $info['title'] : t('No caching');
$cache_links[] = array(
'title' => $cache_method,
'attributes' => array('class' => 'panels-text'),
);
$cache_links[] = array(
'title' => t('Change'),
'href' => "panels/ajax/cache-method/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-modal'),
);
if (panels_plugin_get_function('cache', $info, 'settings form')) {
$cache_links[] = array(
'title' => t('Settings'),
'href' => "panels/ajax/cache-settings/$cache_key/$pane->pid",
'attributes' => array('class' => 'ctools-use-modal'),
);
}
$links[] = array(
'title' => '' . t('Caching') . '' . theme_links($cache_links),
'html' => TRUE,
'attributes' => array('class' => 'panels-sub-menu'),
);
}
$links[] = array(
'title' => '',
'html' => TRUE,
);
$links[] = array(
'title' => t('Remove'),
'href' => '#',
'attributes' => array(
'class' => 'pane-delete',
'id' => "pane-delete-panel-pane-$pane->pid",
),
);
$buttons = theme('ctools_dropdown', theme('image', panels_get_path("images/icon-configure.png")), $links, TRUE);
// Render administrative buttons for the pane.
$block = new stdClass();
if (empty($content_type)) {
$block->title = '' . t('Missing content type') . '';
$block->content = t('This pane\'s content type is either missing or has been deleted. This pane will not render.');
}
else {
$block = ctools_content_admin_info($content_type, $pane->subtype, $pane->configuration, $display->context);
}
$output = panels_render_pane_dnd($block, $pane->pid, $title, '', $buttons);
if ($skin) {
$class = 'panel-pane';
if (empty($pane->shown)) {
$class .= ' hidden-pane';
}
if (isset($display->title_pane) && $display->title_pane == $pane->pid) {
$class .= ' panel-pane-is-title';
}
$output = '
' . $output . '
';
}
return $output;
}
/**
* @defgroup panels_ajax Functions for panels ajax features
* @{
*/
/**
* Entry point for AJAX: 'Display settings' modal form, from which the user
* can control settings for the display.
*
* @param $cache
* The display id of the $display object currently being edited.
*/
function panels_ajax_display_settings($cache) {
$form_state = array(
'display' => &$cache->display,
'display_title' => !empty($cache->display_title),
'title' => t('Display settings'),
'ajax' => TRUE,
);
$output = ctools_modal_form_wrapper('panels_edit_display_settings_form', $form_state);
if (empty($output)) {
panels_edit_cache_set($cache);
$output = array();
$output[] = ctools_modal_command_dismiss();
}
ctools_ajax_render($output);
}
/**
* Form for display settings.
*/
function panels_edit_display_settings_form(&$form_state) {
$form = array();
$display = &$form_state['display'];
$layout = panels_get_layout($display->layout);
$form_state['layout'] = $layout;
ctools_include('dependent');
if ($form_state['display_title']) {
$form['display_title'] = array (
'#tree' => TRUE,
);
$form['display_title']['hide_title'] = array(
'#type' => 'select',
'#title' => t('Title type'),
'#default_value' => (int) $display->hide_title,
'#options' => array(
PANELS_TITLE_NONE => t('No title'),
PANELS_TITLE_FIXED => t('Manually set'),
PANELS_TITLE_PANE => t('From pane'),
),
);
$form['display_title']['title'] = array(
'#type' => 'textfield',
'#default_value' => $display->title,
'#title' => t('Title'),
'#description' => t('The title of this panel. If left blank, a default title may be used. Set to No Title if you want the title to actually be blank.'),
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-display-title-hide-title' => array(PANELS_TITLE_FIXED)),
);
if (!empty($display->context)) {
$form['display_title']['title']['#description'] .= ' ' . t('You may use substitutions in this title.');
// We have to create a manual fieldset because fieldsets do not support IDs.
// Use 'hidden' instead of 'markup' so that the process will run.
$form['display_title']['contexts_prefix'] = array(
'#type' => 'hidden',
'#id' => 'edit-display-substitutions',
'#prefix' => '',
);
}
}
// TODO doc the ability to do this as part of the API
if (!empty($layout['settings form']) && function_exists($layout['settings form'])) {
$form['layout_settings'] = $layout['settings form']($display, $layout, $display->layout_settings);
}
$form['layout_settings']['#tree'] = TRUE;
return $form;
}
/**
* Validate the layout settings form.
*/
function panels_edit_display_settings_form_validate($form, &$form_state) {
if ($function = panels_plugin_get_function('layout', $form_state['layout'], 'settings validate')) {
$function($form_state['values']['layout_settings'], $form['layout_settings'], $form_state['display'], $form_state['layout'], $form_state['display']->layout_settings);
}
}
/**
* Store changes from the layout settings form.
*/
function panels_edit_display_settings_form_submit($form, &$form_state) {
$display = &$form_state['display'];
if ($function = panels_plugin_get_function('layout', $form_state['layout'], 'settings submit')) {
$function($form_state['values']['layout_settings'], $display, $form_state['layout'], $display->layout_settings);
}
// Since not all layouts have layout settings, check here in case of notices.
if (isset($form_state['values']['layout_settings'])) {
$display->layout_settings = $form_state['values']['layout_settings'];
}
if (isset($form_state['values']['display_title']['title'])) {
$display->title = $form_state['values']['display_title']['title'];
$display->hide_title = $form_state['values']['display_title']['hide_title'];
}
}
/**
* Entry point for AJAX: 'Add Content' modal form, from which the user selects the
* type of pane to add.
*
* @param int $cache
* The display id of the $display object currently being edited.
* @param string $panel_id
* A string with the name of the panel region to which the selected
* pane type will be added.
*/
function panels_ajax_add_pane_choose($cache, $panel_id = NULL, $category = NULL) {
$display = $cache->display;
$layout = panels_get_layout($display->layout);
$layout_panels = panels_get_panels($layout, $display);
if ($layout && array_key_exists($panel_id, $layout_panels)) {
ctools_modal_render(
t('Add content to !s', array('!s' => $layout_panels[$panel_id])),
panels_add_content($cache, $panel_id, $category)
);
}
ctools_modal_render(t('Error'), t('Invalid input'));
}
/**
* Display a list of content available.
*/
function panels_add_content($cache, $panel_id, $key) {
ctools_include('content');
$cache_key = $cache->display->cache_key;
$category_names = array();
$categories = array();
$titles = array();
foreach ($cache->content_types as $type_name => $subtypes) {
if (is_array($subtypes)) {
$content_type = ctools_get_content_type($type_name);
foreach ($subtypes as $subtype_name => $subtype_info) {
$title = filter_xss_admin($subtype_info['title']);
$description = isset($subtype_info['description']) ? $subtype_info['description'] : $title;
$icon = ctools_content_admin_icon($subtype_info);
if (isset($subtype_info['top level'])) {
$category = 'root';
}
else if (isset($subtype_info['category'])) {
if (is_array($subtype_info['category'])) {
list($category, $weight) = $subtype_info['category'];
}
else {
$category = $subtype_info['category'];
}
}
else {
$category = t('Uncategorized');
}
$category_key = preg_replace('/[^a-z0-9]/', '-', strtolower($category));
$output = '