FINAL suepr merge step : added all modules to this super repos

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-19 16:46:59 +02:00
7585 changed files with 1723356 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

View File

@@ -0,0 +1,568 @@
<?php
/**
* @file
* Content type plugin to expose all views as content.
*/
if (variable_get('ctools_content_all_views', TRUE)) {
$plugin = array(
'title' => t('All views'),
'defaults' => array(
'override_pager_settings' => FALSE,
'use_pager' => FALSE,
'nodes_per_page' => 10,
'pager_id' => 0,
'offset' => 0,
'more_link' => FALSE,
'feed_icons' => FALSE,
'panel_args' => FALSE,
'link_to_view' => FALSE,
'args' => '',
'url' => '',
),
'add form' => array(
'views_content_views_select_display' => t('Select display'),
'views_content_views_content_type_edit_form' => array(
'default' => TRUE, // put wrapper here, not on the previous form.
'title' => t('Configure view'),
),
),
'all contexts' => TRUE,
);
}
/**
* Return all content types available.
*/
function views_content_views_content_type_content_types($plugin) {
$types = array();
// It can be fairly intensive to calculate this, so let's cache this in the
// cache_views table. The nice thing there is that if views ever change, that
// table will always be cleared. Except for the occasional default view, so
// we must use the Views caching functions in order to respect Views caching
// settings.
views_include('cache');
$data = views_cache_get('views_content_all', TRUE);
if (!empty($data->data)) {
$types = $data->data;
}
if (empty($types)) {
$views = views_get_all_views();
foreach ($views as $view) {
if (empty($view->disabled)) {
$types[$view->name] = _views_content_views_content_type($view);
}
}
views_cache_set('views_content_all', $types, TRUE);
}
return $types;
}
/**
* Return a single content type.
*/
function views_content_views_content_type_content_type($subtype, $plugin) {
$view = views_get_view($name);
if (empty($view)) {
return;
}
return _views_content_views_content_type($view);
}
/**
* Create the content type info array to give back to ctools for a given display.
*/
function _views_content_views_content_type($view) {
$title = $view->get_human_name();
$icon = 'icon_views_page_legacy.png';
return array(
'view' => $view->name,
'title' => $title,
'icon' => $icon,
'description' => filter_xss_admin($view->description),
'category' => t('Views'),
);
}
/**
* Output function for the 'views' content type.
*
* Outputs a view based on the module and delta supplied in the configuration.
*/
function views_content_views_content_type_render($subtype, $conf, $panel_args, $contexts) {
if (!is_array($contexts)) {
$contexts = array($contexts);
}
$view = _views_content_views_update_conf($conf, $subtype);
if (empty($view) || !is_object($view) || empty($view->display_handler)) {
return;
}
if (!$view->display_handler->access($GLOBALS['user'])) {
return;
}
$arguments = explode('/', $_GET['q']);
$args = $conf['args'];
foreach ($arguments as $id => $arg) {
$args = str_replace("%$id", $arg, $args);
}
foreach ($panel_args as $id => $arg) {
if (is_string($arg)) {
$args = str_replace("@$id", $arg, $args);
}
}
$args = preg_replace(',/?(%\d|@\d),', '', $args);
$args = $args ? explode('/', $args) : array();
if ($conf['panel_args'] && is_array($panel_args)) {
$args = array_merge($panel_args, $args);
}
if (isset($conf['context']) && is_array($conf['context'])) {
foreach ($conf['context'] as $count => $context_info) {
if (!strpos($context_info, '.')) {
// old skool: support pre-converter contexts as well.
$cid = $context_info;
$converter = '';
}
else {
list($cid, $converter) = explode('.', $context_info, 2);
}
if (!empty($contexts[$cid])) {
$arg = ctools_context_convert_context($contexts[$cid], $converter, array('sanitize' => FALSE));
array_splice($args, $count, 0, array($arg));
}
else {
// Make sure we put an argument in even if it was not there.
$arg = NULL;
}
}
}
$view->set_arguments($args);
if ($conf['url']) {
$view->override_path = $conf['url'];
}
$block = new stdClass();
$block->module = 'views';
$block->delta = $view->name . '-' . $view->current_display;
if (!empty($conf['link_to_view'])) {
$block->title_link = $view->get_url();
}
if (!empty($conf['more_link'])) {
$block->more = array('href' => $view->get_url());
$view->display_handler->set_option('use_more', FALSE);
}
// Only set use_pager if they differ, this way we can avoid overwriting the
// pager type that Views uses.
if ($conf['override_pager_settings']) {
if (method_exists($view, 'init_pager')) {
// Views 3 version
$view->set_items_per_page($conf['nodes_per_page']);
$view->set_offset($conf['offset']);
$pager = $view->display_handler->get_option('pager');
if ($conf['use_pager'] && ($pager['type'] == 'none' || $pager['type'] == 'some')) {
$pager['type'] = 'full';
}
elseif (!$conf['use_pager'] && $pager['type'] != 'none' && $pager['type'] != 'some') {
$pager['type'] = $view->get_items_per_page() ? 'some' : 'none';
}
if ($conf['use_pager']) {
if (!isset($pager['options']['id']) || $pager['options']['id'] != $conf['pager_id']) {
$pager['options']['id'] = $conf['pager_id'];
}
}
$view->display_handler->set_option('pager', $pager);
}
else {
if (!$view->display_handler->get_option('use_pager') || empty($conf['use_pager'])) {
$view->display_handler->set_option('use_pager', $conf['use_pager']);
}
$view->display_handler->set_option('pager_element', $conf['pager_id']);
$view->display_handler->set_option('items_per_page', $conf['nodes_per_page']);
$view->display_handler->set_option('offset', $conf['offset']);
}
}
$stored_feeds = drupal_add_feed();
$block->content = $view->preview();
$block->title = $view->get_title();
if (empty($view->result) && !$view->display_handler->get_option('empty') && empty($view->style_plugin->definition['even empty'])) {
return;
}
if (!empty($conf['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];
}
}
}
$view->destroy();
return $block;
}
/**
* Returns an edit form for a block.
*/
function views_content_views_select_display($form, &$form_state) {
$view = views_get_view($form_state['subtype_name']);
if (empty($view)) {
return;
}
$displays = array();
foreach ($view->display as $id => $display) {
// Content pane views should never be used this way.
if ($display->display_plugin != 'panel_pane') {
$displays[$id] = views_content_get_display_label($view, $id);
}
}
$form['display'] = array(
'#type' => 'select',
'#title' => t('Display'),
'#options' => $displays,
'#description' => t('Choose which display of this view you wish to use.')
);
return $form;
}
/**
* Submit the basic view edit form.
*
* This just dumps everything into the $conf array.
*/
function views_content_views_select_display_submit(&$form, &$form_state) {
$form_state['conf']['display'] = $form_state['values']['display'];
}
/**
* Returns an edit form for a block.
*/
function views_content_views_content_type_edit_form($form, &$form_state) {
$conf = $form_state['conf'];
$view = _views_content_views_update_conf($conf, $form_state['subtype_name']);
if (empty($view) || !is_object($view)) {
$form['markup'] = array('#value' => t('Broken/missing/deleted view.'));
return;
}
$form_state['title'] = t('Configure view @view (@display)', array('@view' => $view->get_human_name(), '@display' => views_content_get_display_label($view, $view->current_display)));
// @todo
// If using the older format, just a context is listed. We should go through
// and check for that and forcibly set them to the right converter so that
// it doesn't get changed to some whacky default. Oooor just let it get changed
// to 'no context', I suppose.
$required = array();
if (isset($view->display_handler) && $arguments = $view->display_handler->get_handlers('argument')) {
foreach ($arguments as $arg) {
$required[] = new ctools_context_optional($arg->ui_name(), 'any');
}
}
if ($required) {
$form['context'] = ctools_context_converter_selector($form_state['contexts'], $required, isset($conf['context']) ? $conf['context'] : array());
}
$form['link_to_view'] = array(
'#type' => 'checkbox',
'#default_value' => $conf['link_to_view'],
'#title' => t('Link title to view'),
);
$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.'),
);
$form['feed_icons'] = array(
'#type' => 'checkbox',
'#default_value' => $conf['feed_icons'],
'#title' => t('Display feed icons'),
);
$form['pager_settings'] = array(
'#type' => 'fieldset',
'#collapsible' => FALSE,
'#title' => t('Custom pager settings'),
);
$form['pager_settings']['override_pager_settings'] = array(
'#type' => 'checkbox',
'#title' => t('Use different pager settings from view settings'),
'#default_value' => $conf['override_pager_settings'],
'#id' => 'override-pager-checkbox',
);
if ($view->display_handler->get_option('use_ajax')) {
$form['pager_settings']['warning'] = array(
'#value' => '<div>' . t('<strong>Warning: </strong> This view has AJAX enabled. Overriding the pager settings will work initially, but when the view is updated via AJAX, the original settings will be used. You should not override pager settings on Views with the AJAX setting enabled.') . '</div>',
);
}
$form['pager_settings']['use_pager'] = array(
'#prefix' => '<div class="container-inline">',
'#type' => 'checkbox',
'#title' => t('Use pager'),
'#default_value' => $conf['use_pager'],
'#id' => 'use-pager-checkbox',
'#dependency' => array('override-pager-checkbox' => array(1)),
);
$form['pager_settings']['pager_id'] = array(
'#type' => 'textfield',
'#default_value' => $conf['pager_id'],
'#title' => t('Pager ID'),
'#size' => 4,
'#id' => 'use-pager-textfield',
'#dependency' => array('override-pager-checkbox' => array(1), 'use-pager-checkbox' => array(1)),
'#dependency_count' => 2,
'#suffix' => '</div>',
);
$form['pager_settings']['nodes_per_page'] = array(
'#type' => 'textfield',
'#default_value' => $conf['nodes_per_page'],
'#size' => 4,
'#title' => t('Num posts'),
'#dependency' => array('override-pager-checkbox' => array(1)),
);
$form['pager_settings']['offset'] = array(
'#type' => 'textfield',
'#default_value' => $conf['offset'],
'#title' => t('Offset'),
'#size' => 4,
'#description' => t('The number of items to skip and not display.'),
'#dependency' => array('override-pager-checkbox' => array(1)),
);
$form['panel_args'] = array(
'#type' => 'checkbox',
'#title' => t('Send arguments'),
'#default_value' => $conf['panel_args'],
'#description' => t('Select this to send all arguments from the panel directly to the view. If checked, the panel arguments will come after any context arguments above and precede any additional arguments passed in through the Arguments field below. Note that arguments do not include the base URL; only values after the URL or set as placeholders are considered arguments.'),
);
$form['args'] = array(
'#type' => 'textfield',
'#default_value' => $conf['args'],
'#title' => t('Arguments'),
'#size' => 30,
'#description' => t('Additional arguments to send to the view as if they were part of the URL in the form of arg1/arg2/arg3. You may use %0, %1, ..., %N to grab arguments from the URL. Or use @0, @1, @2, ..., @N to use arguments passed into the panel. Note: use these values only as a last resort. In future versions of Panels these may go away.'),
);
$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'),
);
$view->destroy();
return $form;
}
/**
* Store form values in $conf.
*/
function views_content_views_content_type_edit_form_submit(&$form, &$form_state) {
// Copy everything from our defaults.
foreach (array_keys($form_state['plugin']['defaults']) as $key) {
$form_state['conf'][$key] = $form_state['values'][$key];
}
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_content_type_admin_title($subtype, $conf) {
$view = _views_content_views_update_conf($conf, $subtype);
if (!is_object($view)) {
return t('Deleted/missing view @view', array('@view' => $view));
}
$title = views_content_get_display_label($view, $view->current_display);
return t('View: @name', array('@name' => $view->get_human_name() . ': ' . $title));
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_content_type_admin_info($subtype, $conf, $contexts) {
$view = _views_content_views_update_conf($conf, $subtype);
if (!is_object($view)) {
return t('Deleted/missing view @view', array('@view' => $view));
}
$display = empty($conf['display']) ? $view->current_display : $conf['display'];
$block = new stdClass();
$block->title = t('View information');
$block->content = '<ul>';
$block->content .= '<li>' . t('Using display @display.', array('@display' => views_content_get_display_label($view, $display))) . '</li>';
if (!empty($conf['context']) && $arguments = $view->display_handler->get_handlers('argument')) {
$argument = reset($arguments);
foreach ($conf['context'] as $count => $context_info) {
if (!$argument) {
break;
}
if (!strpos($context_info, '.')) {
// old skool: support pre-converter contexts as well.
$cid = $context_info;
$converter = '';
}
else {
list($cid, $converter) = explode('.', $context_info, 2);
}
if (!empty($contexts[$cid])) {
$converters = ctools_context_get_converters($cid . '.', $contexts[$cid]);
$converter = !empty($converters[$context_info]) ? $converters[$context_info] : t('Default');
$block->content .= '<li>' . t('Argument @arg using context @context converted into @converter', array(
'@arg' => $argument->ui_name(), '@context' => $contexts[$cid]->get_identifier(),
'@converter' => $converter)) . '</li>';
}
$argument = next($arguments);
}
}
$block->content .= '<li>' . t('@count items displayed.', array('@count' => $conf['nodes_per_page'])) . '</li>';
if ($conf['use_pager']) {
$block->content .= '<li>' . t('With pager.') . '</li>';
}
else {
$block->content .= '<li>' . t('Without pager.') . '</li>';
}
if ($conf['offset']) {
$block->content .= '<li>' . t('Skipping first @count results', array('@count' => $conf['offset'])) . '</li>';
}
if ($conf['more_link']) {
$block->content .= '<li>' . t('With more link.') . '</li>';
}
if ($conf['feed_icons']) {
$block->content .= '<li>' . t('With feed icon.') . '</li>';
}
if ($conf['panel_args']) {
$block->content .= '<li>' . t('Sending arguments.') . '</li>';
}
if ($conf['args']) {
$block->content .= '<li>' . t('Using arguments: @args', array('@args' => $conf['args'])) . '</li>';
}
if ($conf['url']) {
$block->content .= '<li>' . t('Using url: @url', array('@url' => $conf['url'])) . '</li>';
}
$view->destroy();
return $block;
}
/**
* Update the $conf to deal with updates from Drupal 5.
*
* @param &$conf
* The $conf array to modify.
* @param $subtype
* The subtype in use. This should just be the view name, but in older
* versions it was the view name with a dash and the display ID.
* If this is the case, we can use it to correct the 'display' setting
* in the $conf.
* @return
* The $view with the initialized display. If the $view could not be
* loaded, the name attempted will be loaded for use in errors.
* Correct error checking on this function checks against is_object().
*/
function _views_content_views_update_conf(&$conf, $subtype) {
$plugin = ctools_get_content_type('views');
// Special: Existing content types get a different default than new ones:
if (!empty($conf) && !isset($conf['override_pager_settings'])) {
$conf['override_pager_settings'] = TRUE;
}
// Make sure that our defaults are always set if there is no
// previous setting. This helps updates go more smoothly.
foreach ($plugin['defaults'] as $key => $value) {
if (!isset($conf[$key])) {
$conf[$key] = $value;
}
}
if (strpos($subtype, '-')) {
list($name, $display) = explode('-', $subtype);
$view = views_get_view($name);
if (!isset($conf['display'])) {
$conf['display'] = $display;
}
}
else {
$name = $subtype;
$view = views_get_view($subtype);
$display = isset($conf['display']) ? $conf['display'] : 'default';
}
if (empty($view)) {
return $name;
}
$view->set_display($display);
// $view->current_display will now reflect this value.
// If set NOT to override, go ahead and refresh from the view.
if (empty($conf['override_pager_settings'])) {
if (method_exists($view, 'init_pager')) {
$pager = $view->display_handler->get_option('pager');
$conf['use_pager'] = $pager['type'] != 'none' && $pager['type'] != 'some';
$conf['pager_id'] = isset($pager['options']['id']) ? $pager['options']['id'] : 0;
$conf['offset'] = isset($pager['options']['offset']) ? $pager['options']['offset'] : 0;
$conf['nodes_per_page'] = isset($pager['options']['items_per_page']) ? $pager['options']['items_per_page'] : 0;
}
else {
$conf['use_pager'] = $view->display_handler->get_option('use_pager');
$conf['pager_id'] = $view->display_handler->get_option('element_id');
$conf['nodes_per_page'] = $view->display_handler->get_option('items_per_page');
$conf['offset'] = $view->display_handler->get_option('offset');
}
}
return $view;
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View attachment'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the attachments on a view context.'),
'required context' => new ctools_context_required(t('View'), 'view'),
'defaults' => array(
'which' => array(),
),
);
/**
* Render the node_terms content type.
*/
function views_content_views_attachments_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_attachments';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
foreach ($conf['which'] as $attachment) {
if (isset($output[$attachment])) {
$block->content .= $output[$attachment];
}
}
return $block;
}
function views_content_views_attachments_content_type_edit_form($form, &$form_state) {
$conf = $form_state['conf'];
$form['which'] = array(
'#type' => 'checkboxes',
'#options' => array(
'attachment_before' => t('"Before" attachment'),
'attachment_after' => t('"After" attachment'),
),
'#default_value' => $conf['which'],
);
return $form;
}
function views_content_views_attachments_content_type_edit_form_validate(&$form, &$form_state) {
if (!array_filter($form_state['values']['which'])) {
form_error($form['which'], t('You must select at least one attachment to display.'));
}
}
function views_content_views_attachments_content_type_edit_form_submit(&$form, &$form_state) {
$form_state['conf']['which'] = array_filter($form_state['values']['which']);
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_attachments_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" attachment', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View empty text'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the view empty text if there are no results.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the node_terms content type.
*/
function views_content_views_empty_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_empty';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
if (isset($output['empty'])) {
$block->content = $output['empty'];
}
return $block;
}
function views_content_views_empty_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_empty_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_empty_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" empty text', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View exposed widgets'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the view exposed widgets if there are no results.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the node_terms content type.
*/
function views_content_views_exposed_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_exposed';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
$block->content = $output['exposed'];
return $block;
}
function views_content_views_exposed_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_exposed_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_exposed_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" exposed widgets', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View feed icon'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the view feed icon if there are no results.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the views feed content type.
*/
function views_content_views_feed_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_feed';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
$block->content = $output['feed_icon'];
return $block;
}
function views_content_views_feed_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_feed_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_feed_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" feed icon', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View footer'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the view footer if there are no results.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the node_terms content type.
*/
function views_content_views_footer_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_footer';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
$block->content = $output['footer'];
return $block;
}
function views_content_views_footer_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_footer_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_footer_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" footer', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View header'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the view header if there are no results.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the node_terms content type.
*/
function views_content_views_header_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_header';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
$block->content = $output['header'];
return $block;
}
function views_content_views_header_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_header_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_header_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" header', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* @file
* Allow a view context to display its attachment(s).
*/
$plugin = array(
'title' => t('View pager'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the view pager if there are no results.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the node_terms content type.
*/
function views_content_views_pager_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_pager';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
$block->content = $output['pager'];
return $block;
}
function views_content_views_pager_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_pager_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_pager_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" pager', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,621 @@
<?php
/**
* @file
* Content type plugin to allow Views to be exposed as a display type,
* leaving most of the configuration on the view.
*/
/**
* Implements hook_ctools_content_types()
*/
function views_content_views_panes_ctools_content_types() {
return array(
'title' => t('View panes'),
'admin settings' => 'views_content_admin_form',
'all contexts' => TRUE,
);
}
/**
* Return all content types available.
*/
function views_content_views_panes_content_type_content_types($plugin) {
$types = array();
// It can be fairly intensive to calculate this, so let's cache this in the
// cache_views table. The nice thing there is that if views ever change, that
// table will always be cleared. Except for the occasional default view, so
// we must use the Views caching functions in order to respect Views caching
// settings.
views_include('cache');
$data = views_cache_get('views_content_panes', TRUE);
if (!empty($data->data)) {
$types = $data->data;
}
if (empty($types)) {
$types = array();
$views = views_get_all_views();
foreach ($views as $view) {
if (!empty($view->disabled)) {
continue;
}
$view->init_display();
foreach ($view->display as $id => $display) {
if (empty($display->handler->panel_pane_display)) {
continue;
}
$info = _views_content_panes_content_type($view, $display);
if ($info) {
$types[$view->name . '-' . $id] = $info;
}
}
$view->destroy();
}
views_cache_set('views_content_panes', $types, TRUE);
}
return $types;
}
/**
* Return a single content type.
*/
function views_content_views_panes_content_type_content_type($subtype, $plugin) {
list($name, $display) = explode('-', $subtype);
$view = views_get_view($name);
if (empty($view)) {
return;
}
$view->set_display($display);
$retval = _views_content_panes_content_type($view, $view->display[$display]);
$view->destroy();
return $retval;
}
function _views_content_panes_content_type($view, $display) {
// Ensure the handler is the right type, as Views will fall back to
// the default display if something is broken:
if (get_class($display->handler) != 'views_content_plugin_display_panel_pane') {
return;
}
$title = views_content_get_display_title($view, $display->id);
$description = $display->handler->get_option('pane_description');
if (!$description) {
$description = $view->description;
}
$category = $display->handler->get_option('pane_category');
if (!$category['name']) {
$category['name'] = t('View panes');
}
$icon = 'icon_views_page.png';
$contexts = array();
$arguments = $display->handler->get_argument_input();
ctools_include('views');
foreach ($arguments as $argument) {
$contexts[] = ctools_views_get_argument_context($argument);
}
$allow = $display->handler->get_option('allow');
return array(
'title' => $title,
'icon' => $icon,
'description' => filter_xss_admin($description),
'required context' => $contexts,
'category' => array($category['name'], $category['weight']),
'no title override' => empty($allow['title_override']),
);
}
/**
* Output function for the 'views' content type.
*
* Outputs a view based on the module and delta supplied in the configuration.
*/
function views_content_views_panes_content_type_render($subtype, $conf, $panel_args, $contexts) {
if (!is_array($contexts)) {
$contexts = array($contexts);
}
list($name, $display) = explode('-', $subtype);
$view = views_get_view($name);
if (empty($view)) {
return;
}
$view->set_display($display);
views_content_views_panes_add_defaults($conf, $view);
if (!$view->display_handler->access($GLOBALS['user']) || !$view->display_handler->panel_pane_display) {
return;
}
$view->display_handler->set_pane_conf($conf);
$args = array();
$arguments = $view->display_handler->get_option('arguments');
$context_keys = isset($conf['context']) ? $conf['context'] : array();
foreach ($view->display_handler->get_argument_input() as $id => $argument) {
switch ($argument['type']) {
case 'context':
$key = array_shift($context_keys);
if (isset($contexts[$key])) {
if (strpos($argument['context'], '.')) {
list($context, $converter) = explode('.', $argument['context'], 2);
$args[] = ctools_context_convert_context($contexts[$key], $converter, array('sanitize' => FALSE));
}
else {
$args[] = $contexts[$key]->argument;
}
}
break;
case 'fixed':
$args[] = $argument['fixed'];
break;
case 'panel':
$args[] = isset($panel_args[$argument['panel']]) ? $panel_args[$argument['panel']] : NULL;
break;
case 'user':
$args[] = (isset($conf['arguments'][$id]) && $conf['arguments'][$id] !== '') ? ctools_context_keyword_substitute($conf['arguments'][$id], array(), $contexts) : NULL;
break;
case 'wildcard':
// Put in the wildcard.
$args[] = isset($arguments[$id]['wildcard']) ? $arguments[$id]['wildcard'] : '*';
break;
case 'none':
default:
// Put in NULL.
// views.module knows what to do with NULL (or missing) arguments
$args[] = NULL;
break;
}
}
// remove any trailing NULL arguments as these are non-args:
while (count($args) && end($args) === NULL) {
array_pop($args);
}
$view->set_arguments($args);
$allow = $view->display_handler->get_option('allow');
if (!empty($conf['path'])) {
$conf['path'] = ctools_context_keyword_substitute($conf['path'], array(), $contexts);
}
if ($allow['path_override'] && !empty($conf['path'])) {
$view->override_path = $conf['path'];
}
else if ($path = $view->display_handler->get_option('inherit_panels_path')) {
$view->override_path = $_GET['q'];
}
$block = new stdClass();
$block->module = 'views';
$block->delta = $view->name . '-' . $display;
if (($allow['link_to_view'] && !empty($conf['link_to_view'])) ||
(!$allow['link_to_view'] && $view->display_handler->get_option('link_to_view'))) {
$block->title_link = $view->get_url();
}
// more link
if ($allow['more_link']) {
if (empty($conf['more_link'])) {
$view->display_handler->set_option('use_more', FALSE);
}
else {
$view->display_handler->set_option('use_more', TRUE);
// make sure the view runs the count query so we know whether or not the
// more link applies.
$view->get_total_rows = TRUE;
}
}
if ($allow['items_per_page'] && isset($conf['items_per_page'])) {
$view->set_items_per_page($conf['items_per_page']);
}
if ($allow['offset']) {
$view->set_offset($conf['offset']);
}
if ($allow['use_pager']) {
// Only set use_pager if they differ, this way we can avoid overwriting the
// pager type that Views uses.
$pager = $view->display_handler->get_option('pager');
if ($conf['use_pager'] && ($pager['type'] == 'none' || $pager['type'] == 'some')) {
$pager['type'] = 'full';
}
elseif (!$conf['use_pager'] && $pager['type'] != 'none' && $pager['type'] != 'some') {
$pager['type'] = $view->get_items_per_page() || !empty($pager['options']['items_per_page']) ? 'some' : 'none';
}
if ($conf['use_pager']) {
if (!isset($pager['options']['id']) || (isset($conf['pager_id']) && $pager['options']['id'] != $conf['pager_id'])) {
$pager['options']['id'] = $conf['pager_id'];
}
}
$view->display_handler->set_option('pager', $pager);
}
if ($allow['fields_override']) {
if ($conf['fields_override']) {
$fields = $view->get_items('field');
foreach ($fields as $field => $display) {
$fields[$field]['exclude'] = empty($conf['fields_override'][$field]);
}
$view->display_handler->set_option('fields', $fields);
}
}
if ($allow['exposed_form'] && !empty($conf['exposed'])) {
$view->set_exposed_input($conf['exposed']);
}
$stored_feeds = drupal_add_feed();
$block->content = $view->preview();
if (empty($view->result) && !$view->display_handler->get_option('empty') && empty($view->style_plugin->definition['even empty'])) {
return;
}
$block->title = $view->get_title();
if (empty($view->total_rows) || $view->total_rows <= $view->get_items_per_page()) {
unset($block->more);
}
if ((!empty($allow['feed_icons']) && !empty($conf['feed_icons'])) ||
(empty($allow['feed_icons']) && $view->display_handler->get_option('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];
}
}
}
return $block;
}
/**
* Add defaults to view pane settings.
* This helps cover us if $allow settings changed and there are no actual
* settings for a particular item.
*/
function views_content_views_panes_add_defaults(&$conf, $view) {
$pager = $view->display_handler->get_option('pager');
$conf += array(
'link_to_view' => $view->display_handler->get_option('link_to_view'),
'more_link' => $view->display_handler->get_option('more_link'),
'feed_icons' => FALSE,
'use_pager' => $pager['type'] != 'none' && $pager['type'] != 'some',
'pager_id' => isset($pager['options']['id']) ? $pager['options']['id'] : 0,
'items_per_page' => !empty($pager['options']['items_per_page']) ? $pager['options']['items_per_page'] : 10,
'offset' => !empty($pager['options']['offset']) ? $pager['options']['offset'] : 0,
'path_override' => FALSE,
'path' => $view->get_path(),
'fields_override' => $view->display_handler->get_option('fields_override'),
);
}
/**
* Returns an edit form for a block.
*/
function views_content_views_panes_content_type_edit_form($form, &$form_state) {
$conf = $form_state['conf'];
$contexts = $form_state['contexts'];
// This allows older content to continue to work, where we used to embed
// the display directly.
list($name, $display_id) = explode('-', $form_state['subtype_name']);
$view = views_get_view($name);
if (empty($view)) {
$form['markup'] = array('#markup' => t('Broken/missing/deleted view.'));
return $form;
}
$view->set_display($display_id);
// If it couldn't set the display and we got the default display instead,
// fail.
if ($view->current_display == 'default') {
$form['markup'] = array('#markup' => t('Broken/missing/deleted view display.'));
return $form;
}
$allow = $view->display_handler->get_option('allow');
// Provide defaults for everything in order to prevent warnings.
views_content_views_panes_add_defaults($conf, $view);
$form['arguments']['#tree'] = TRUE;
foreach ($view->display_handler->get_argument_input() as $id => $argument) {
if ($argument['type'] == 'user') {
$form['arguments'][$id] = array(
'#type' => 'textfield',
'#default_value' => isset($conf['arguments'][$id]) ? $conf['arguments'][$id] : '',
'#description' => t('You may use keywords for substitutions.'),
'#title' => check_plain($argument['label']),
);
}
}
if ($allow['link_to_view'] ) {
$form['link_to_view'] = array(
'#type' => 'checkbox',
'#default_value' => isset($conf['link_to_view']) ? $conf['link_to_view'] : $view->display_handler->get_option('link_to_view'),
'#title' => t('Link title to page'),
);
}
if ($allow['more_link']) {
$form['more_link'] = array(
'#type' => 'checkbox',
'#default_value' => isset($conf['more_link']) ? $conf['more_link'] : $view->display_handler->get_option('use_more'),
'#description' => t('The text of this link will be "@more". This setting can only be modified on the View configuration.', array('@more' => $view->display_handler->use_more_text())),
'#title' => t('Provide a "more" link.'),
);
}
if (!empty($allow['feed_icons'])) {
$form['feed_icons'] = array(
'#type' => 'checkbox',
'#default_value' => !empty($conf['feed_icons']),
'#title' => t('Display feed icons'),
);
}
$view->init_style();
if ($allow['fields_override'] && $view->style_plugin->uses_fields()) {
$form['fields_override'] = array(
'#type' => 'fieldset',
'#title' => 'Fields to display',
'#collapsible' => TRUE,
'#tree' => TRUE,
);
foreach ($view->display_handler->get_handlers('field') as $field => $handler) {
$title = $handler->ui_name();
if ($handler->options['label']) {
$title .= ' (' . check_plain($handler->options['label']) . ')';
}
$form['fields_override'][$field] = array(
'#type' => 'checkbox',
'#title' => $title,
'#default_value' => isset($conf['fields_override'][$field]) ? $conf['fields_override'][$field] : TRUE,
);
}
}
ctools_include('dependent');
if ($allow['use_pager']) {
$form['use_pager'] = array(
'#type' => 'checkbox',
'#title' => t('Use pager'),
'#default_value' => $conf['use_pager'],
'#id' => 'use-pager-checkbox',
'#prefix' => '<div class="container-inline">',
);
$form['pager_id'] = array(
'#type' => 'textfield',
'#default_value' => $conf['pager_id'],
'#title' => t('Pager ID'),
'#size' => 4,
'#id' => 'use-pager-textfield',
'#dependency' => array('use-pager-checkbox' => array(1)),
'#suffix' => '</div>',
);
}
if ($allow['items_per_page']) {
$form['items_per_page'] = array(
'#type' => 'textfield',
'#default_value' => $conf['items_per_page'],
'#title' => t('Num items'),
'#size' => 4,
'#description' => t('Select the number of items to display, or 0 to display all results.'),
);
}
if ($allow['offset']) {
$form['offset'] = array(
'#type' => 'textfield',
'#default_value' => $conf['offset'],
'#title' => t('Offset'),
'#size' => 4,
'#description' => t('Enter the number of items to skip; enter 0 to skip no items.'),
);
}
if ($allow['path_override']) {
$form['path'] = array(
'#type' => 'textfield',
'#default_value' => isset($conf['path']) ? $conf['path'] : $view->get_path(),
'#title' => t('Override path'),
'#size' => 30,
'#description' => t('If this is set, override the View URL path; this can sometimes be useful to set to the panel URL.'),
);
if (!empty($contexts)) {
$form['path']['#description'] .= ' ' . t('You may use substitutions in this path.');
$form['contexts'] = array(
'#type' => 'fieldset',
'#title' => t('Substitutions'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$rows = array();
foreach ($contexts as $context) {
foreach (ctools_context_get_converters('%' . check_plain($context->keyword) . ':', $context) as $keyword => $title) {
$rows[] = array(
check_plain($keyword),
t('@identifier: @title', array('@title' => $title, '@identifier' => $context->identifier)),
);
}
}
$header = array(t('Keyword'), t('Value'));
$form['contexts']['context'] = array('#markup' => theme('table', array('header' => $header, 'rows' => $rows)));
}
}
if (empty($conf['exposed'])) {
$conf['exposed'] = array();
}
if ($allow['exposed_form']) {
// If the exposed form is part of pane configuration, get the exposed
// form re-tool it for our use.
$exposed_form_state = array(
'view' => &$view,
'display' => &$view->display[$display_id],
);
$view->set_exposed_input($conf['exposed']);
if (version_compare(views_api_version(), '3', '>=')) {
$exposed_form_state['exposed_form_plugin'] = $view->display_handler->get_plugin('exposed_form');
}
$view->init_handlers();
$exposed_form = array();
$exposed_form = views_exposed_form($exposed_form, $exposed_form_state);
$form['exposed'] = array(
'#tree' => TRUE,
);
foreach ($exposed_form['#info'] as $id => $info) {
$form['exposed'][$id] = array(
'#type' => 'item',
'#id' => 'views-exposed-pane',
);
if (!empty($info['label'])) {
$form['exposed'][$id]['#title'] = $info['label'];
}
if (!empty($info['operator']) && !empty($exposed_form[$info['operator']])) {
$form['exposed'][$id][$info['operator']] = $exposed_form[$info['operator']];
$form['exposed'][$id][$info['operator']]['#parents'] = array('exposed', $info['operator']);
$form['exposed'][$id][$info['operator']]['#default_value'] = isset($conf['exposed'][$info['operator']]) ? $conf['exposed'][$info['operator']] : '';
}
$form['exposed'][$id][$info['value']] = $exposed_form[$info['value']];
$form['exposed'][$id][$info['value']]['#parents'] = array('exposed', $info['value']);
$form['exposed'][$id][$info['value']]['#default_value'] = isset($conf['exposed'][$info['value']]) ? $conf['exposed'][$info['value']] : '';
}
}
// The exposed sort stuff doesn't fall into $exposed_form['#info'] so we
// have to handle it separately.
if (isset($exposed_form['sort_by'])) {
$form['exposed']['sort_by'] = $exposed_form['sort_by'];
}
if (isset($exposed_form['sort_order'])) {
$form['exposed']['sort_order'] = $exposed_form['sort_order'];
}
// Add the view object to the form to allow additional customization
$form_state['view'] = $view;
return $form;
}
/**
* Store form values in $conf.
*/
function views_content_views_panes_content_type_edit_form_submit(&$form, &$form_state) {
// Copy everything from our defaults.
$keys = array('link_to_view', 'more_link', 'feed_icons', 'use_pager',
'pager_id', 'items_per_page', 'offset', 'path_override', 'path', 'arguments', 'fields_override', 'exposed');
foreach ($keys as $key) {
if (isset($form_state['values'][$key])) {
$form_state['conf'][$key] = $form_state['values'][$key];
}
}
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_panes_content_type_admin_title($subtype, $conf, $contexts) {
list($name, $display) = explode('-', $subtype);
$view = views_get_view($name);
if (empty($view) || empty($view->display[$display])) {
return t('Deleted/missing view @view', array('@view' => $name));
}
$view->set_display($display);
views_content_views_panes_add_defaults($conf, $view);
$title = views_content_get_display_title($view, $display);
return check_plain($title);
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_panes_content_type_admin_info($subtype, $conf, $contexts) {
$info = array();
list($view_name, $display_name) = explode('-', $subtype);
$view = views_get_view($view_name);
if (empty($view) || empty($view->display[$display_name])) {
return;
}
$view->set_display($display_name);
views_content_views_panes_add_defaults($conf, $view);
// Add arguments first
if (!empty($conf['arguments'])) {
$keys = array_keys($conf['arguments']);
$values = array_values($conf['arguments']);
$argument_input = $view->display_handler->get_option('argument_input');
foreach ($conf['arguments'] as $key => $value) {
if(!empty($value)){
$label = $argument_input[$key]['label'];
$info[] = $label . ': ' . $value;
}
}
}
$block = new stdClass;
if ($info) {
$block->title = array_shift($info);
$info[] = $view->display_handler->get_option('pane_description');
$block->content = theme('item_list', array('items' => $info));
}
else {
$block->title = $view->display_handler->get_option('pane_description');
$block->content = '';
}
return $block;
}

View File

@@ -0,0 +1,237 @@
<?php
/**
* @file
* Allow a view context to display individual rows.
*/
$plugin = array(
'title' => t('View row'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display all or a specific amount of rows from a loaded view context.'),
'required context' => new ctools_context_required(t('View'), 'view'),
'defaults' => array(
'rows' => array(),
'use_fields' => array(),
'fields' => array(),
),
'add form' => array(
'views_content_views_row_content_type_edit_form' => t('Select context'),
'views_content_views_row_edit' => t('Configure rows'),
),
'edit form' => array(
'views_content_views_row_content_type_edit_form' => t('Select context'),
'views_content_views_row_edit' => t('Configure rows'),
),
);
/**
* Render the node_terms content type.
*/
function views_content_views_row_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_row';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
// This guarantees the view is rendered normally which must happen.
$view = views_content_context_get_view($context);
$output = views_content_context_get_output($context);
$sets = array();
$plugin = $view->style_plugin;
// If all rows have to be displayed then simply get the key of all rows.
$row_indexes = array();
if (empty($conf['rows'])) {
if (is_array($output['rows'])) {
$row_indexes = array_keys($output['rows']);
}
}
else {
// If a subset of rows is requested collect the list of row keys.
foreach ($conf['rows'] as $index) {
$row_indexes[] = $index - 1;
}
}
if (empty($conf['use_fields']) || empty($plugin->row_plugin)) {
foreach ($row_indexes as $row_index) {
if (isset($output['rows'][$row_index])) {
$sets[$plugin->groups[$row_index]][$row_index] = $output['rows'][$row_index];
}
}
}
else {
// If we're using specific fields, go through and poke the 'exclude' flag.
foreach ($view->field as $id => $field) {
$view->field[$id]->options['exclude'] = empty($conf['fields'][$id]);
}
// Rerender just the rows we need.
foreach ($row_indexes as $row_index) {
$view->row_index = $row_index;
if (!empty($view->result[$view->row_index])) {
$sets[$plugin->groups[$view->row_index]][$view->row_index] = $plugin->row_plugin->render($view->result[$view->row_index]);
}
unset($view->row_index);
}
}
foreach ($sets as $title => $rows) {
$block->content .= theme($plugin->theme_functions(),
array(
'view' => $view,
'options' => $plugin->options,
'rows' => $rows,
'title' => $title
)
);
}
return $block;
}
function views_content_views_row_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_row_content_type_edit_form_submit($form, &$form_state) {
}
function views_content_views_row_edit($form, &$form_state) {
$conf = $form_state['conf'];
$contexts = $form_state['contexts'];
if (empty($contexts[$conf['context']])) {
$form['markup'] = array('#markup' => '<p>' . t('Invalid context selected.') . '</p>');
return $form;
}
if (!isset($contexts[$conf['context']]->argument)) {
$name = $contexts[$conf['context']]->placeholder['conf']['name'];
list($plugin, $view_data) = explode(':', $name);
list($view_name, $display_id) = explode('-', $view_data);
}
else {
$view_data = $contexts[$conf['context']]->argument;
list($view_name, $display_id) = explode(':', $view_data);
}
$contexts[$conf['context']]->data['name'] = $view_name;
$contexts[$conf['context']]->data['display'] = $display_id;
$view = views_content_context_get_view($contexts[$conf['context']]);
if (empty($view)) {
$form['markup'] = array('#markup' => '<p>' . t('Context contains an invalid view.') . '</p>');
return $form;
}
ctools_include('dependent');
$form['limit_rows'] = array(
'#type' => 'checkbox',
'#title' => t('Limit rows'),
'#default_value' => (int) !empty($conf['rows']),
);
$view->init_pager();
$rows = $view->get_items_per_page();
if (!empty($rows)) {
foreach (range(1, $rows) as $row) {
$options[$row] = t('Row @number', array('@number' => $row));
}
$form['rows'] = array(
'#type' => 'checkboxes',
'#title' => t('Select rows'),
'#options' => $options,
'#default_value' => $conf['rows'],
'#dependency' => array('edit-limit-rows' => array(TRUE)),
);
}
else {
$form['rows'] = array('#markup' => '<p>' . t('The view must have a maximum number of items set to use this setting.') . '</p>');
return $form;
}
if ($view->display_handler->uses_fields()) {
$form['use_fields'] = array(
'#type' => 'checkbox',
'#title' => t('Display specific fields'),
'#default_value' => $conf['use_fields'],
);
$form['fields'] = array(
'#type' => 'checkboxes',
'#options' => $view->display_handler->get_field_labels(),
'#default_value' => $conf['fields'],
'#prefix' => '<div id="edit-fields-wrapper"><div id="edit-fields">',
'#suffix' => '</div></div>',
'#dependency' => array('edit-use-fields' => array(TRUE)),
);
}
return $form;
}
function views_content_views_row_edit_validate(&$form, &$form_state) {
}
function views_content_views_row_edit_submit(&$form, &$form_state) {
$form_state['conf']['rows'] = array_filter($form_state['values']['rows']);
$form_state['conf']['use_fields'] = $form_state['values']['use_fields'];
$form_state['conf']['fields'] = array_filter($form_state['values']['fields']);
}
function views_content_views_row_content_type_admin_info($subtype, $conf, $contexts) {
// Go through this route to make sure we catch changes in configuration
// that can happen.
$plugin = ctools_get_content_type('views_row');
$context = ctools_content_select_context($plugin, $subtype, $conf, $contexts);
$block = new stdClass();
$block->title = t('Row information');
if (!empty($conf['use_fields'])) {
$display_fields = array();
$view = views_content_context_get_view($context);
if (empty($view)) {
$block->title = t('Broken view');
return $block;
}
$fields = $view->display_handler->get_field_labels();
foreach ($conf['fields'] as $field) {
if (!empty($fields[$field])) {
$display_fields[$field] = '"<em>' . check_plain($fields[$field]) . '</em>"';
}
}
if ($display_fields) {
$block->content = t('Displaying: !fields', array('!fields' => implode(', ', $display_fields)));
}
else {
$block->content = t('Displaying no fields due to misconfiguration.');
}
}
else {
$block->content = t('Displaying the configured row.');
}
return $block;
}
function views_content_views_row_content_type_admin_title($subtype, $conf, $context) {
$rows = array_filter($conf['rows']);
$rows = empty($rows) ? t('Show all') : implode(', ', $rows);
return format_plural(count($rows),
'"@context" row @rows',
'"@context" rows @rows',
array('@context' => $context->identifier, '@rows' => $rows)
);
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* @file
* Allow a view context to be displayed as whole.
*/
$plugin = array(
'title' => t('Entire view'),
'category' => t('View context'),
'icon' => 'icon_views_page.png',
'description' => t('Display the entire view.'),
'required context' => new ctools_context_required(t('View'), 'view'),
);
/**
* Render the views view content type.
*/
function views_content_views_view_content_type_render($subtype, $conf, $panel_args, $context) {
if (empty($context) || empty($context->data)) {
return;
}
// Build the content type block.
$block = new stdClass();
$block->module = 'views_view';
$block->delta = $context->argument;
$block->title = '';
$block->content = '';
$output = views_content_context_get_output($context);
$output = $output['view']->preview();
$block->content = $output;
return $block;
}
function views_content_views_view_content_type_edit_form($form, &$form_state) {
// This form does nothing; it exists to let the main form select the view context.
return $form;
}
function views_content_views_view_content_type_edit_form_submit(&$form, &$form_state) {
// Kept so we guarantee we have a submit handler.
}
/**
* Returns the administrative title for a type.
*/
function views_content_views_view_content_type_admin_title($subtype, $conf, $context) {
return t('"@context" entire view', array('@context' => $context->identifier));
}

View File

@@ -0,0 +1,174 @@
<?php
/**
* @file
*
* Plugin to provide a node context. A node context is a node wrapped in a
* context object that can be utilized by anything that accepts contexts.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
'title' => t("View"),
'description' => t('Loads a view result into a context that can then be displayed across a panel or turned into other contexts.'),
'context' => 'views_content_context_view_create',
'edit form' => 'views_content_context_view_settings_form',
'edit form validate' => 'views_content_context_view_settings_form_validate',
'edit form submit' => 'views_content_context_view_settings_form_submit',
'defaults' => array('view' => ''),
'keyword' => 'view',
'context name' => 'view',
'get child' => 'views_content_context_view_get_child',
'get children' => 'views_content_context_view_get_children',
);
function views_content_context_view_get_child($plugin, $parent, $child) {
list($name, $id) = explode('-', $child, 2);
$view = views_get_view($name);
if (!$view) {
return;
}
$view->set_display($id);
if ($view->current_display != $id) {
return;
}
$info = _views_content_get_context_from_display($view, $id, $parent, FALSE);
if ($info) {
return $info;
}
return;
}
function views_content_context_view_get_children($plugin, $parent) {
$types = array(
'view' => $plugin,
);
// We're keeping the 'view' context around for legacy reasons but
// we want to disable the UI so you can't add it that way anymore.
$types['view']['no ui'] = TRUE;
$views = views_get_applicable_views('returns context');
foreach ($views as $data) {
list($view, $id) = $data;
$info = _views_content_get_context_from_display($view, $id, $parent, FALSE);
if ($info) {
$info['no required context ui'] = TRUE;
$types[$info['name']] = $info;
}
}
return $types;
}
function views_content_context_view_create($empty, $data = NULL, $conf = FALSE, $plugin = array()) {
$context = new ctools_context('view');
$context->plugin = 'view';
if ($empty) {
return $context;
}
if ($conf) {
if (is_array($data) && !empty($data['view'])) {
// This code is left in for backward compatibility. Will not be used
// with child plugins.
list($name, $display_id) = explode(':', $data['view'], 2);
$data = views_get_view($name);
if ($data) {
$data->set_display($display_id);
}
}
else if (!empty($plugin['view name'])) {
$data = views_get_view($plugin['view name']);
$data->set_display($plugin['view display id']);
}
}
if (is_object($data) && $data->current_display != 'default') {
// We don't store the loaded view as we don't want the view object
// cached. However, in order to extract it you can use:
// @code
// $output = views_content_context_get_output($context);
// $view = $output['view'];
// @endcode
$context->data = array(
'name' => $data->name,
'display' => $data->current_display,
'args' => $data->args,
);
// At runtime, this can get populated. Once it is populated this
// object should not be cached.
$context->view = NULL;
$context->title = $data->get_title();
$context->argument = $data->name . ':' . $data->current_display;
$context->restrictions['base'] = array($data->base_table);
return $context;
}
}
function views_content_context_view_settings_form($form, &$form_state) {
$conf = $form_state['conf'];
$views = views_get_applicable_views('returns context');
foreach ($views as $data) {
list($view, $id) = $data;
$title = views_content_get_display_title($view, $id, 'admin_title');
$options[$view->name . ':' . $id] = $title;
}
if (!empty($options)) {
natcasesort($options);
$form['view'] = array(
'#type' => 'select',
'#options' => $options,
'#title' => t('View'),
);
}
else {
$form['view'] = array(
'#value' => '<p>' . t('There are currently no views with Context displays enabled. You should go to the view administration and add a Context display to use a view as a context.') . '</p>',
);
}
return $form;
}
/**
* Validate a node.
*/
function views_content_context_view_settings_form_validate($form, &$form_state) {
if (empty($form_state['values']['view'])) {
form_error($form['view'], t('You must select a view.'));
}
}
/**
* Provide a list of ways that this context can be converted to a string.
*/
function views_content_context_view_convert_list() {
$list = array(
);
return $list;
}
/**
* Convert a context into a string.
*/
function views_content_context_view_convert($context, $type) {
switch ($type) {
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* @file
* Plugin to provide an relationship handler for node from view.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
'title' => t('Node from view'),
'keyword' => 'node',
'description' => t('Extract a node context from a view context of the base type node.'),
'required context' => new ctools_context_required(t('View'), 'view', array('base' => 'node')),
'context' => 'views_content_node_from_view_context',
'edit form' => 'views_content_node_from_view_settings_form',
'edit form validate' => 'views_content_node_from_view_settings_form_validate',
'defaults' => array('row' => 1),
);
/**
* Return a new context based on an existing context.
*/
function views_content_node_from_view_context($context, $conf, $placeholder = FALSE) {
// If unset it wants a generic, unfilled context, which is just NULL.
if (empty($context->data) || $placeholder) {
return ctools_context_create_empty('node', NULL);
}
$view = views_content_context_get_view($context);
// Ensure the view executes, but we don't need its output.
views_content_context_get_output($context);
$row = intval($conf['row']) - 1;
if (isset($view->result[$row])) {
$nid = $view->result[$row]->{$view->base_field};
if ($nid) {
$node = node_load($nid);
return ctools_context_create('node', $node);
}
}
return ctools_context_create_empty('node', NULL);
}
/**
* Settings form for the relationship.
*/
function views_content_node_from_view_settings_form($form, &$form_state) {
$conf = $form_state['conf'];
$form['row'] = array(
'#title' => t('Row number'),
'#type' => 'textfield',
'#default_value' => $conf['row'],
);
return $form;
}
function views_content_node_from_view_settings_form_validate($form, &$form_state) {
if (intval($form_state['values']['row']) <= 0) {
form_error($form['row'], t('Row number must be a positive integer value.'));
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* @file
* Plugin to provide an relationship handler for term from view.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
'title' => t('Term from view'),
'keyword' => 'term',
'description' => t('Extract a term context from a view context of the base type term.'),
'required context' => new ctools_context_required(t('View'), 'view', array('base' => 'term_data')),
'context' => 'views_content_term_from_view_context',
'edit form' => 'views_content_term_from_view_settings_form',
'edit form validate' => 'views_content_term_from_view_settings_form_validate',
'defaults' => array('row' => 1),
);
/**
* Return a new context based on an existing context.
*/
function views_content_term_from_view_context($context, $conf, $placeholder = FALSE) {
// If unset it wants a generic, unfilled context, which is just NULL.
if (empty($context->data) || $placeholder) {
return ctools_context_create_empty('term', NULL);
}
$view = views_content_context_get_view($context);
// Ensure the view executes, but we don't need its output.
views_content_context_get_output($context);
$row = intval($conf['row']) - 1;
if (isset($view->result[$row])) {
$tid = $view->result[$row]->{$view->base_field};
if ($tid) {
$term = taxonomy_get_term($tid);
return ctools_context_create('term', $term);
}
}
return ctools_context_create_empty('term', NULL);
}
/**
* Settings form for the relationship.
*/
function views_content_term_from_view_settings_form($form, &$form_state) {
$conf = $form_state['conf'];
$form['row'] = array(
'#title' => t('Row number'),
'#type' => 'textfield',
'#default_value' => $conf['row'],
);
return $form;
}
function views_content_term_from_view_settings_form_validate($form, &$form_state) {
if (intval($form_state['values']['row']) <= 0) {
form_error($form['row'], t('Row number must be a positive integer value.'));
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* @file
* Plugin to provide an relationship handler for user from term.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
'title' => t('User from view'),
'keyword' => 'user',
'description' => t('Extract a user context from a view context of the base type user.'),
'required context' => new ctools_context_required(t('View'), 'view', array('base' => 'users')),
'context' => 'views_content_user_from_view_context',
'edit form' => 'views_content_user_from_view_settings_form',
'edit form validate' => 'views_content_user_from_view_settings_form_validate',
'defaults' => array('row' => 1),
);
/**
* Return a new context based on an existing context.
*/
function views_content_user_from_view_context($context, $conf, $placeholder = FALSE) {
// If unset it wants a generic, unfilled context, which is just NULL.
if (empty($context->data) || $placeholder) {
return ctools_context_create_empty('user', NULL);
}
$view = views_content_context_get_view($context);
// Ensure the view executes, but we don't need its output.
views_content_context_get_output($context);
$row = intval($conf['row']) - 1;
if (isset($view->result[$row])) {
$uid = $view->result[$row]->{$view->base_field};
if ($uid) {
$user = user_load($uid);
return ctools_context_create('user', $user);
}
}
return ctools_context_create_empty('user', NULL);
}
/**
* Settings form for the relationship.
*/
function views_content_user_from_view_settings_form($form, &$form_state) {
$conf = $form_state['conf'];
$form['row'] = array(
'#title' => t('Row number'),
'#type' => 'textfield',
'#default_value' => $conf['row'],
);
return $form;
}
function views_content_user_from_view_settings_form_validate($form, &$form_state) {
if (intval($form_state['values']['row']) <= 0) {
form_error($form['row'], t('Row number must be a positive integer value.'));
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* @file
* Plugin to provide an relationship handler for a view by argument input settings.
*/
/**
* Plugins are described by creating a $plugin array which will be used
* by the system that includes this file.
*/
$plugin = array(
'title' => t('View From Argument'),
'description' => t('Creates a view context from argument input settings.'),
'context' => 'views_content_view_from_argument_context',
'get child' => 'views_content_view_from_argument_get_child',
'get children' => 'views_content_view_from_argument_get_children',
);
function views_content_view_from_argument_get_child($plugin, $parent, $child) {
list($name, $id) = explode('-', $child, 2);
$view = views_get_view($name);
if (!$view) {
return;
}
$view->set_display($id);
if ($view->current_display != $id) {
return;
}
$info = _views_content_get_context_from_display($view, $id, $parent, TRUE);
if ($info) {
return $info;
}
return;
}
function views_content_view_from_argument_get_children($plugin, $parent) {
$types = array();
$views = views_get_applicable_views('returns context');
foreach ($views as $data) {
list($view, $id) = $data;
$info = _views_content_get_context_from_display($view, $id, $parent, TRUE);
if ($info) {
$types[$info['name']] = $info;
}
}
return $types;
}
/**
* Return a new context based on an existing context.
*/
function views_content_view_from_argument_context($contexts, $conf) {
$name = $conf['name'];
list($plugin, $view_data) = explode(':', $name);
list($view_name, $display_id) = explode('-', $view_data);
$keys = array_keys($conf['context']);
if (empty($contexts[$keys[0]]->data)) {
return ctools_context_create_empty('view', NULL);
}
// Load our view up.
$data = views_get_view($view_name);
if ($data) {
// Set the display.
$data->set_display($display_id);
$context_keys = array_keys($contexts);
foreach ($data->display_handler->get_argument_input() as $id => $argument) {
if ($argument['type'] == 'context') {
$key = array_shift($context_keys);
if (isset($contexts [$key])) {
if (strpos($argument['context'], '.')) {
list($context, $converter) = explode('.', $argument['context'], 2);
$args[] = ctools_context_convert_context($contexts[$key], $converter, array('sanitize' => FALSE));
}
else {
$args[] = $contexts[$key]->argument;
}
}
}
}
// remove any trailing NULL arguments as these are non-args:
while (count($args) && end($args) === NULL) {
array_pop($args);
}
$data->set_arguments($args);
if ($path = $data->display_handler->get_option('inherit_panels_path')) {
$data->override_path = $_GET['q'];
}
}
if (isset($contexts[$keys[0]]->data)) {
return ctools_context_create('view', $data);
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* @file
* Contains Views plugin definitions for the panel pane display.
*/
/**
* Implements hook_views_plugins
*/
function views_content_views_plugins() {
return array(
'display' => array(
'panel_pane' => array(
'title' => t('Content pane'),
'admin' => t('Content pane'),
'help' => t('Is available as content for a panel or dashboard display.'),
'handler' => 'views_content_plugin_display_panel_pane',
'path' => drupal_get_path('module', 'views_content') . '/plugins/views',
'theme path' => drupal_get_path('module', 'views') . '/theme',
'theme' => 'views_view',
'register theme' => FALSE,
'use ajax' => TRUE,
'use pager' => TRUE,
'use more' => TRUE,
'accept attachments' => TRUE,
'help topic' => 'display-pane',
),
'ctools_context' => array(
'title' => t('Context'),
'admin' => t('Context'),
'help' => t('Makes the view results available as a context for use in Panels and other applications.'),
'handler' => 'views_content_plugin_display_ctools_context',
'path' => drupal_get_path('module', 'views_content') . '/plugins/views',
'theme path' => drupal_get_path('module', 'views') . '/theme',
'theme' => 'views_view',
'register theme' => FALSE,
'use ajax' => FALSE,
'use pager' => TRUE,
'use more' => FALSE,
'accept attachments' => TRUE,
'returns context' => TRUE,
'help topic' => 'display-context',
),
),
'style' => array(
'ctools_context' => array(
'title' => t('Context'),
'help' => t('Contains rows in contexts.'),
'handler' => 'views_content_plugin_style_ctools_context',
'path' => drupal_get_path('module', 'views_content') . '/plugins/views',
'theme path' => drupal_get_path('module', 'views') . '/theme',
'theme' => 'views_view_unformatted',
'register theme' => FALSE,
'uses row plugin' => TRUE,
'uses row class' => TRUE,
'uses fields' => TRUE,
'uses options' => TRUE,
'type' => 'context',
'help topic' => 'style-context',
),
),
);
}

View File

@@ -0,0 +1,272 @@
<?php
/**
* @file
* Contains the block display plugin.
*/
/**
* The plugin that handles a block.
*
* @ingroup views_display_plugins
*/
class views_content_plugin_display_ctools_context extends views_plugin_display {
/**
* If this variable is true, this display counts as a context. We use this
* variable so that we can easily build plugins against this display type.
*/
var $context_display = TRUE;
function get_style_type() { return 'context'; }
function defaultable_sections($section = NULL) {
if (in_array($section, array('style_options', 'style_plugin', 'row_options', 'row_plugin',))) {
return FALSE;
}
return parent::defaultable_sections($section);
}
function option_definition() {
$options = parent::option_definition();
$options['admin_title'] = array('default' => '', 'translatable' => TRUE);
// Overrides for standard stuff:
$options['style_plugin']['default'] = 'ctools_context';
$options['row_plugin']['default'] = 'fields';
$options['defaults']['default']['style_plugin'] = FALSE;
$options['defaults']['default']['style_options'] = FALSE;
$options['defaults']['default']['row_plugin'] = FALSE;
$options['defaults']['default']['row_options'] = FALSE;
$options['inherit_panels_path'] = array('default' => 0);
$options['argument_input'] = array('default' => array());
return $options;
}
/**
* The display block handler returns the structure necessary for a block.
*/
function execute() {
$this->executing = TRUE;
return $this->view->render();
}
function preview() {
$this->previewing = TRUE;
return $this->view->render();
}
/**
* Render this display.
*/
function render() {
if (!empty($this->previewing)) {
return theme($this->theme_functions(), array('view' => $this->view));
}
else {
// We want to process the view like we're theming it, but not actually
// use the template part. Therefore we run through all the preprocess
// functions which will populate the variables array.
$hooks = theme_get_registry();
$info = $hooks[$this->definition['theme']];
if (!empty($info['file'])) {
@include_once('./' . $info['path'] . '/' . $info['file']);
}
$this->variables = array('view' => &$this->view);
if (isset($info['preprocess functions']) && is_array($info['preprocess functions'])) {
foreach ($info['preprocess functions'] as $preprocess_function) {
if (function_exists($preprocess_function)) {
$preprocess_function($this->variables, $this->definition['theme']);
}
}
}
}
return $this->variables;
}
/**
* Provide the summary for page options in the views UI.
*
* This output is returned as an array.
*/
function options_summary(&$categories, &$options) {
// It is very important to call the parent function here:
parent::options_summary($categories, $options);
$categories['context'] = array(
'title' => t('Context settings'),
'column' => 'second',
'build' => array(
'#weight' => -10,
),
);
$admin_title = $this->get_option('admin_title');
if (empty($admin_title)) {
$admin_title = t('Use view name');
}
if (drupal_strlen($admin_title) > 16) {
$admin_title = drupal_substr($admin_title, 0, 16) . '...';
}
$options['admin_title'] = array(
'category' => 'context',
'title' => t('Admin title'),
'value' => $admin_title,
);
$options['inherit_panels_path'] = array(
'category' => 'context',
'title' => t('Use Panel path'),
'value' => $this->get_option('inherit_panels_path') ? t('Yes') : t('No'),
);
$options['argument_input'] = array(
'category' => 'context',
'title' => t('Argument input'),
'value' => t('Edit'),
);
}
/**
* Provide the default form for setting options.
*/
function options_form(&$form, &$form_state) {
// It is very important to call the parent function here:
parent::options_form($form, $form_state);
switch ($form_state['section']) {
case 'row_plugin':
// This just overwrites the existing row_plugin which is using the wrong options.
$form['row_plugin']['#options'] = views_fetch_plugin_names('row', 'normal', array($this->view->base_table));
break;
case 'admin_title':
$form['#title'] .= t('Administrative title');
$form['admin_title'] = array(
'#type' => 'textfield',
'#default_value' => $this->get_option('admin_title'),
'#description' => t('This is the title that will appear for this view context in the configure context dialog. If left blank, the view name will be used.'),
);
break;
case 'inherit_panels_path':
$form['#title'] .= t('Inherit path from panel display');
$form['inherit_panels_path'] = array(
'#type' => 'select',
'#options' => array(1 => t('Yes'), 0 => t('No')),
'#default_value' => $this->get_option('inherit_panels_path'),
'#description' => t('If yes, all links generated by Views, such as more links, summary links, and exposed input links will go to the panels display path, not the view, if the display has a path.'),
);
break;
case 'argument_input':
$form['#title'] .= t('Choose the data source for view arguments');
$argument_input = $this->get_argument_input();
ctools_include('context');
ctools_include('dependent');
$form['argument_input']['#tree'] = TRUE;
$converters = ctools_context_get_all_converters();
ksort($converters);
foreach ($argument_input as $id => $argument) {
$form['argument_input'][$id] = array(
'#tree' => TRUE,
);
$safe = str_replace(array('][', '_', ' ', ':'), '-', $id);
$type_id = 'edit-argument-input-' . $safe;
$form['argument_input'][$id]['type'] = array(
'#type' => 'select',
'#options' => array(
'none' => t('No argument'),
'context' => t('From context'),
),
'#id' => $type_id,
'#title' => t('@arg source', array('@arg' => $argument['name'])),
'#default_value' => $argument['type'],
);
$form['argument_input'][$id]['context'] = array(
'#type' => 'select',
'#title' => t('Required context'),
'#description' => t('If "From context" is selected, which type of context to use.'),
'#default_value' => $argument['context'],
'#options' => $converters,
'#dependency' => array($type_id => array('context')),
);
$form['argument_input'][$id]['context_optional'] = array(
'#type' => 'checkbox',
'#title' => t('Context is optional'),
'#description' => t('This context need not be present for the pane to function. If you plan to use this, ensure that the argument handler can handle empty values gracefully.'),
'#default_value' => $argument['context_optional'],
'#dependency' => array($type_id => array('context')),
);
}
break;
}
}
/**
* Perform any necessary changes to the form values prior to storage.
* There is no need for this function to actually store the data.
*/
function options_submit(&$form, &$form_state) {
// It is very important to call the parent function here:
parent::options_submit($form, $form_state);
switch ($form_state['section']) {
case 'admin_title':
case 'argument_input':
case 'inherit_panels_path':
$this->set_option($form_state['section'], $form_state['values'][$form_state['section']]);
break;
}
}
/**
* Adjust the array of argument input to match the current list of
* arguments available for this display. This ensures that changing
* the arguments doesn't cause the argument input field to just
* break.
*/
function get_argument_input() {
$arguments = $this->get_option('argument_input');
$handlers = $this->get_handlers('argument');
// We use a separate output so as to seamlessly discard info for
// arguments that no longer exist.
$output = array();
foreach ($handlers as $id => $handler) {
if (empty($arguments[$id])) {
$output[$id] = array(
'type' => 'none',
'context' => 'any',
'context_optional' => FALSE,
'name' => $handler->ui_name(),
);
}
else {
$output[$id] = $arguments[$id];
$output[$id]['name'] = $handler->ui_name();
}
}
return $output;
}
function get_path() {
if ($this->get_option('link_display') == 'custom_url' && $override_path = $this->get_option('link_url')) {
return $override_path;
}
if ($this->get_option('inherit_panels_path')) {
return $_GET['q'];
}
return parent::get_path();
}
}

View File

@@ -0,0 +1,416 @@
<?php
/**
* The plugin that handles a panel_pane.
*/
class views_content_plugin_display_panel_pane extends views_plugin_display {
/**
* If this variable is true, this display counts as a panel pane. We use
* this variable so that other modules can create alternate pane displays.
*/
var $panel_pane_display = TRUE;
var $has_pane_conf = NULL;
function option_definition() {
$options = parent::option_definition();
$options['pane_title'] = array('default' => '', 'translatable' => TRUE);
$options['pane_description'] = array('default' => '', 'translatable' => TRUE);
$options['pane_category'] = array(
'contains' => array(
'name' => array('default' => 'View panes', 'translatable' => TRUE),
'weight' => array('default' => 0),
),
);
$options['allow'] = array(
'contains' => array(
'use_pager' => array('default' => FALSE),
'items_per_page' => array('default' => FALSE),
'offset' => array('default' => FALSE),
'link_to_view' => array('default' => FALSE),
'more_link' => array('default' => FALSE),
'path_override' => array('default' => FALSE),
'title_override' => array('default' => FALSE),
'exposed_form' => array('default' => FALSE),
'fields_override' => array('default' => FALSE),
),
);
$options['argument_input'] = array('default' => array());
$options['link_to_view'] = array('default' => 0);
$options['inherit_panels_path'] = array('default' => 0);
return $options;
}
function has_pane_conf() {
return isset($this->has_pane_conf);
}
function set_pane_conf($conf = array()) {
$this->set_option('pane_conf', $conf);
$this->has_pane_conf = TRUE;
}
/**
* Provide the summary for page options in the views UI.
*
* This output is returned as an array.
*/
function options_summary(&$categories, &$options) {
// It is very important to call the parent function here:
parent::options_summary($categories, $options);
$categories['panel_pane'] = array(
'title' => t('Pane settings'),
'column' => 'second',
'build' => array(
'#weight' => -10,
),
);
$pane_title = $this->get_option('pane_title');
if (empty($pane_title)) {
$pane_title = t('Use view name');
}
if (drupal_strlen($pane_title) > 16) {
$pane_title = drupal_substr($pane_title, 0, 16) . '...';
}
$options['pane_title'] = array(
'category' => 'panel_pane',
'title' => t('Admin title'),
'value' => $pane_title,
);
$pane_description = $this->get_option('pane_description');
if (empty($pane_description)) {
$pane_description = t('Use view description');
}
if (drupal_strlen($pane_description) > 16) {
$pane_description = drupal_substr($pane_description, 0, 16) . '...';
}
$options['pane_description'] = array(
'category' => 'panel_pane',
'title' => t('Admin desc'),
'value' => $pane_description,
);
$category = $this->get_option('pane_category');
$pane_category = $category['name'];
if (empty($pane_category)) {
$pane_category = t('View panes');
}
if (drupal_strlen($pane_category) > 16) {
$pane_category = drupal_substr($pane_category, 0, 16) . '...';
}
$options['pane_category'] = array(
'category' => 'panel_pane',
'title' => t('Category'),
'value' => $pane_category,
);
$options['link_to_view'] = array(
'category' => 'panel_pane',
'title' => t('Link to view'),
'value' => $this->get_option('link_to_view') ? t('Yes') : t('No'),
);
$options['inherit_panels_path'] = array(
'category' => 'panel_pane',
'title' => t('Use Panel path'),
'value' => $this->get_option('inherit_panels_path') ? t('Yes') : t('No'),
);
$options['argument_input'] = array(
'category' => 'panel_pane',
'title' => t('Argument input'),
'value' => t('Edit'),
);
$allow = $this->get_option('allow');
$filtered_allow = array_filter($allow);
$options['allow'] = array(
'category' => 'panel_pane',
'title' => t('Allow settings'),
'value' => empty($filtered_allow) ? t('None') : ($allow === $filtered_allow ? t('All') : t('Some')),
);
}
/**
* Provide the default form for setting options.
*/
function options_form(&$form, &$form_state) {
// It is very important to call the parent function here:
parent::options_form($form, $form_state);
switch ($form_state['section']) {
case 'allow':
$form['#title'] .= t('Allow settings');
$form['description'] = array(
'#value' => '<div class="form-item description">' . t('Checked settings will be available in the panel pane config dialog for modification by the panels user. Unchecked settings will not be available and will only use the settings in this display.') . '</div>',
);
$options = array(
'use_pager' => t('Use pager'),
'items_per_page' => t('Items per page'),
'offset' => t('Pager offset'),
'link_to_view' => t('Link to view'),
'more_link' => t('More link'),
'path_override' => t('Path override'),
'title_override' => t('Title override'),
'exposed_form' => t('Use exposed widgets form as pane configuration'),
'fields_override' => t('Fields override'),
);
$allow = array_filter($this->get_option('allow'));
$form['allow'] = array(
'#type' => 'checkboxes',
'#default_value' => $allow,
'#options' => $options,
);
break;
case 'pane_title':
$form['#title'] .= t('Administrative title');
$form['pane_title'] = array(
'#type' => 'textfield',
'#default_value' => $this->get_option('pane_title'),
'#description' => t('This is the title that will appear for this view pane in the add content dialog. If left blank, the view name will be used.'),
);
break;
case 'pane_description':
$form['#title'] .= t('Administrative description');
$form['pane_description'] = array(
'#type' => 'textfield',
'#default_value' => $this->get_option('pane_description'),
'#description' => t('This is text that will be displayed when the user mouses over the pane in the add content dialog. If blank the view description will be used.'),
);
break;
case 'pane_category':
$form['#title'] .= t('Administrative description');
$cat = $this->get_option('pane_category');
$form['pane_category']['#tree'] = TRUE;
$form['pane_category']['name'] = array(
'#type' => 'textfield',
'#default_value' => $cat['name'],
'#description' => t('This is category the pane will appear in on the add content dialog.'),
);
$form['pane_category']['weight'] = array(
'#title' => t('Weight'),
'#type' => 'textfield',
'#default_value' => $cat['weight'],
'#description' => t('This is the default weight of the category. Note that if the weight of a category is defined in multiple places, only the first one Panels sees will get that definition, so if the weight does not appear to be working, check other places that the weight might be set.'),
);
break;
case 'link_to_view':
$form['#title'] .= t('Link pane title to view');
$form['link_to_view'] = array(
'#type' => 'select',
'#options' => array(1 => t('Yes'), 0 => t('No')),
'#default_value' => $this->get_option('link_to_view'),
);
break;
case 'inherit_panels_path':
$form['#title'] .= t('Inherit path from panel display');
$form['inherit_panels_path'] = array(
'#type' => 'select',
'#options' => array(1 => t('Yes'), 0 => t('No')),
'#default_value' => $this->get_option('inherit_panels_path'),
'#description' => t('If yes, all links generated by Views, such as more links, summary links, and exposed input links will go to the panels display path, not the view, if the display has a path.'),
);
break;
case 'argument_input':
$form['#title'] .= t('Choose the data source for view arguments');
$argument_input = $this->get_argument_input();
ctools_include('context');
ctools_include('dependent');
$form['argument_input']['#tree'] = TRUE;
$converters = ctools_context_get_all_converters();
ksort($converters);
foreach ($argument_input as $id => $argument) {
$form['argument_input'][$id] = array(
'#tree' => TRUE,
);
$safe = str_replace(array('][', '_', ' '), '-', $id);
$type_id = 'edit-argument-input-' . $safe;
$form['argument_input'][$id]['type'] = array(
'#type' => 'select',
'#options' => array(
'none' => t('No argument'),
'wildcard' => t('Argument wildcard'),
'context' => t('From context'),
'panel' => t('From panel argument'),
'fixed' => t('Fixed'),
'user' => t('Input on pane config'),
),
'#id' => $type_id,
'#title' => t('@arg source', array('@arg' => $argument['name'])),
'#default_value' => $argument['type'],
);
$form['argument_input'][$id]['context'] = array(
'#type' => 'select',
'#title' => t('Required context'),
'#description' => t('If "From context" is selected, which type of context to use.'),
'#default_value' => $argument['context'],
'#options' => $converters,
'#dependency' => array($type_id => array('context')),
);
$form['argument_input'][$id]['context_optional'] = array(
'#type' => 'checkbox',
'#title' => t('Context is optional'),
'#description' => t('This context need not be present for the pane to function. If you plan to use this, ensure that the argument handler can handle empty values gracefully.'),
'#default_value' => $argument['context_optional'],
'#dependency' => array($type_id => array('context')),
);
$form['argument_input'][$id]['panel'] = array(
'#type' => 'select',
'#title' => t('Panel argument'),
'#description' => t('If "From panel argument" is selected, which panel argument to use.'),
'#default_value' => $argument['panel'],
'#options' => array(0 => t('First'), 1 => t('Second'), 2 => t('Third'), 3 => t('Fourth'), 4 => t('Fifth'), 5 => t('Sixth')),
'#dependency' => array($type_id => array('panel')),
);
$form['argument_input'][$id]['fixed'] = array(
'#type' => 'textfield',
'#title' => t('Fixed argument'),
'#description' => t('If "Fixed" is selected, what to use as an argument.'),
'#default_value' => $argument['fixed'],
'#dependency' => array($type_id => array('fixed')),
);
$form['argument_input'][$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($argument['label']) ? $argument['name'] : $argument['label'],
'#dependency' => array($type_id => array('user')),
);
}
break;
}
}
/**
* Perform any necessary changes to the form values prior to storage.
* There is no need for this function to actually store the data.
*/
function options_submit(&$form, &$form_state) {
// It is very important to call the parent function here:
parent::options_submit($form, $form_state);
switch ($form_state['section']) {
case 'allow':
case 'argument_input':
case 'link_to_view':
case 'inherit_panels_path':
case 'pane_title':
case 'pane_description':
case 'pane_category':
$this->set_option($form_state['section'], $form_state['values'][$form_state['section']]);
break;
}
}
/**
* Adjust the array of argument input to match the current list of
* arguments available for this display. This ensures that changing
* the arguments doesn't cause the argument input field to just
* break.
*/
function get_argument_input() {
$arguments = $this->get_option('argument_input');
$handlers = $this->get_handlers('argument');
// We use a separate output so as to seamlessly discard info for
// arguments that no longer exist.
$output = array();
foreach ($handlers as $id => $handler) {
if (empty($arguments[$id])) {
$output[$id] = array(
'type' => 'none',
'context' => 'any',
'context_optional' => FALSE,
'panel' => 0,
'fixed' => '',
'name' => $handler->ui_name(),
);
}
else {
$output[$id] = $arguments[$id];
$output[$id]['name'] = $handler->ui_name();
}
}
return $output;
}
function use_more() {
$allow = $this->get_option('allow');
if (!$allow['more_link'] || !$this->has_pane_conf()) {
return parent::use_more();
}
$conf = $this->get_option('pane_conf');
return (bool) $conf['more_link'];
}
function get_path() {
if (empty($this->view->override_path)) {
return parent::get_path();
}
return $this->view->override_path;
}
function get_url() {
if ($this->get_option('inherit_panels_path')) {
return $this->get_path();
}
return parent::get_url();
}
function uses_exposed_form_in_block() {
// We'll always allow the exposed form in a block, regardless of path.
return TRUE;
}
/**
* Determine if this display should display the exposed
* filters widgets, so the view will know whether or not
* to render them.
*
* Regardless of what this function
* returns, exposed filters will not be used nor
* displayed unless uses_exposed() returns TRUE.
*/
function displays_exposed() {
$conf = $this->get_option('allow');
// If this is set, the exposed form is part of pane configuration, not
// rendered normally.
return empty($conf['exposed_form']);
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* @file
* Contains the default style plugin.
*/
/**
* Default style plugin to render rows one after another with no
* decorations.
*
* @ingroup views_style_plugins
*/
class views_content_plugin_style_ctools_context extends views_plugin_style {
var $rows = array();
/**
* Render the display in this style.
*/
function render() {
if (!empty($this->view->display_handler->previewing)) {
return parent::render();
}
$this->rows = array();
$this->groups = array();
if ($this->uses_row_plugin() && empty($this->row_plugin)) {
vpr('views_plugin_style_default: Missing row plugin');
return;
}
// Some engines like solr key results on ids, but rendering really expects
// things to be keyed exclusively by row index. Using array_values()
// guarantees that.
$this->view->result = array_values($this->view->result);
// Group the rows according to the grouping field, if specified.
$sets = $this->render_grouping($this->view->result, $this->options['grouping']);
// Render each group separately and concatenate. Plugins may override this
// method if they wish some other way of handling grouping.
$output = '';
foreach ($sets as $title => $records) {
foreach ($records as $row_index => $row) {
$this->view->row_index = $row_index;
$this->rows[$row_index] = $this->row_plugin->render($row);
$this->groups[$row_index] = $title;
}
}
unset($this->view->row_index);
return $this->rows;
}
}

View File

@@ -0,0 +1,17 @@
name = Views content panes
description = Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API.
package = Views
dependencies[] = ctools
dependencies[] = views
core = 7.x
package = Chaos tool suite
files[] = plugins/views/views_content_plugin_display_ctools_context.inc
files[] = plugins/views/views_content_plugin_display_panel_pane.inc
files[] = plugins/views/views_content_plugin_style_ctools_context.inc
; Information added by drupal.org packaging script on 2013-04-03
version = "7.x-1.3"
core = "7.x"
project = "ctools"
datestamp = "1365013512"

View File

@@ -0,0 +1,283 @@
<?php
/**
* @file views_content.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.
*/
/**
* Implements hook_menu().
*/
function views_content_menu() {
$items = array();
if (!module_exists('panels')) {
$items['admin/config/content-views'] = array(
'title' => 'Views panes',
'access arguments' => array('administer views content plugin'),
'page callback' => 'drupal_get_form',
'page arguments' => array('views_content_admin_page'),
'description' => 'Configure Views to be used as CTools content.',
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
/**
* Implementation of hook_ctools_plugin_dierctory() to let the system know
* where our content_type plugins are.
*/
function views_content_ctools_plugin_directory($owner, $plugin_type) {
if ($owner == 'ctools') {
return 'plugins/' . $plugin_type;
}
}
/**
* Don't show Views' blocks; we expose them already.
*/
function views_ctools_block_info($module, $delta, &$info) {
if (strlen($delta) == 32) {
$hashes = variable_get('views_block_hashes', array());
if (!empty($hashes[$delta])) {
$delta = $hashes[$delta];
}
}
if (substr($delta, 0, 1) != '-') {
$info = NULL;
}
else {
$info['category'] = t('Views');
$info['icon'] = 'icon_views_block_legacy.png';
$info['path'] = drupal_get_path('module', 'views_content');
$info['edit form'] = 'views_content_exposed_form_pane_edit';
$info['add form'] = 'views_content_exposed_form_pane_edit';
$info['render callback'] = 'views_content_exposed_form_pane_render';
}
}
/**
* Add settings to the "exposed form in block" views.
*/
function views_content_exposed_form_pane_edit($form, &$form_state) {
// This is a cheesy way to add defaults only to new versions of the block
// but leave older blocks without the setting alone. We can tell because
// all older content will have something set for override_title which is
// the only pre-existing setting.
if (!isset($form_state['conf']['inherit_path']) && !isset($form_state['conf']['override_title'])) {
$form_state['conf']['inherit_path'] = TRUE;
}
$form['inherit_path'] = array(
'#type' => 'checkbox',
'#title' => t('Inherit path'),
'#default_value' => !empty($form_state['conf']['inherit_path']),
);
return $form;
}
/**
* Store data for the exposed form in block settings page.
*/
function views_content_exposed_form_pane_edit_submit($form, &$form_state) {
$form_state['conf']['inherit_path'] = $form_state['values']['inherit_path'];
}
/**
* Render function for 'special' view blocks.
*
* We took over the render for the special view blocks so that we could
* add options to it.
*/
function views_content_exposed_form_pane_render($subtype, $conf, $panel_args, $contexts) {
$delta = str_replace('views-', '', $subtype);
if (strlen($delta) == 32) {
$hashes = variable_get('views_block_hashes', array());
if (!empty($hashes[$delta])) {
$delta = $hashes[$delta];
}
}
list($nothing, $type, $name, $display_id) = explode('-', $delta);
// Put the - back on. For views special blocks, the first character is always - but
// the explode killed it. Note that this code is mostly copied from views_block().
$type = '-' . $type;
if ($view = views_get_view($name)) {
if ($view->access($display_id)) {
if (!empty($conf['inherit_path'])) {
$view->override_path = $_GET['q'];
}
$view->set_display($display_id);
if (isset($view->display_handler)) {
$block = (object) $view->display_handler->view_special_blocks($type);
return $block;
}
}
$view->destroy();
}
}
/**
* Implements hook_views_api().
*
* This one is used as the base to reduce errors when updating.
*/
function views_content_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'views_content') . '/plugins/views',
);
}
/**
* Page callback to provide the basic administration form.
*/
function views_content_admin_page() {
$form = array();
views_content_admin_form($form);
return system_settings_form($form);
}
function views_content_admin_form(&$form) {
$form['ctools_content_all_views'] = array(
'#type' => 'checkbox',
'#title' => t('Make all views available as panes'),
'#description' => t("If checked, all views will be made available as content panes to be added to content types. If not checked, only Views that have a 'Content pane' display will be available as content panes. Uncheck this if you want to be able to more carefully control what view content is available to users using the panels layout UI."),
'#default_value' => variable_get('ctools_content_all_views', TRUE),
);
}
/**
* API function to get the view.
*/
function views_content_context_get_view(&$context) {
if (empty($context->view) || get_class($context->view) == '__PHP_Incomplete_Class') {
$context->view = views_get_view($context->data['name']);
if ($context->view) {
$context->view->set_display($context->data['display']);
$context->view->set_arguments($context->data['args']);
}
}
return $context->view;
}
/**
* API function to get the view.
*/
function views_content_context_get_output(&$context) {
if (empty($context->output)) {
$view = views_content_context_get_view($context);
$context->output = $view->execute_display($context->data['display']);
}
return $context->output;
}
/**
* Get the title to display for a views content display for pane or context.
*/
function views_content_get_display_title($view, $display_id, $option = 'pane_title') {
$handler = $view->display[$display_id]->handler;
$title = $handler->get_option($option);
if (!$title) {
if ($handler->display->display_title == $handler->definition['title']) {
$title = t('View: @view', array('@view' => $view->get_human_name()));
}
else {
$title = t('View: @view: @display', array('@view' => $view->get_human_name(), '@display' => $handler->display->display_title));
}
}
return $title;
}
/**
* Get the proper label for a display.
*
* Views renamed the default to Master, but it can still have a conflicting
* display title. Fix that.
*/
function views_content_get_display_label($view, $display_id) {
$title = $display_id == 'default' ? t('Master') : $view->display[$display_id]->display_title;
return $title;
}
/**
* Get the child plugin for a view context display.
*
* This can return both the context and relationship style. The
* $required parameter is used to distinguish if context is required
* or not, so we know whether we need it suitable as a pure context
* (i.e, no context required) or a relationship (i.e, context required).
*/
function _views_content_get_context_from_display($view, $id, $parent, $required = TRUE) {
$title = views_content_get_display_title($view, $id, 'admin_title');
$description = $view->description;
$contexts = array();
$arguments = $view->display_handler->get_argument_input();
ctools_include('views');
foreach ($arguments as $argument) {
$argument['label'] = $argument['name'] ? $argument['name'] : '';
$contexts[] = ctools_views_get_argument_context($argument);
}
$pass = FALSE;
if ($required) {
// If context is required, make sure we have at least one optional
// or required context.
foreach ($contexts as $context) {
if (is_object($context)) {
$pass = TRUE;
break;
}
}
if (!$pass) {
return;
}
}
else {
// If context is not required, then having any required context
// causes a fail.
foreach ($contexts as $context) {
if (is_object($context) && get_class($context) == 'ctools_context_required') {
return;
}
}
// Since we know we don't want contexts, we an unset this now.
$contexts = array();
}
if ($required) {
$function = 'views_content_view_from_argument_context';
}
else {
$function = 'views_content_context_view_create';
}
return array(
'title' => $title,
'description' => filter_xss_admin($description),
'required context' => $contexts,
'keyword' => 'view',
'context' => $function,
'context name' => $view->name,
'name' => $parent . ':' . $view->name . '-' . $id,
'view name' => $view->name,
'view display id' => $id,
);
}