panels_views.module in Panels 5.2
Same filename and directory in other branches
Provides views as panels content, configurable by the administrator. Each view provided as panel content must be configured in advance, but once configured, building panels with views is a little bit simpler.
File
panels_views/panels_views.moduleView source
<?php
/**
* @file panels_views.module
*
* Provides views as panels content, configurable by the administrator.
* Each view provided as panel content must be configured in advance,
* but once configured, building panels with views is a little bit simpler.
*/
/**
* Implementation of hook_menu().
*/
function panels_views_menu($may_cache) {
$items = array();
if ($may_cache) {
$access = user_access('administer panel views');
$items[] = array(
'path' => 'admin/panels/views',
'title' => t('Views panes'),
'access' => $access,
'type' => MENU_NORMAL_ITEM,
'callback' => 'panels_views_list_views',
'description' => t('Configure Views to be used as panes within panel displays.'),
);
$items[] = array(
'path' => 'admin/panels/views/list',
'title' => t('List'),
'access' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'callback' => 'panels_views_list_views',
'weight' => -10,
);
$items[] = array(
'path' => 'admin/panels/views/add',
'title' => t('Add'),
'access' => $access,
'callback' => 'panels_views_add_view',
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/panels/views/edit',
'title' => t('Edit'),
'access' => $access,
'callback' => 'panels_views_edit_view',
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/panels/views/delete',
'title' => t('Delete'),
'access' => $access,
'callback' => 'drupal_get_form',
'callback arguments' => array(
'panels_views_delete_confirm',
),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/panels/views/import',
'title' => t('Import'),
'access' => $access,
'callback' => 'panels_views_import_view',
'type' => MENU_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/panels/views/export',
'title' => t('Export'),
'access' => $access,
'callback' => 'drupal_get_form',
'callback arguments' => array(
'panels_views_export_view',
),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/panels/views/disable',
'access' => $access,
'callback' => 'panels_views_disable_page',
'weight' => -1,
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/panels/views/enable',
'access' => $access,
'callback' => 'panels_views_enable_page',
'weight' => -1,
'type' => MENU_CALLBACK,
);
}
return $items;
}
/**
* Implementation of hook_perm().
*/
function panels_views_perm() {
return array(
'administer panel views',
);
}
/**
* Page callback to list view panes and the initial form to add new view panes.
*/
function panels_views_list_views() {
// Run the form first as it may redirect; no point in doing the rest of
// the work if it does.
$form = drupal_get_form('panels_views_add_view_form');
$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',
),
array(
'data' => t('View'),
'field' => 'view',
),
t('Operations'),
);
foreach (panels_views_load_all() as $panel_view) {
$ops = array();
if (empty($panel_view->disabled)) {
$ops[] = l(t('Edit'), "admin/panels/views/edit/{$panel_view->name}");
$ops[] = l(t('Export'), "admin/panels/views/export/{$panel_view->name}");
}
if ($panel_view->type != t('Default')) {
$text = $panel_view->type == t('Overridden') ? t('Revert') : t('Delete');
$ops[] = l($text, "admin/panels/views/delete/{$panel_view->name}");
}
else {
if (empty($panel_view->disabled)) {
$ops[] = l(t('Disable'), "admin/panels/views/disable/{$panel_view->name}", NULL, drupal_get_destination());
}
else {
$ops[] = l(t('Enable'), "admin/panels/views/enable/{$panel_view->name}", NULL, drupal_get_destination());
}
}
$item = array();
$item[] = check_plain($panel_view->title);
$item[] = check_plain($panel_view->name);
// this is safe as it's always programmatic
$item[] = $panel_view->type;
$item[] = check_plain($panel_view->view);
$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_view->type . $item[0];
break;
case 'view':
$sorts[] = $item[2];
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);
$output .= $form;
return $output;
}
/**
* Form to select a view for creating a new view pane.
*/
function panels_views_add_view_form() {
$form['view'] = array(
'#type' => 'select',
'#options' => panels_views_get_all_views(),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Create panel view'),
);
return $form;
}
function theme_panels_views_add_view_form($form) {
$row = array(
drupal_render($form['view']),
drupal_render($form['submit']),
);
return theme('table', array(), array(
$row,
)) . drupal_render($form);
}
function panels_views_add_view_form_submit($form_id, $form_values) {
return 'admin/panels/views/add/' . $form_values['view'];
}
/**
* Page callback to add a new view pane from an existing view.
*/
function panels_views_add_view($view_name) {
$view = views_get_view($view_name);
if (empty($view)) {
return drupal_not_found();
}
return drupal_get_form('panels_views_edit_view_form', $view, panels_views_default_view_pane($view));
}
/**
* Page callback to edit a view pane.
*/
function panels_views_edit_view($view_name) {
$pv = panels_views_load($view_name);
if (empty($pv)) {
return drupal_not_found();
}
$view = views_get_view($pv->view);
drupal_set_title(t("Edit '@title'", array(
'@title' => $pv->title,
)));
return drupal_get_form('panels_views_edit_view_form', $view, $pv);
}
/**
* Form to add or edit add a view pane.
*/
function panels_views_edit_view_form($view, $panel_view) {
panels_views_pane_arguments($view, $panel_view);
$form['basic'] = array(
'#type' => 'fieldset',
'#title' => t('Basic information'),
);
if (!empty($panel_view->pvid) && is_numeric($panel_view->pvid)) {
$form['pvid'] = array(
'#type' => 'value',
'#value' => $panel_view->pvid,
);
}
$form['view'] = array(
'#type' => 'value',
'#value' => $panel_view->view,
);
$form['basic']['name'] = array(
'#type' => 'textfield',
'#title' => t('Panel view name'),
'#description' => t('Enter a unique name for this view pane. It must contain only letters and numbers.'),
'#default_value' => $panel_view->name,
);
$form['basic']['title'] = array(
'#type' => 'textfield',
'#title' => t('Panel view title'),
'#description' => t('The title of the pane; this will appear in the add content dialog.'),
'#default_value' => $panel_view->title,
);
$form['basic']['description'] = array(
'#type' => 'textfield',
'#title' => t('Description'),
'#description' => t('This description will be shown to the user when as a hover tip when adding this pane.'),
'#default_value' => $panel_view->description,
);
$form['basic']['category'] = array(
'#type' => 'textfield',
'#title' => t('Category'),
'#category' => t('The category this view will appear in using the add content dialog.'),
'#default_value' => $panel_view->category,
);
$form['basic']['category_weight'] = array(
'#type' => 'select',
'#default_value' => $panel_view->category_weight,
'#title' => t('Category weight'),
'#description' => t('The weight of the category; lower numbers will appear closer to the top of the dialog.'),
'#options' => drupal_map_assoc(range(-10, 10)),
);
$form['basic']['view_type'] = array(
'#type' => 'select',
'#default_value' => $panel_view->view_type,
'#title' => t('View type'),
'#description' => t('Select which type of the view to display.'),
'#options' => array(
'page' => t('Page'),
'block' => t('Block'),
'embed' => t('Embedded'),
),
);
$form['contexts'] = array(
'#tree' => TRUE,
);
views_load_cache();
$arginfo = _views_get_arguments();
panels_load_include('plugins');
$contexts = panels_get_contexts();
$context_options = array(
'any' => t('Any context'),
);
foreach ($contexts as $name => $context) {
$context_options[$name] = $context['title'];
}
asort($context_options);
foreach ($panel_view->contexts as $id => $info) {
$name = $arginfo[$view->argument[$id]['type']]['name'];
$form['contexts'][$id] = array(
'#type' => 'fieldset',
'#title' => t('Argument: @arg', array(
'@arg' => $name,
)),
'#tree' => TRUE,
);
$form['contexts'][$id]['type'] = array(
'#type' => 'select',
'#options' => array(
'wildcard' => t('Argument wildcard'),
'none' => t('No argument'),
'context' => t('From context'),
'panel' => t('From panel argument'),
'fixed' => t('Fixed'),
'user' => t('Input on pane config'),
),
'#title' => t('Argument source'),
'#default_value' => $panel_view->contexts[$id]['type'],
);
$form['contexts'][$id]['context'] = array(
'#type' => 'select',
'#title' => t('Required context'),
'#description' => t('If "From context" is selected, which context to require.'),
'#default_value' => $panel_view->contexts[$id]['context'],
'#options' => $context_options,
);
$form['contexts'][$id]['panel'] = array(
'#type' => 'select',
'#title' => t('Panel argument'),
'#description' => t('If "From panel argument" is selected, which panel argument to use.'),
'#default_value' => $panel_view->contexts[$id]['panel'],
'#options' => array(
0 => t('First'),
1 => t('Second'),
2 => t('Third'),
3 => t('Fourth'),
4 => t('Fifth'),
5 => t('Sixth'),
),
);
$form['contexts'][$id]['fixed'] = array(
'#type' => 'textfield',
'#title' => t('Fixed argument'),
'#description' => t('If "Fixed" is selected, what to use as an argument.'),
'#default_value' => $panel_view->contexts[$id]['fixed'],
);
$form['contexts'][$id]['label'] = array(
'#type' => 'textfield',
'#title' => t('Label'),
'#description' => t('If this argument is presented to the panels user, what label to apply to it.'),
'#default_value' => empty($panel_view->contexts[$id]['label']) ? $name : $panel_view->contexts[$id]['label'],
);
}
$form['pager'] = array(
'#type' => 'fieldset',
'#title' => t('Paging information'),
);
$form['pager']['use_pager'] = array(
'#type' => 'checkbox',
'#title' => t('Use pager'),
'#description' => t('Use a pager with this view'),
'#default_value' => $panel_view->use_pager,
);
$form['pager']['pager_id'] = array(
'#type' => 'textfield',
'#title' => t('Pager ID'),
'#description' => t('If using a pager, what pager ID to use; every pager on the page should be unique and you should always use the lowest pager ID available. Use 0 if at all possible.'),
'#default_value' => $panel_view->pager_id,
);
$form['pager']['allow_use_pager'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the use pager setting.'),
'#default_value' => $panel_view->allow_use_pager,
);
$form['pager']['nodes_per_page'] = array(
'#type' => 'textfield',
'#title' => t('Items to display'),
'#description' => t('The maximum number of nodes to display.'),
'#default_value' => $panel_view->nodes_per_page,
);
$form['pager']['allow_nodes_per_page'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the items to display setting'),
'#default_value' => $panel_view->allow_nodes_per_page,
);
$form['pager']['offset'] = array(
'#type' => 'textfield',
'#title' => t('Offset'),
'#description' => t('Enter the item number to start at; this option only works if "use pager" is not checked. Enter 0 to start at the first item, 1 to start at the second, etc.'),
'#default_value' => $panel_view->offset,
);
$form['pager']['allow_offset'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the offset setting'),
'#default_value' => $panel_view->allow_offset,
);
$form['deco'] = array(
'#type' => 'fieldset',
'#title' => t('Pane decorations'),
);
$form['deco']['link_to_view'] = array(
'#type' => 'checkbox',
'#title' => t('Link to view'),
'#description' => t('If checked, link the title of the pane to the view.'),
'#default_value' => $panel_view->link_to_view,
);
$form['deco']['allow_link_to_view'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the link to view setting.'),
'#default_value' => $panel_view->allow_link_to_view,
);
$form['deco']['more_link'] = array(
'#type' => 'checkbox',
'#title' => t('More link'),
'#description' => t('If checked, Panels will provide a "more" link that links to the view URL; this is different from the view\'s "more" link which will automatically be disabled.'),
'#default_value' => $panel_view->more_link,
);
$form['deco']['allow_more_link'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the "more" link setting.'),
'#default_value' => $panel_view->allow_more_link,
);
$form['deco']['more_text'] = array(
'#type' => 'textfield',
'#title' => t('More link text'),
'#description' => t('If you checked the above box allowing Panels to provide its own "more" link, Panels will render that link using the text you enter here. If left blank, defaults to "more".'),
'#default_value' => $panel_view->more_text,
);
$form['deco']['allow_more_text'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the "more" link text.'),
'#default_value' => $panel_view->allow_more_text,
);
$form['deco']['feed_icons'] = array(
'#type' => 'checkbox',
'#title' => t('Show feed icons'),
'#description' => t('If checked, any feed icons provided by the view will be visible in the pane.'),
'#default_value' => $panel_view->feed_icons,
);
$form['deco']['allow_feed_icons'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the feed icon setting.'),
'#default_value' => $panel_view->allow_feed_icons,
);
$form['deco']['url_override'] = array(
'#type' => 'checkbox',
'#title' => t('Override the panel URL with a manually set URL.'),
'#default_value' => $panel_view->url_override,
);
$form['deco']['url'] = array(
'#type' => 'textfield',
'#title' => t('Override view URL'),
'#description' => t('If override URL is set, the URL the view thinks it is using; all "more", "exposed filters", "summary" and "feed" type links will use this URL.') . ' ' . t('You may use $arg to pass panel arguments to the view.'),
'#default_value' => $panel_view->url,
);
$form['deco']['allow_url_override'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the URL override setting.'),
'#default_value' => $panel_view->allow_url_override,
);
$form['deco']['url_from_panel'] = array(
'#type' => 'checkbox',
'#title' => t('Set view URL to panel URL'),
'#description' => t('If checked, the URL of the view will be changed to the URL of the panel; this setting is ignored if the "Override view URL" setting, above, is set or allowed.'),
'#default_value' => $panel_view->url_from_panel,
);
$form['deco']['allow_url_from_panel'] = array(
'#type' => 'checkbox',
'#title' => t('Allow the pane configuration to modify the "set view URL to panel URL" setting.'),
'#default_value' => $panel_view->allow_url_from_panel,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
/**
* Validate the edit form.
*/
function panels_views_edit_view_form_validate($form_id, $form_values, $form) {
// Test uniqueness of name:
if (!$form_values['name']) {
form_error($form['basic']['name'], t('Panel view name is required.'));
}
else {
if (preg_match("/[^A-Za-z0-9_]/", $form_values['name'])) {
form_error($form['basic']['name'], t('Name must be alphanumeric or underscores only.'));
}
else {
$query = "SELECT pvid FROM {panels_views} WHERE name = '%s'";
if (!empty($form_values['pvid']) && is_numeric($form_values['pvid'])) {
$query .= " AND pvid != {$form_values['pvid']}";
}
if (db_result(db_query($query, $form_values['name']))) {
form_error($form['basic']['name'], t('Panel name must be unique.'));
}
}
}
}
/**
* Submit the edit form and save the values.
*/
function panels_views_edit_view_form_submit($form_id, $form_values) {
$form_values['contexts'] = isset($form_values['contexts']) ? $form_values['contexts'] : array();
$pv = new stdClass();
foreach (array_keys(panels_views_pane_fields()) as $field) {
$pv->{$field} = $form_values[$field];
}
panels_views_save($pv);
drupal_set_message(t("The panel view has been saved."));
return 'admin/panels/views';
}
/**
* Provide a form to confirm deletion of a view pane.
*/
function panels_views_delete_confirm($panel_view) {
if (!is_object($panel_view)) {
$panel_view = panels_views_load($panel_view);
}
if (empty($panel_view) || empty($panel_view->pvid)) {
return drupal_not_found();
}
$form['pvid'] = array(
'#type' => 'value',
'#value' => $panel_view->pvid,
);
return confirm_form($form, t('Are you sure you want to delete the panel view "@title"?', array(
'@title' => $panel_view->title,
)), $_GET['destination'] ? $_GET['destination'] : 'admin/panels/views', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
/**
* Handle the submit button to delete a view pane.
*/
function panels_views_delete_confirm_submit($form_id, $form) {
if ($form['confirm']) {
panels_views_delete((object) $form);
return 'admin/panels/views';
}
}
/**
* Page callback to import a view pane.
*/
function panels_views_import_view() {
if ($_POST['form_id'] == 'panels_views_edit_view_form') {
$panel_view = $_SESSION['pv_import'];
drupal_set_title(t('Import panel view "@s"', array(
'@s' => $panel_view->title,
)));
$view = views_get_view($panel_view->view);
return drupal_get_form('panels_views_edit_view_form', $view, $panel_view);
}
return drupal_get_form('panels_views_import_form');
}
/**
* Form for the view pane import.
*/
function panels_views_import_form() {
$form['panel_view'] = array(
'#type' => 'textarea',
'#title' => t('Panel view code'),
'#cols' => 60,
'#rows' => 15,
'#description' => t('Cut and paste the results of an exported panel view here.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
$form['#redirect'] = NULL;
return $form;
}
/**
* Handle the submit button on importing a view pane.
*/
function panels_views_import_form_submit($form_id, $form) {
ob_start();
eval($form['panel_view']);
ob_end_clean();
if (isset($panel_view)) {
$view = views_get_view($panel_view->view);
if (empty($view)) {
drupal_set_message(t('Unable to load the view for that import. Be sure the view already exists in your system.'));
return;
}
drupal_set_title(t('Import panel view "@s"', array(
'@s' => $panel_view->title,
)));
$_SESSION['pv_import'] = $panel_view;
$output = drupal_get_form('panels_views_edit_view_form', $view, $panel_view);
print theme('page', $output);
exit;
}
else {
drupal_set_message(t('Unable to get a panel view out of that.'));
}
}
/**
* Page callback to export a view pane.
*/
function panels_views_export_view($pv, $prefix = '') {
if (!is_object($pv)) {
$pv = panels_views_load($pv);
}
if (empty($pv)) {
return drupal_not_found();
}
drupal_set_title(check_plain($pv->title));
$code = panels_views_export($pv);
$lines = substr_count($code, "\n");
$form['code'] = array(
'#type' => 'textarea',
'#title' => $pv->title,
'#default_value' => $code,
'#rows' => $lines,
);
return $form;
}
/**
* Enable a default view pane.
*/
function panels_views_enable_page($name = NULL) {
$defaults = panels_views_default_panels();
if (isset($defaults[$name])) {
$status = variable_get('panels_views_defaults', array());
$status[$name] = FALSE;
variable_set('panels_views_defaults', $status);
drupal_set_message(t('Panel view enabled'));
}
drupal_goto();
}
/**
* Disable a default view pane.
*/
function panels_views_disable_page($name = NULL) {
$defaults = panels_views_default_panels();
if (isset($defaults[$name])) {
$status = variable_get('panels_views_defaults', array());
$status[$name] = TRUE;
variable_set('panels_views_defaults', $status);
drupal_set_message(t('Panel view disabled'));
}
drupal_goto();
}
// -------------------------------------------------------------------------
// Content type routines.
/**
* Implementation of hook_panels_content_types().
*/
function panels_views_panels_content_types() {
$items['views2'] = array(
'title' => t('View'),
'content_types' => 'panels_views_content_types',
'render callback' => 'panels_views_render',
'add callback' => 'panels_views_edit',
'edit callback' => 'panels_views_edit',
'title callback' => 'panels_views_title',
'add validate callback' => 'panels_views_edit_validate',
'edit validate callback' => 'panels_views_edit_validate',
);
return $items;
}
/**
* Return a list of each view type we support.
*/
function panels_views_content_types() {
$panes = panels_views_load_all();
$types = array();
foreach ($panes as $name => $pv) {
// Skip default but disabled panel views.
if (!empty($pv->disabled)) {
continue;
}
$contexts = array();
if (!empty($pv->contexts)) {
foreach ($pv->contexts as $context) {
if ($context['type'] == 'context') {
$contexts[] = new panels_required_context($context['label'], $context['context']);
}
}
}
$types[$name] = array(
'title' => filter_xss_admin($pv->title),
'icon' => $pv->view_type == 'block' ? 'icon_views_block.png' : 'icon_views_page.png',
'description' => filter_xss_admin($pv->description),
'path' => panels_get_path('content_types/views'),
'required context' => $contexts,
'category' => empty($pv->category) ? array(
t('Views'),
-1,
) : array(
$pv->category,
$pv->category_weight,
),
);
}
return $types;
}
/**
* Render a view as a pane.
*/
function panels_views_render($conf, $panel_args, &$contexts) {
$pv = panels_views_load($conf['name']);
if (empty($pv)) {
return;
}
$v = views_get_view($pv->view);
// no view, we go no further
if (empty($v)) {
return;
}
// Use clone to make sure this is fresh.
$view = drupal_clone($v);
// Check to make sure the user can view this view.
if (function_exists('views_access') && !views_access($view)) {
return;
}
$args = array();
if (!empty($pv->contexts)) {
foreach ($pv->contexts as $id => $data) {
switch ($data['type']) {
case 'context':
$c = array_shift($contexts);
$args[] = $c->argument;
break;
case 'fixed':
$args[] = $data['fixed'];
break;
case 'panel':
// Only fill $args if a panel arg was passed in that belongs there
if (array_key_exists($data['panel'], $panel_args)) {
$args[] = $panel_args[$data['panel']];
}
break;
case 'user':
$args[] = $conf['arguments'][$id];
break;
case 'wildcard':
// Put in the wildcard.
$args[] = $view->arguments[$id]['wildcard'] ? $view->arguments[$id]['wildcard'] : '*';
break;
case 'none':
default:
// Put in NULL.
// views.module knows what to do with NULL (or missing) arguments
$args[] = NULL;
break;
}
}
}
if ($pv->allow_url_override && $conf['url']) {
$view->url = $conf['url'];
}
else {
if ($pv->url_override) {
$view->url = $pv->url;
}
}
$block = new stdClass();
$block->module = 'views';
$block->delta = $view->name;
$view_type = $pv->view_type == 'embed' ? 'page' : $pv->view_type;
$block->subject = views_get_title($view, $view_type, $args);
// link to view
if ($pv->allow_link_to_view && !empty($conf['link_to_view']) || !$pv->allow_link_to_view && $pv->link_to_view) {
$block->title_link = views_get_url($view, $args);
}
// more link
if ($pv->allow_more_link && !empty($conf['more_link']) || !$pv->allow_more_link && $pv->more_link) {
$block->more = array(
'href' => views_get_url($view, $args),
);
$view->block_more = FALSE;
// Alternative "more" link text
if ($pv->allow_more_text && $conf['more_text']) {
$block->more['title'] = $conf['more_text'];
}
else {
if ($pv->more_text) {
$block->more['title'] = $pv->more_text;
}
}
}
// Turn on pager?
if ($pv->allow_use_pager) {
$pager_id = empty($conf['use_pager']) ? 0 : intval($conf['pager_id']) + 1;
}
else {
$pager_id = empty($pv->use_pager) ? 0 : intval($pv->pager_id) + 1;
}
$nodes_per_page = $pv->allow_nodes_per_page ? $conf['nodes_per_page'] : $pv->nodes_per_page;
$offset = $pv->allow_offset ? $conf['offset'] : $pv->offset;
$stored_feeds = drupal_add_feed();
// remove any trailing NULL arguments as these are non-args:
while (count($args) && end($args) === NULL) {
array_pop($args);
}
$block->content = views_build_view($pv->view_type, $view, $args, $pager_id, $nodes_per_page, 0, $offset);
if ($view->num_rows < $nodes_per_page) {
unset($block->more);
}
if ($pv->allow_feed_icons && !empty($conf['feed_icons']) || !$pv->allow_feed_icons && $pv->feed_icons) {
$new_feeds = drupal_add_feed();
if ($diff = array_diff(array_keys($new_feeds), array_keys($stored_feeds))) {
foreach ($diff as $url) {
$block->feeds[$url] = $new_feeds[$url];
}
}
}
// Provide administrative links
if (user_access('administer views')) {
$block->admin_links['update'] = array(
'title' => t('Edit view'),
'alt' => t("Edit this view"),
'href' => $view->vid ? "admin/build/views/{$view->name}/edit" : "admin/build/views/add/{$view->name}",
'query' => drupal_get_destination(),
);
}
return $block;
}
/**
* Provide the pane edit dialog.
*/
function panels_views_edit($id, $parents, $conf = array()) {
$pv = panels_views_load($id);
if (empty($pv)) {
$form['markup'] = array(
'#value' => t('The view for this pane is not valid or has been deleted from the system. This pane cannot render; you must either delete this pane or restore the panel view. If you save this pane and then restore the panel view, your settings may be lost.'),
);
return $form;
}
// Provide defaults for the items we let the user edit.
if (empty($conf)) {
if ($pv->allow_type) {
$conf['view_type'] = $pv->view_type;
}
if ($pv->allow_link_to_view) {
$conf['link_to_view'] = $pv->link_to_view;
}
if ($pv->allow_more_link) {
$conf['more_link'] = $pv->more_link;
}
if ($pv->allow_more_text) {
$conf['more_text'] = $pv->more_text;
}
if ($pv->allow_feed_icons) {
$conf['feed_icons'] = $pv->feed_icons;
}
if ($pv->allow_use_pager) {
$conf['use_pager'] = $pv->use_pager;
$conf['pager_id'] = $pv->pager_id;
}
if ($pv->allow_nodes_per_page) {
$conf['nodes_per_page'] = $pv->nodes_per_page;
}
if ($pv->allow_offset) {
$conf['offset'] = $pv->offset;
}
if ($pv->allow_url_override) {
$conf['url'] = $pv->url;
}
if ($pv->allow_url_from_panel) {
$conf['url_from_panel'] = $pv->url_from_panel;
}
}
$form['title'] = array(
'#type' => 'hidden',
'#value' => $pv->title,
);
$form['name'] = array(
'#type' => 'hidden',
'#value' => $id,
);
foreach ($pv->contexts as $id => $data) {
if ($data['type'] == 'user') {
$form['arguments'][$id] = array(
'#type' => 'textfield',
'#default_value' => $conf['arguments'][$id],
'#title' => $data['label'],
);
}
}
// Provide form gadgets only on the things that th euser can change.
if ($pv->allow_type) {
$form['view_type'] = array(
'#type' => 'select',
'#default_value' => $conf['view_type'],
'#title' => t('View type'),
'#description' => t('Select which type of the view to display.'),
'#options' => array(
'page' => t('Page'),
'block' => t('Block'),
'embed' => t('Embedded'),
),
);
}
if ($pv->allow_link_to_view) {
$form['link_to_view'] = array(
'#type' => 'checkbox',
'#default_value' => $conf['link_to_view'],
'#title' => t('Link title to view'),
'#description' => t('If checked, the title will be a link to the view.'),
);
}
if ($pv->allow_more_link) {
$form['more_link'] = array(
'#type' => 'checkbox',
'#default_value' => $conf['more_link'],
'#title' => t('Provide a "more" link that links to the view'),
'#description' => t('This is independent of any more link that may be provided by the view itself; if you see two more links, turn this one off. Views will only provide a more link if using the "block" type, however, so if using embed, use this one.'),
);
if ($pv->allow_more_text) {
$form['more_text'] = array(
'#type' => 'textfield',
'#default_value' => $conf['more_text'],
'#title' => t('"More" link text'),
'#description' => t('If you activated panels own "more" link above, this allows you to customize the text to display.'),
);
}
}
if ($pv->allow_feed_icons) {
$form['feed_icons'] = array(
'#type' => 'checkbox',
'#default_value' => $conf['feed_icons'],
'#title' => t('Display feed icons'),
'#description' => t('If checked, any feed icons provided by this view will be displayed.'),
);
}
if ($pv->allow_use_pager) {
$form['pager_aligner_start'] = array(
'#value' => '<div class="option-text-aligner">',
);
$form['use_pager'] = array(
'#type' => 'checkbox',
'#title' => t('Use pager'),
'#default_value' => $conf['use_pager'],
'#id' => 'use-pager-checkbox',
);
$form['pager_id'] = array(
'#type' => 'textfield',
'#default_value' => $conf['pager_id'],
'#title' => t('Pager ID'),
'#size' => 4,
'#id' => 'use-pager-textfield',
);
$form['pager_aligner_stop'] = array(
'#value' => '</div><div style="clear: both; padding: 0; margin: 0"></div>',
);
}
if ($pv->allow_nodes_per_page) {
$form['nodes_per_page'] = array(
'#type' => 'textfield',
'#default_value' => $conf['nodes_per_page'],
'#title' => t('Num posts'),
'#size' => 4,
'#description' => t('Select the number of posts to display, or 0 to display all results.'),
);
}
if ($pv->allow_offset) {
$form['offset'] = array(
'#type' => 'textfield',
'#default_value' => $conf['offset'],
'#title' => t('Offset'),
'#size' => 4,
'#description' => t('Enter the item number to start at; this option only works if "use pager" is not checked. Enter 0 to start at the first item, 1 to start at the second, etc.'),
);
}
if ($pv->allow_url_override) {
// TODO: Because javascript in the dialogs is kind of weird, dependent checkboxes
// don't work right for external modules. This needs fixing in panels itself.
$form['url'] = array(
'#type' => 'textfield',
'#default_value' => $conf['url'],
'#title' => t('Override URL'),
'#size' => 30,
'#description' => t('If this is set, override the View URL; this can sometimes be useful to set to the panel URL.') . ' ' . t('You may use $arg to pass panel arguments to the view.'),
);
}
if ($pv->allow_url_from_panel) {
$form['url_from_panel'] = array(
'#type' => 'checkbox',
'#title' => t('Set view URL to panel URL'),
'#default_value' => $conf['url_from_panel'],
);
}
return $form;
}
/**
* Returns the administrative title for a type.
*/
function panels_views_title($conf) {
return $conf['title'];
}
// -------------------------------------------------------------------------
// Panels views helpers.
/**
* Get a list of all views as an option array.
*
* This really should be included with views.
*/
function panels_views_get_all_views() {
views_load_cache();
$result = db_query("SELECT name, description FROM {view_view} ORDER BY name");
$views = array();
while ($view = db_fetch_object($result)) {
$views[$view->name] = check_plain($view->name);
}
$default_views = _views_get_default_views();
$views_status = variable_get('views_defaults', array());
foreach ($default_views as $view) {
if (!$views[$view->name] && ($views_status[$view->name] == 'enabled' || !$views_status[$view->name] && !$view->disabled)) {
$views[$view->name] = check_plain($view->name);
}
}
return $views;
}
// -------------------------------------------------------------------------
// Database routines
/**
* Poor man's schema API.
*/
function panels_views_pane_fields() {
// Schema version 0
$names = array(
'pvid' => array(
'default' => 'NULL',
'arg' => '%d',
'definition' => 'integer NOT NULL PRIMARY KEY',
'primary' => TRUE,
),
'view' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'name' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255) UNIQUE',
),
'description' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'title' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'category' => array(
'default' => 'Views',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'category_weight' => array(
'default' => -1,
'arg' => "%d",
'definition' => 'integer',
),
'view_type' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'use_pager' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'pager_id' => array(
'default' => 0,
'arg' => '%d',
'definition' => 'integer',
),
'nodes_per_page' => array(
'default' => 0,
'arg' => '%d',
'definition' => 'integer',
),
'offset' => array(
'default' => 0,
'arg' => '%d',
'definition' => 'integer',
),
'link_to_view' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'more_link' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'more_text' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'feed_icons' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'url_override' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'url' => array(
'default' => '',
'arg' => "'%s'",
'definition' => 'varchar(255)',
),
'url_from_panel' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'contexts' => array(
'default' => array(),
'arg' => "'%s'",
'serialize' => TRUE,
'definition' => 'text',
),
// Whether or not array these things are allowed from the pane UI.
'allow_type' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_nodes_per_page' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_offset' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_use_pager' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_link_to_view' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_more_link' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_more_text' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_feed_icons' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_url_override' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
'allow_url_from_panel' => array(
'default' => FALSE,
'arg' => '%d',
'definition' => 'integer',
),
);
return $names;
}
/**
* Provide default settings for a new view pane.
*/
function panels_views_default_view_pane($view) {
$names = panels_views_pane_fields();
$panel_view = new stdClass();
foreach ($names as $name => $info) {
$panel_view->{$name} = $info['default'];
}
$panel_view->view = $panel_view->name = $view->name;
$panel_view->description = $view->description;
if ($view->page) {
$panel_view->view_type = 'page';
$panel_view->nodes_per_page = $view->nodes_per_page;
$panel_view->title = $view->page_title;
}
else {
$panel_view->view_type = 'block';
$panel_view->nodes_per_page = $view->nodes_per_block;
$panel_view->title = $view->block_title;
}
return $panel_view;
}
/**
* Adjust a pane for a view's arguments, adding or subtracting as needed to
* match the current view's argument configuration.
*/
function panels_views_pane_arguments($view, &$panel_view) {
$contexts = array();
foreach ($view->argument as $id => $arg) {
if (empty($panel_view->contexts[$id])) {
$contexts[$id] = array(
'type' => 'context',
'context' => 'any',
'panel' => 0,
'fixed' => '',
);
}
else {
$contexts[$id] = $panel_view->contexts[$id];
}
}
// By copying this back, we automatically erase any arguments that may
// no longer exist.
$panel_view->contexts = $contexts;
}
/**
* Write a view pane to the database.
*/
function panels_views_save($panel_view) {
$fields = $types = $values = $pairs = array();
// If pvid is empty, this is an insert, otherwise an update.
$insert = empty($panel_view->pvid);
// Build arrays of fields and types (resp. pairs of both) and of values.
foreach (panels_views_pane_fields() as $field => $data) {
$primary = !empty($data['primary']);
// Skip primary key and empty values.
if (!$primary && isset($panel_view->{$field})) {
if ($insert) {
$fields[] = $field;
$types[] = $data['arg'];
}
else {
$pairs[] = "{$field} = {$data['arg']}";
}
// Build the $values array, serializing some fields.
$serialize = !empty($data['serialize']);
$values[] = $serialize ? serialize($panel_view->{$field}) : $panel_view->{$field};
}
}
if ($insert) {
// Determine the new primary key.
$panel_view->pvid = db_next_id('{panels_views}_pvid');
// Build the query adding the new primary key.
$sql = 'INSERT INTO {panels_views} (' . implode(', ', $fields) . ', pvid) VALUES (' . implode(', ', $types) . ', %d)';
}
else {
// Build the query filtering by the primary key.
$sql = 'UPDATE {panels_views} SET ' . implode(', ', $pairs) . ' WHERE pvid = %d';
}
$values[] = $panel_view->pvid;
db_query($sql, $values);
}
/**
* Load a view pane from the database.
*/
function panels_views_load($name) {
static $panel_views = array();
if (array_key_exists($name, $panel_views)) {
return $panel_views[$name];
}
$pv = db_fetch_object(db_query("SELECT * FROM {panels_views} WHERE name = '%s'", $name));
if (empty($pv)) {
$defaults = panels_views_default_panels();
if (isset($defaults[$name])) {
$pv = $defaults[$name];
$status = variable_get('panels_views_defaults', array());
// Determine if default panel is enabled or disabled.
if (isset($status[$pv->name])) {
$pv->disabled = $status[$pv->name];
}
$panel_views[$name] = $pv;
return $pv;
}
$panel_views[$name] = NULL;
return;
}
$names = panels_views_pane_fields();
foreach ($names as $key => $data) {
if (!empty($data['serialize'])) {
$pv->{$key} = unserialize($pv->{$key});
}
}
$panel_views[$name] = $pv;
return $panel_views[$name];
}
/**
* Load all view panes.
*/
function panels_views_load_all() {
static $panel_views = NULL;
if (isset($panel_views)) {
return $panel_views;
}
$panel_views = array();
$names = panels_views_pane_fields();
$result = db_query("SELECT * FROM {panels_views}");
while ($pv = db_fetch_object($result)) {
foreach ($names as $name => $data) {
if (!empty($data['serialize'])) {
$pv->{$name} = unserialize($pv->{$name});
}
}
$pv->type = t('Local');
$panel_views[$pv->name] = $pv;
}
// Now load all the in-code versions
$status = variable_get('panels_views_defaults', array());
foreach (panels_views_default_panels() as $pv) {
// Determine if default panel is enabled or disabled.
if (isset($status[$pv->name])) {
$pv->disabled = $status[$pv->name];
}
if (!empty($panel_views[$pv->name])) {
$panel_views[$pv->name]->type = t('Overridden');
}
else {
$pv->type = t('Default');
$panel_views[$pv->name] = $pv;
}
}
return $panel_views;
}
/**
* Get all 'default' view panes.
*
* @ingroup HookInvokers
*/
function panels_views_default_panels() {
$panels = module_invoke_all('default_panel_views');
if (!is_array($panels)) {
$panels = array();
}
return $panels;
}
/**
* Delete a view pane.
*/
function panels_views_delete($pv) {
db_query("DELETE FROM {panels_views} WHERE pvid = %d", $pv->pvid);
return TRUE;
}
/**
* Export a view pane into PHP code.
*
* This code is suitable to run through eval()
* and then be used in panels_views_save().
*/
function panels_views_export($pv, $prefix = '') {
$output = '';
$fields = panels_views_pane_fields();
$output .= $prefix . '$panel_view = new stdClass()' . ";\n";
foreach ($fields as $field => $data) {
$value = empty($data['primary']) ? $pv->{$field} : 'new';
$output .= $prefix . ' $panel_view->' . $field . ' = ' . panels_var_export($value, ' ') . ";\n";
}
return $output;
}
/**
* Implementation of hook_panels_exportables().
*/
function panels_views_panels_exportables($op = 'list', $panels = NULL, $name = 'foo') {
static $all_panels = NULL;
if ($op == 'list') {
if (empty($all_panels)) {
$all_panels = panels_views_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_views().\n";
$code .= " */\n";
$code .= "function " . $name . "_default_panel_views() {\n";
foreach ($panels as $panel => $truth) {
$code .= panels_views_export($all_panels[$panel], ' ');
$code .= ' $panel_views[\'' . check_plain($panel) . '\'] = $panel_view;' . "\n\n\n";
}
$code .= " return \$panel_views;\n";
$code .= "}\n";
return $code;
}
}
/**
* Implementation of hook_form_alter().
*
* Ugly, hacky fix to compensate for the fact that panels_views isn't aware when
* views changes the system name of a view. With the system name wrong,
* panels_views breaks.
*/
function panels_views_form_alter($form_id, &$form) {
if ($form_id == 'views_edit_view' && !empty($form['basic-info']['name']['#default_value'])) {
$pvids = array();
$result = db_query("SELECT pvid FROM {panels_views} WHERE view = '%s'", $form['basic-info']['name']['#default_value']);
while ($row = db_fetch_object($result)) {
$pvids[] = $row->pvid;
}
if (!empty($pvids)) {
$form['dependent_pvids'] = array(
'#type' => 'value',
'#value' => $pvids,
);
$form['#submit'] += array(
'panels_views_update_pvids_submit' => array(),
);
}
}
}
/**
* If we've gotten this far, then we know we've got pvids that could need
* updating. Don't bother with fancy footwork to see if the view name was
* actually changed - just update em to be safe. Also no need to update
* the whole view pane, so we just batch update using IN ().
*
*/
function panels_views_update_pvids_submit($form_id, $form_values) {
db_query("UPDATE {panels_views} SET view = '%s' WHERE pvid IN (" . implode(', ', $form_values['dependent_pvids']) . ")", $form_values['name']);
}
Functions
Name | Description |
---|---|
panels_views_add_view | Page callback to add a new view pane from an existing view. |
panels_views_add_view_form | Form to select a view for creating a new view pane. |
panels_views_add_view_form_submit | |
panels_views_content_types | Return a list of each view type we support. |
panels_views_default_panels | Get all 'default' view panes. |
panels_views_default_view_pane | Provide default settings for a new view pane. |
panels_views_delete | Delete a view pane. |
panels_views_delete_confirm | Provide a form to confirm deletion of a view pane. |
panels_views_delete_confirm_submit | Handle the submit button to delete a view pane. |
panels_views_disable_page | Disable a default view pane. |
panels_views_edit | Provide the pane edit dialog. |
panels_views_edit_view | Page callback to edit a view pane. |
panels_views_edit_view_form | Form to add or edit add a view pane. |
panels_views_edit_view_form_submit | Submit the edit form and save the values. |
panels_views_edit_view_form_validate | Validate the edit form. |
panels_views_enable_page | Enable a default view pane. |
panels_views_export | Export a view pane into PHP code. |
panels_views_export_view | Page callback to export a view pane. |
panels_views_form_alter | Implementation of hook_form_alter(). |
panels_views_get_all_views | Get a list of all views as an option array. |
panels_views_import_form | Form for the view pane import. |
panels_views_import_form_submit | Handle the submit button on importing a view pane. |
panels_views_import_view | Page callback to import a view pane. |
panels_views_list_views | Page callback to list view panes and the initial form to add new view panes. |
panels_views_load | Load a view pane from the database. |
panels_views_load_all | Load all view panes. |
panels_views_menu | Implementation of hook_menu(). |
panels_views_panels_content_types | Implementation of hook_panels_content_types(). |
panels_views_panels_exportables | Implementation of hook_panels_exportables(). |
panels_views_pane_arguments | Adjust a pane for a view's arguments, adding or subtracting as needed to match the current view's argument configuration. |
panels_views_pane_fields | Poor man's schema API. |
panels_views_perm | Implementation of hook_perm(). |
panels_views_render | Render a view as a pane. |
panels_views_save | Write a view pane to the database. |
panels_views_title | Returns the administrative title for a type. |
panels_views_update_pvids_submit | If we've gotten this far, then we know we've got pvids that could need updating. Don't bother with fancy footwork to see if the view name was actually changed - just update em to be safe. Also no need to update the whole view pane, so… |
theme_panels_views_add_view_form |