Issue #1821654 by damiankloip, dawehner: Refactor Page based display plugin classes.
parent
881edb14c9
commit
6b8d66b5b1
|
|
@ -90,7 +90,6 @@ class Block extends DisplayPluginBase {
|
|||
* This output is returned as an array.
|
||||
*/
|
||||
public function optionsSummary(&$categories, &$options) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::optionsSummary($categories, $options);
|
||||
|
||||
$categories['block'] = array(
|
||||
|
|
@ -151,7 +150,6 @@ class Block extends DisplayPluginBase {
|
|||
* Provide the default form for setting options.
|
||||
*/
|
||||
public function buildOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
|
||||
switch ($form_state['section']) {
|
||||
|
|
@ -189,7 +187,6 @@ class Block extends DisplayPluginBase {
|
|||
* There is no need for this function to actually store the data.
|
||||
*/
|
||||
public function submitOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::submitOptionsForm($form, $form_state);
|
||||
switch ($form_state['section']) {
|
||||
case 'display_id':
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\views\Plugin\views\display\DisplayPluginBase.
|
||||
* Contains Drupal\views\Plugin\views\display\DisplayPluginBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Plugin\views\PluginBase;
|
||||
use \Drupal\views\Plugin\views\PluginBase;
|
||||
|
||||
/**
|
||||
* @defgroup views_display_plugins Views display plugins
|
||||
|
|
@ -333,9 +333,12 @@ abstract class DisplayPluginBase extends PluginBase {
|
|||
* @return bool
|
||||
*/
|
||||
public function acceptAttachments() {
|
||||
if (!$this->usesAttachments()) {
|
||||
// To be able to accept attachments this display have to be able to use
|
||||
// attachments but at the same time, you cannot attach a display to itself.
|
||||
if (!$this->usesAttachments() || ($this->definition['id'] == $this->view->current_display)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!empty($this->view->argument) && $this->getOption('hide_attachment_summary')) {
|
||||
foreach ($this->view->argument as $argument_id => $argument) {
|
||||
if ($argument->needsStylePlugin() && empty($argument->argument_validated)) {
|
||||
|
|
@ -343,6 +346,7 @@ abstract class DisplayPluginBase extends PluginBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -745,7 +749,7 @@ abstract class DisplayPluginBase extends PluginBase {
|
|||
* @param string $type
|
||||
* The type of the plugin.
|
||||
*
|
||||
* @return Drupal\views\Plugin\views\PluginBase
|
||||
* @return \Drupal\views\Plugin\views\PluginBase
|
||||
*/
|
||||
public function getPlugin($type) {
|
||||
// Look up the plugin name to use for this instance.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\views\Plugin\views\display\Feed.
|
||||
* Contains Drupal\views\Plugin\views\display\Feed.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
|
@ -16,8 +16,6 @@ use Drupal\Core\Annotation\Translation;
|
|||
/**
|
||||
* The plugin that handles a feed, such as RSS or atom.
|
||||
*
|
||||
* For the most part, feeds are page displays but with some subtle differences.
|
||||
*
|
||||
* @ingroup views_display_plugins
|
||||
*
|
||||
* @Plugin(
|
||||
|
|
@ -28,7 +26,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* admin = @Translation("Feed")
|
||||
* )
|
||||
*/
|
||||
class Feed extends Page {
|
||||
class Feed extends PathPluginBase {
|
||||
|
||||
/**
|
||||
* Whether the display allows the use of AJAX or not.
|
||||
|
|
@ -57,47 +55,60 @@ class Feed extends Page {
|
|||
}
|
||||
}
|
||||
|
||||
public function usesBreadcrumb() { return FALSE; }
|
||||
protected function getStyleType() { return 'feed'; }
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::getStyleType().
|
||||
*/
|
||||
protected function getStyleType() {
|
||||
return 'feed';
|
||||
}
|
||||
|
||||
/**
|
||||
* Feeds do not go through the normal page theming mechanism. Instead, they
|
||||
* go through their own little theme function and then return NULL so that
|
||||
* Drupal believes that the page has already rendered itself...which it has.
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::execute().
|
||||
*/
|
||||
public function execute() {
|
||||
parent::execute();
|
||||
|
||||
$output = $this->view->render();
|
||||
|
||||
if (empty($output)) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
$response = $this->view->getResponse();
|
||||
|
||||
$response->setContent($output);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::preview().
|
||||
*/
|
||||
public function preview() {
|
||||
if (!empty($this->view->live_preview)) {
|
||||
return '<pre>' . check_plain($this->view->render()) . '</pre>';
|
||||
}
|
||||
|
||||
return $this->view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of going through the standard views_view.tpl.php, delegate this
|
||||
* to the style handler.
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::render().
|
||||
*/
|
||||
public function render() {
|
||||
return $this->view->style_plugin->render($this->view->result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\displays\DisplayPluginBase::defaultableSections().
|
||||
*/
|
||||
public function defaultableSections($section = NULL) {
|
||||
$sections = parent::defaultableSections($section);
|
||||
|
||||
if (in_array($section, array('style', 'row'))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$sections = parent::defaultableSections($section);
|
||||
|
||||
// Tell views our sitename_title option belongs in the title section.
|
||||
if ($section == 'title') {
|
||||
$sections[] = 'sitename_title';
|
||||
|
|
@ -108,6 +119,9 @@ class Feed extends Page {
|
|||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::defineOptions().
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
|
|
@ -124,11 +138,13 @@ class Feed extends Page {
|
|||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::optionsSummary().
|
||||
*/
|
||||
public function optionsSummary(&$categories, &$options) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::optionsSummary($categories, $options);
|
||||
|
||||
// Since we're childing off the 'page' type, we'll still *call* our
|
||||
// Since we're childing off the 'path' type, we'll still *call* our
|
||||
// category 'page' but let's override it so it says feed settings.
|
||||
$categories['page'] = array(
|
||||
'title' => t('Feed settings'),
|
||||
|
|
@ -142,9 +158,6 @@ class Feed extends Page {
|
|||
$options['title']['value'] = t('Using the site name');
|
||||
}
|
||||
|
||||
// I don't think we want to give feeds menus directly.
|
||||
unset($options['menu']);
|
||||
|
||||
$displays = array_filter($this->getOption('displays'));
|
||||
if (count($displays) > 1) {
|
||||
$attach_to = t('Multiple displays');
|
||||
|
|
@ -169,7 +182,7 @@ class Feed extends Page {
|
|||
}
|
||||
|
||||
/**
|
||||
* Provide the default form for setting options.
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::buildOptionsForm().
|
||||
*/
|
||||
public function buildOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here.
|
||||
|
|
@ -214,11 +227,9 @@ class Feed extends Page {
|
|||
}
|
||||
|
||||
/**
|
||||
* Perform any necessary changes to the form values prior to storage.
|
||||
* There is no need for this function to actually store the data.
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::submitOptionsForm().
|
||||
*/
|
||||
public function submitOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::submitOptionsForm($form, $form_state);
|
||||
switch ($form_state['section']) {
|
||||
case 'title':
|
||||
|
|
@ -231,7 +242,7 @@ class Feed extends Page {
|
|||
}
|
||||
|
||||
/**
|
||||
* Attach to another view.
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::attachTo().
|
||||
*/
|
||||
public function attachTo($display_id) {
|
||||
$displays = $this->getOption('displays');
|
||||
|
|
@ -254,6 +265,9 @@ class Feed extends Page {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::usesLinkDisplay().
|
||||
*/
|
||||
public function usesLinkDisplay() {
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\views\Plugin\views\display\Page.
|
||||
* Contains Drupal\views\Plugin\views\display\Page.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
|
@ -27,7 +27,7 @@ use Drupal\Core\Annotation\Translation;
|
|||
* admin = @Translation("Page")
|
||||
* )
|
||||
*/
|
||||
class Page extends DisplayPluginBase {
|
||||
class Page extends PathPluginBase {
|
||||
|
||||
/**
|
||||
* Whether the display allows attachments.
|
||||
|
|
@ -37,15 +37,18 @@ class Page extends DisplayPluginBase {
|
|||
protected $usesAttachments = TRUE;
|
||||
|
||||
/**
|
||||
* The page display has a path.
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::usesBreadcrumb().
|
||||
*/
|
||||
public function hasPath() { return TRUE; }
|
||||
public function usesBreadcrumb() { return TRUE; }
|
||||
public function usesBreadcrumb() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::defineOptions().
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
$options['path'] = array('default' => '');
|
||||
$options['menu'] = array(
|
||||
'contains' => array(
|
||||
'type' => array('default' => 'none'),
|
||||
|
|
@ -72,221 +75,32 @@ class Page extends DisplayPluginBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add this display's path information to Drupal's menu system.
|
||||
*/
|
||||
public function executeHookMenu($callbacks) {
|
||||
$items = array();
|
||||
// Replace % with the link to our standard views argument loader
|
||||
// views_arg_load -- which lives in views.module
|
||||
|
||||
$bits = explode('/', $this->getOption('path'));
|
||||
$page_arguments = array($this->view->storage->get('name'), $this->display['id']);
|
||||
$this->view->initHandlers();
|
||||
$view_arguments = $this->view->argument;
|
||||
|
||||
// Replace % with %views_arg for menu autoloading and add to the
|
||||
// page arguments so the argument actually comes through.
|
||||
foreach ($bits as $pos => $bit) {
|
||||
if ($bit == '%') {
|
||||
$argument = array_shift($view_arguments);
|
||||
if (!empty($argument->options['specify_validation']) && $argument->options['validate']['type'] != 'none') {
|
||||
$bits[$pos] = '%views_arg';
|
||||
}
|
||||
$page_arguments[] = $pos;
|
||||
}
|
||||
}
|
||||
|
||||
$path = implode('/', $bits);
|
||||
|
||||
$access_plugin = $this->getPlugin('access');
|
||||
if (!isset($access_plugin)) {
|
||||
$access_plugin = views_get_plugin('access', 'none');
|
||||
}
|
||||
|
||||
// Get access callback might return an array of the callback + the dynamic arguments.
|
||||
$access_plugin_callback = $access_plugin->get_access_callback();
|
||||
|
||||
if (is_array($access_plugin_callback)) {
|
||||
$access_arguments = array();
|
||||
|
||||
// Find the plugin arguments.
|
||||
$access_plugin_method = array_shift($access_plugin_callback);
|
||||
$access_plugin_arguments = array_shift($access_plugin_callback);
|
||||
if (!is_array($access_plugin_arguments)) {
|
||||
$access_plugin_arguments = array();
|
||||
}
|
||||
|
||||
$access_arguments[0] = array($access_plugin_method, &$access_plugin_arguments);
|
||||
|
||||
// Move the plugin arguments to the access arguments array.
|
||||
$i = 1;
|
||||
foreach ($access_plugin_arguments as $key => $value) {
|
||||
if (is_int($value)) {
|
||||
$access_arguments[$i] = $value;
|
||||
$access_plugin_arguments[$key] = $i;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$access_arguments = array($access_plugin_callback);
|
||||
}
|
||||
|
||||
if ($path) {
|
||||
$items[$path] = array(
|
||||
// default views page entry
|
||||
'page callback' => 'views_page',
|
||||
'page arguments' => $page_arguments,
|
||||
// Default access check (per display)
|
||||
'access callback' => 'views_access',
|
||||
'access arguments' => $access_arguments,
|
||||
// Identify URL embedded arguments and correlate them to a handler
|
||||
'load arguments' => array($this->view->storage->get('name'), $this->display['id'], '%index'),
|
||||
);
|
||||
$menu = $this->getOption('menu');
|
||||
if (empty($menu)) {
|
||||
$menu = array('type' => 'none');
|
||||
}
|
||||
// Set the title and description if we have one.
|
||||
if ($menu['type'] != 'none') {
|
||||
$items[$path]['title'] = $menu['title'];
|
||||
$items[$path]['description'] = $menu['description'];
|
||||
}
|
||||
|
||||
if (isset($menu['weight'])) {
|
||||
$items[$path]['weight'] = intval($menu['weight']);
|
||||
}
|
||||
|
||||
switch ($menu['type']) {
|
||||
case 'none':
|
||||
default:
|
||||
$items[$path]['type'] = MENU_CALLBACK;
|
||||
break;
|
||||
case 'normal':
|
||||
$items[$path]['type'] = MENU_NORMAL_ITEM;
|
||||
// Insert item into the proper menu
|
||||
$items[$path]['menu_name'] = $menu['name'];
|
||||
break;
|
||||
case 'tab':
|
||||
$items[$path]['type'] = MENU_LOCAL_TASK;
|
||||
break;
|
||||
case 'default tab':
|
||||
$items[$path]['type'] = MENU_DEFAULT_LOCAL_TASK;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add context for contextual links.
|
||||
// @see menu_contextual_links()
|
||||
if (!empty($menu['context'])) {
|
||||
$items[$path]['context'] = MENU_CONTEXT_INLINE;
|
||||
}
|
||||
|
||||
// If this is a 'default' tab, check to see if we have to create teh
|
||||
// parent menu item.
|
||||
if ($menu['type'] == 'default tab') {
|
||||
$tab_options = $this->getOption('tab_options');
|
||||
if (!empty($tab_options['type']) && $tab_options['type'] != 'none') {
|
||||
$bits = explode('/', $path);
|
||||
// Remove the last piece.
|
||||
$bit = array_pop($bits);
|
||||
|
||||
// we can't do this if they tried to make the last path bit variable.
|
||||
// @todo: We can validate this.
|
||||
if ($bit != '%views_arg' && !empty($bits)) {
|
||||
$default_path = implode('/', $bits);
|
||||
$items[$default_path] = array(
|
||||
// default views page entry
|
||||
'page callback' => 'views_page',
|
||||
'page arguments' => $page_arguments,
|
||||
// Default access check (per display)
|
||||
'access callback' => 'views_access',
|
||||
'access arguments' => $access_arguments,
|
||||
// Identify URL embedded arguments and correlate them to a handler
|
||||
'load arguments' => array($this->view->storage->get('name'), $this->display['id'], '%index'),
|
||||
'title' => $tab_options['title'],
|
||||
'description' => $tab_options['description'],
|
||||
'menu_name' => $tab_options['name'],
|
||||
);
|
||||
switch ($tab_options['type']) {
|
||||
default:
|
||||
case 'normal':
|
||||
$items[$default_path]['type'] = MENU_NORMAL_ITEM;
|
||||
break;
|
||||
case 'tab':
|
||||
$items[$default_path]['type'] = MENU_LOCAL_TASK;
|
||||
break;
|
||||
}
|
||||
if (isset($tab_options['weight'])) {
|
||||
$items[$default_path]['weight'] = intval($tab_options['weight']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* The display page handler returns a normal view, but it also does
|
||||
* a drupal_set_title for the page, and does a views_set_page_view
|
||||
* on the view.
|
||||
* Overrides \Drupal\views\Plugin\views\display\PathPluginBase::execute().
|
||||
*/
|
||||
public function execute() {
|
||||
parent::execute();
|
||||
|
||||
// Let the world know that this is the page view we're using.
|
||||
views_set_page_view($this->view);
|
||||
|
||||
// Prior to this being called, the $view should already be set to this
|
||||
// display, and arguments should be set on the view.
|
||||
$this->view->build();
|
||||
if (!empty($this->view->build_info['fail'])) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
if (!empty($this->view->build_info['denied'])) {
|
||||
throw new AccessDeniedHttpException();
|
||||
}
|
||||
|
||||
$this->view->getBreadcrumb(TRUE);
|
||||
|
||||
|
||||
// And now render the view.
|
||||
$render = $this->view->render();
|
||||
|
||||
// First execute the view so it's possible to get tokens for the title.
|
||||
// And the title, which is much easier.
|
||||
drupal_set_title(filter_xss_admin($this->view->getTitle()), PASS_THROUGH);
|
||||
|
||||
return $render;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the summary for page options in the views UI.
|
||||
*
|
||||
* This output is returned as an array.
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::optionsSummary().
|
||||
*/
|
||||
public function optionsSummary(&$categories, &$options) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::optionsSummary($categories, $options);
|
||||
|
||||
$categories['page'] = array(
|
||||
'title' => t('Page settings'),
|
||||
'column' => 'second',
|
||||
'build' => array(
|
||||
'#weight' => -10,
|
||||
),
|
||||
);
|
||||
|
||||
$path = strip_tags('/' . $this->getOption('path'));
|
||||
if (empty($path)) {
|
||||
$path = t('None');
|
||||
}
|
||||
|
||||
$options['path'] = array(
|
||||
'category' => 'page',
|
||||
'title' => t('Path'),
|
||||
'value' => views_ui_truncate($path, 24),
|
||||
);
|
||||
|
||||
$menu = $this->getOption('menu');
|
||||
if (!is_array($menu)) {
|
||||
$menu = array('type' => 'none');
|
||||
|
|
@ -319,24 +133,12 @@ class Page extends DisplayPluginBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Provide the default form for setting options.
|
||||
* Overrides \Drupal\views\Plugin\views\display\callbackPluginBase::buildOptionsForm().
|
||||
*/
|
||||
public function buildOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
|
||||
switch ($form_state['section']) {
|
||||
case 'path':
|
||||
$form['#title'] .= t('The menu path or URL of this view');
|
||||
$form['path'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed".'),
|
||||
'#default_value' => $this->getOption('path'),
|
||||
'#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)),
|
||||
'#field_suffix' => '</span>‎',
|
||||
'#attributes' => array('dir' => 'ltr'),
|
||||
);
|
||||
break;
|
||||
case 'menu':
|
||||
$form['#title'] .= t('Menu item entry');
|
||||
$form['menu'] = array(
|
||||
|
|
@ -561,50 +363,39 @@ class Page extends DisplayPluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\callbackPluginBase::validateOptionsForm().
|
||||
*/
|
||||
public function validateOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::validateOptionsForm($form, $form_state);
|
||||
switch ($form_state['section']) {
|
||||
case 'path':
|
||||
if (strpos($form_state['values']['path'], '$arg') !== FALSE) {
|
||||
form_error($form['path'], t('"$arg" is no longer supported. Use % instead.'));
|
||||
}
|
||||
|
||||
if (strpos($form_state['values']['path'], '%') === 0) {
|
||||
form_error($form['path'], t('"%" may not be used for the first segment of a path.'));
|
||||
}
|
||||
if ($form_state['section'] == 'menu') {
|
||||
$path = $this->getOption('path');
|
||||
if ($form_state['values']['menu']['type'] == 'normal' && strpos($path, '%') !== FALSE) {
|
||||
form_error($form['menu']['type'], t('Views cannot create normal menu items for paths with a % in them.'));
|
||||
}
|
||||
|
||||
// automatically remove '/' and trailing whitespace from path.
|
||||
$form_state['values']['path'] = trim($form_state['values']['path'], '/ ');
|
||||
break;
|
||||
case 'menu':
|
||||
$path = $this->getOption('path');
|
||||
if ($form_state['values']['menu']['type'] == 'normal' && strpos($path, '%') !== FALSE) {
|
||||
form_error($form['menu']['type'], t('Views cannot create normal menu items for paths with a % in them.'));
|
||||
if ($form_state['values']['menu']['type'] == 'default tab' || $form_state['values']['menu']['type'] == 'tab') {
|
||||
$bits = explode('/', $path);
|
||||
$last = array_pop($bits);
|
||||
if ($last == '%') {
|
||||
form_error($form['menu']['type'], t('A display whose path ends with a % cannot be a tab.'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($form_state['values']['menu']['type'] == 'default tab' || $form_state['values']['menu']['type'] == 'tab') {
|
||||
$bits = explode('/', $path);
|
||||
$last = array_pop($bits);
|
||||
if ($last == '%') {
|
||||
form_error($form['menu']['type'], t('A display whose path ends with a % cannot be a tab.'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($form_state['values']['menu']['type'] != 'none' && empty($form_state['values']['menu']['title'])) {
|
||||
form_error($form['menu']['title'], t('Title is required for this menu type.'));
|
||||
}
|
||||
break;
|
||||
if ($form_state['values']['menu']['type'] != 'none' && empty($form_state['values']['menu']['title'])) {
|
||||
form_error($form['menu']['title'], t('Title is required for this menu type.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\callbackPluginBase::submitOptionsForm().
|
||||
*/
|
||||
public function submitOptionsForm(&$form, &$form_state) {
|
||||
// It is very important to call the parent function here:
|
||||
parent::submitOptionsForm($form, $form_state);
|
||||
|
||||
switch ($form_state['section']) {
|
||||
case 'path':
|
||||
$this->setOption('path', $form_state['values']['path']);
|
||||
break;
|
||||
case 'menu':
|
||||
$this->setOption('menu', $form_state['values']['menu']);
|
||||
// send ajax form to options page if we use it.
|
||||
|
|
@ -618,6 +409,9 @@ class Page extends DisplayPluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::validate().
|
||||
*/
|
||||
public function validate() {
|
||||
$errors = parent::validate();
|
||||
|
||||
|
|
@ -636,6 +430,9 @@ class Page extends DisplayPluginBase {
|
|||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::getArgumentText().
|
||||
*/
|
||||
public function getArgumentText() {
|
||||
return array(
|
||||
'filter value not present' => t('When the filter value is <em>NOT</em> in the URL'),
|
||||
|
|
@ -644,6 +441,9 @@ class Page extends DisplayPluginBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::getPagerText().
|
||||
*/
|
||||
public function getPagerText() {
|
||||
return array(
|
||||
'items per page title' => t('Items per page'),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\views\Plugin\views\display\PathPluginBase.
|
||||
*/
|
||||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* The base display plugin for path/callbacks. This is used for pages, feeds.
|
||||
*/
|
||||
abstract class PathPluginBase extends DisplayPluginBase {
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::hasPath().
|
||||
*/
|
||||
public function hasPath() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase:defineOptions().
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['path'] = array('default' => '');
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add this display's path information to Drupal's menu system.
|
||||
*/
|
||||
public function executeHookMenu($callbacks) {
|
||||
$items = array();
|
||||
// Replace % with the link to our standard views argument loader
|
||||
// views_arg_load -- which lives in views.module
|
||||
|
||||
$bits = explode('/', $this->getOption('path'));
|
||||
$page_arguments = array($this->view->storage->name, $this->display['id']);
|
||||
$this->view->initHandlers();
|
||||
$view_arguments = $this->view->argument;
|
||||
|
||||
// Replace % with %views_arg for menu autoloading and add to the
|
||||
// page arguments so the argument actually comes through.
|
||||
foreach ($bits as $pos => $bit) {
|
||||
if ($bit == '%') {
|
||||
$argument = array_shift($view_arguments);
|
||||
if (!empty($argument->options['specify_validation']) && $argument->options['validate']['type'] != 'none') {
|
||||
$bits[$pos] = '%views_arg';
|
||||
}
|
||||
$page_arguments[] = $pos;
|
||||
}
|
||||
}
|
||||
|
||||
$path = implode('/', $bits);
|
||||
|
||||
$access_plugin = $this->getPlugin('access');
|
||||
if (!isset($access_plugin)) {
|
||||
$access_plugin = views_get_plugin('access', 'none');
|
||||
}
|
||||
|
||||
// Get access callback might return an array of the callback + the dynamic arguments.
|
||||
$access_plugin_callback = $access_plugin->get_access_callback();
|
||||
|
||||
if (is_array($access_plugin_callback)) {
|
||||
$access_arguments = array();
|
||||
|
||||
// Find the plugin arguments.
|
||||
$access_plugin_method = array_shift($access_plugin_callback);
|
||||
$access_plugin_arguments = array_shift($access_plugin_callback);
|
||||
if (!is_array($access_plugin_arguments)) {
|
||||
$access_plugin_arguments = array();
|
||||
}
|
||||
|
||||
$access_arguments[0] = array($access_plugin_method, &$access_plugin_arguments);
|
||||
|
||||
// Move the plugin arguments to the access arguments array.
|
||||
$i = 1;
|
||||
foreach ($access_plugin_arguments as $key => $value) {
|
||||
if (is_int($value)) {
|
||||
$access_arguments[$i] = $value;
|
||||
$access_plugin_arguments[$key] = $i;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$access_arguments = array($access_plugin_callback);
|
||||
}
|
||||
|
||||
if ($path) {
|
||||
$items[$path] = array(
|
||||
// default views page entry
|
||||
'page callback' => 'views_page',
|
||||
'page arguments' => $page_arguments,
|
||||
// Default access check (per display)
|
||||
'access callback' => 'views_access',
|
||||
'access arguments' => $access_arguments,
|
||||
// Identify URL embedded arguments and correlate them to a handler
|
||||
'load arguments' => array($this->view->storage->name, $this->display['id'], '%index'),
|
||||
);
|
||||
$menu = $this->getOption('menu');
|
||||
if (empty($menu)) {
|
||||
$menu = array('type' => 'none');
|
||||
}
|
||||
// Set the title and description if we have one.
|
||||
if ($menu['type'] != 'none') {
|
||||
$items[$path]['title'] = $menu['title'];
|
||||
$items[$path]['description'] = $menu['description'];
|
||||
}
|
||||
|
||||
if (isset($menu['weight'])) {
|
||||
$items[$path]['weight'] = intval($menu['weight']);
|
||||
}
|
||||
|
||||
switch ($menu['type']) {
|
||||
case 'none':
|
||||
default:
|
||||
$items[$path]['type'] = MENU_CALLBACK;
|
||||
break;
|
||||
case 'normal':
|
||||
$items[$path]['type'] = MENU_NORMAL_ITEM;
|
||||
// Insert item into the proper menu
|
||||
$items[$path]['menu_name'] = $menu['name'];
|
||||
break;
|
||||
case 'tab':
|
||||
$items[$path]['type'] = MENU_LOCAL_TASK;
|
||||
break;
|
||||
case 'default tab':
|
||||
$items[$path]['type'] = MENU_DEFAULT_LOCAL_TASK;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add context for contextual links.
|
||||
// @see menu_contextual_links()
|
||||
if (!empty($menu['context'])) {
|
||||
$items[$path]['context'] = MENU_CONTEXT_INLINE;
|
||||
}
|
||||
|
||||
// If this is a 'default' tab, check to see if we have to create teh
|
||||
// parent menu item.
|
||||
if ($menu['type'] == 'default tab') {
|
||||
$tab_options = $this->getOption('tab_options');
|
||||
if (!empty($tab_options['type']) && $tab_options['type'] != 'none') {
|
||||
$bits = explode('/', $path);
|
||||
// Remove the last piece.
|
||||
$bit = array_pop($bits);
|
||||
|
||||
// we can't do this if they tried to make the last path bit variable.
|
||||
// @todo: We can validate this.
|
||||
if ($bit != '%views_arg' && !empty($bits)) {
|
||||
$default_path = implode('/', $bits);
|
||||
$items[$default_path] = array(
|
||||
// default views page entry
|
||||
'page callback' => 'views_page',
|
||||
'page arguments' => $page_arguments,
|
||||
// Default access check (per display)
|
||||
'access callback' => 'views_access',
|
||||
'access arguments' => $access_arguments,
|
||||
// Identify URL embedded arguments and correlate them to a handler
|
||||
'load arguments' => array($this->view->storage->name, $this->display['id'], '%index'),
|
||||
'title' => $tab_options['title'],
|
||||
'description' => $tab_options['description'],
|
||||
'menu_name' => $tab_options['name'],
|
||||
);
|
||||
switch ($tab_options['type']) {
|
||||
default:
|
||||
case 'normal':
|
||||
$items[$default_path]['type'] = MENU_NORMAL_ITEM;
|
||||
break;
|
||||
case 'tab':
|
||||
$items[$default_path]['type'] = MENU_LOCAL_TASK;
|
||||
break;
|
||||
}
|
||||
if (isset($tab_options['weight'])) {
|
||||
$items[$default_path]['weight'] = intval($tab_options['weight']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::execute().
|
||||
*/
|
||||
public function execute() {
|
||||
// Prior to this being called, the $view should already be set to this
|
||||
// display, and arguments should be set on the view.
|
||||
$this->view->build();
|
||||
|
||||
if (!empty($this->view->build_info['fail'])) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
if (!empty($this->view->build_info['denied'])) {
|
||||
throw new AccessDeniedHttpException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::optionsSummary().
|
||||
*/
|
||||
public function optionsSummary(&$categories, &$options) {
|
||||
parent::optionsSummary($categories, $options);
|
||||
|
||||
$categories['page'] = array(
|
||||
'title' => t('Page settings'),
|
||||
'column' => 'second',
|
||||
'build' => array(
|
||||
'#weight' => -10,
|
||||
),
|
||||
);
|
||||
|
||||
$path = strip_tags('/' . $this->getOption('path'));
|
||||
if (empty($path)) {
|
||||
$path = t('None');
|
||||
}
|
||||
|
||||
$options['path'] = array(
|
||||
'category' => 'page',
|
||||
'title' => t('Path'),
|
||||
'value' => views_ui_truncate($path, 24),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::buildOptionsForm()..
|
||||
*/
|
||||
public function buildOptionsForm(&$form, &$form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
|
||||
switch ($form_state['section']) {
|
||||
case 'path':
|
||||
$form['#title'] .= t('The menu path or URL of this view');
|
||||
$form['path'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed".'),
|
||||
'#default_value' => $this->getOption('path'),
|
||||
'#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)),
|
||||
'#field_suffix' => '</span>‎',
|
||||
'#attributes' => array('dir' => 'ltr'),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::validateOptionsForm().
|
||||
*/
|
||||
public function validateOptionsForm(&$form, &$form_state) {
|
||||
parent::validateOptionsForm($form, $form_state);
|
||||
|
||||
if ($form_state['section'] == 'path') {
|
||||
if (strpos($form_state['values']['path'], '%') === 0) {
|
||||
form_error($form['path'], t('"%" may not be used for the first segment of a path.'));
|
||||
}
|
||||
|
||||
// Automatically remove '/' and trailing whitespace from path.
|
||||
$form_state['values']['path'] = trim($form_state['values']['path'], '/ ');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\views\Plugin\views\display\DisplayPluginBase::submitOptionsForm().
|
||||
*/
|
||||
public function submitOptionsForm(&$form, &$form_state) {
|
||||
parent::submitOptionsForm($form, $form_state);
|
||||
|
||||
if ($form_state['section'] == 'path') {
|
||||
$this->setOption('path', $form_state['values']['path']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ class DisplayFeedTest extends PluginTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
$this->assertEqual($options, array('default', 'feed', 'page'), 'Make sure all displays appears as expected.');
|
||||
$this->assertEqual($options, array('default', 'page'), 'Make sure all displays appears as expected.');
|
||||
|
||||
// Post and save this and check the output.
|
||||
$this->drupalPost('admin/structure/views/nojs/display/test_feed_display/feed/displays', array('displays[page]' => 'page'), t('Apply'));
|
||||
|
|
|
|||
Loading…
Reference in New Issue