Newer
Older
Angie Byron
committed
* Contains Drupal\views\Plugin\views\display\DisplayPluginBase.
namespace Drupal\views\Plugin\views\display;
use Drupal\Core\Language\Language;
use Drupal\views\Plugin\views\area\AreaPluginBase;
Daniel Wehner
committed
use Drupal\views\ViewExecutable;
Angie Byron
committed
use \Drupal\views\Plugin\views\PluginBase;
Dries Buytaert
committed
use Drupal\views\Views;
/**
* @defgroup views_display_plugins Views display plugins
* @{
* Display plugins control how Views interact with the rest of Drupal.
*
* They can handle creating Views from a Drupal page hook; they can
* handle creating Views from a Drupal block hook. They can also
* handle creating Views from an external module source.
*/
/**
* The default display plugin handler. Display plugins handle options and
* basic mechanisms for different output methods.
*/
Tim Plunkett
committed
abstract class DisplayPluginBase extends PluginBase {
* @var \Drupal\views\ViewExecutable
*/
var $view = NULL;
var $handlers = array();
Tim Plunkett
committed
/**
* An array of instantiated plugins used in this display.
*
* @var array
*/
protected $plugins = array();
/**
* Stores all available display extenders.
*/
var $extender = array();
Tim Plunkett
committed
/**
* Overrides Drupal\views\Plugin\Plugin::$usesOptions.
*/
protected $usesOptions = TRUE;
Tim Plunkett
committed
Daniel Wehner
committed
/**
* Stores the rendered output of the display.
*
* @see View::render
Daniel Wehner
committed
* @var string
*/
public $output = NULL;
Salvador Molina
committed
/**
* Whether the display allows the use of AJAX or not.
*
* @var bool
*/
protected $usesAJAX = TRUE;
Salvador Molina
committed
/**
* Whether the display allows the use of a pager or not.
*
* @var bool
*/
protected $usesPager = TRUE;
/**
* Whether the display allows the use of a 'more' link or not.
*
* @var bool
*/
protected $usesMore = TRUE;
Damian Lee
committed
/**
* Whether the display allows attachments.
*
* @var bool
* TRUE if the display can use attachments, or FALSE otherwise.
*/
protected $usesAttachments = FALSE;
Angie Byron
committed
/**
* Whether the display allows area plugins.
*
* @var bool
*/
protected $usesAreas = TRUE;
/**
* Constructs a new DisplayPluginBase object.
*
* Because DisplayPluginBase::initDisplay() takes the display configuration by
* reference and handles it differently than usual plugin configuration, pass
* an empty array of configuration to the parent. This prevents our
* configuration from being duplicated.
*
* @todo Replace DisplayPluginBase::$display with
* DisplayPluginBase::$configuration to standardize with other plugins.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
parent::__construct(array(), $plugin_id, $plugin_definition);
}
public function initDisplay(ViewExecutable $view, array &$display, array &$options = NULL) {
Tim Plunkett
committed
$this->setOptionDefaults($this->options, $this->defineOptions());
$this->view = $view;
$this->display = &$display;
// Load extenders as soon as possible.
$this->extender = array();
$extenders = views_get_enabled_display_extenders();
if (!empty($extenders)) {
Dries Buytaert
committed
$manager = Views::pluginManager('display_extender');
Angie Byron
committed
$plugin = $manager->createInstance($extender);
if ($plugin) {
$plugin->init($this->view, $this);
$this->extender[$extender] = $plugin;
}
}
}
// Track changes that the user should know about.
$changed = FALSE;
// Make some modifications:
Daniel Wehner
committed
if (!isset($options) && isset($display['display_options'])) {
$options = $display['display_options'];
Daniel Wehner
committed
if ($this->isDefaultDisplay() && isset($options['defaults'])) {
// Cache for unpackOptions, but not if we are in the ui.
static $unpack_options = array();
if (empty($view->editing)) {
Angie Byron
committed
$cid = 'unpackOptions:' . hash('sha256', serialize(array($this->options, $options)));
if (empty($unpack_options[$cid])) {
$cache = views_cache_get($cid, TRUE);
if (!empty($cache->data)) {
$this->options = $cache->data;
}
else {
$this->unpackOptions($this->options, $options);
views_cache_set($cid, $this->options, TRUE);
}
$unpack_options[$cid] = $this->options;
}
else {
$this->options = $unpack_options[$cid];
}
}
else {
$this->unpackOptions($this->options, $options);
// Convert the field_language and field_language_add_to_query settings.
Daniel Wehner
committed
$field_language = $this->getOption('field_language');
$field_language_add_to_query = $this->getOption('field_language_add_to_query');
if (isset($field_langcode)) {
Daniel Wehner
committed
$this->setOption('field_langcode', $field_language);
$this->setOption('field_langcode_add_to_query', $field_language_add_to_query);
$changed = TRUE;
}
// Mark the view as changed so the user has a chance to save it.
if ($changed) {
$this->view->changed = TRUE;
}
}
Daniel Wehner
committed
public function destroy() {
parent::destroy();
foreach ($this->handlers as $type => $handlers) {
foreach ($handlers as $id => $handler) {
if (is_object($handler)) {
$this->handlers[$type][$id]->destroy();
}
}
}
if (isset($this->default_display)) {
unset($this->default_display);
}
foreach ($this->extender as $extender) {
$extender->destroy();
}
}
/**
* Determine if this display is the 'default' display which contains
* fallback settings
*/
Daniel Wehner
committed
public function isDefaultDisplay() { return FALSE; }
/**
* Determine if this display uses exposed filters, so the view
* will know whether or not to build them.
*/
Daniel Wehner
committed
public function usesExposed() {
if (!isset($this->has_exposed)) {
foreach ($this->handlers as $type => $value) {
foreach ($this->view->$type as $id => $handler) {
if ($handler->canExpose() && $handler->isExposed()) {
// one is all we need; if we find it, return true.
$this->has_exposed = TRUE;
return TRUE;
}
}
}
Daniel Wehner
committed
$pager = $this->getPlugin('pager');
Alex Pott
committed
if (isset($pager) && $pager->usesExposed()) {
$this->has_exposed = TRUE;
return TRUE;
}
$this->has_exposed = FALSE;
}
return $this->has_exposed;
}
/**
* 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
Daniel Wehner
committed
* displayed unless usesExposed() returns TRUE.
Daniel Wehner
committed
public function displaysExposed() {
Salvador Molina
committed
* Whether the display allows the use of AJAX or not.
*
* @return bool
*/
Daniel Wehner
committed
public function usesAJAX() {
Salvador Molina
committed
return $this->usesAJAX;
}
/**
* Whether the display is actually using AJAX or not.
*
* @return bool
public function ajaxEnabled() {
Salvador Molina
committed
if ($this->usesAJAX()) {
Daniel Wehner
committed
return $this->getOption('use_ajax');
Daniel Wehner
committed
/**
* Whether the display is enabled.
*
* @return bool
* Returns TRUE if the display is marked as enabled, else FALSE.
*/
public function isEnabled() {
return (bool) $this->getOption('enabled');
}
Salvador Molina
committed
* Whether the display allows the use of a pager or not.
*
* @return bool
*/
Daniel Wehner
committed
public function usesPager() {
Salvador Molina
committed
return $this->usesPager;
}
/**
* Whether the display is using a pager or not.
*
* @return bool
Daniel Wehner
committed
public function isPagerEnabled() {
Salvador Molina
committed
if ($this->usesPager()) {
Daniel Wehner
committed
$pager = $this->getPlugin('pager');
Salvador Molina
committed
if ($pager) {
Alex Pott
committed
return $pager->usePager();
Salvador Molina
committed
}
Salvador Molina
committed
return FALSE;
Salvador Molina
committed
* Whether the display allows the use of a 'more' link or not.
*
* @return bool
*/
Daniel Wehner
committed
public function usesMore() {
Salvador Molina
committed
return $this->usesMore;
}
/**
* Whether the display is using the 'more' link or not.
*
* @return bool
Daniel Wehner
committed
public function isMoreEnabled() {
Salvador Molina
committed
if ($this->usesMore()) {
Daniel Wehner
committed
return $this->getOption('use_more');
}
return FALSE;
}
/**
* Does the display have groupby enabled?
*/
Daniel Wehner
committed
public function useGroupBy() {
return $this->getOption('group_by');
}
/**
* Should the enabled display more link be shown when no more items?
*/
Daniel Wehner
committed
public function useMoreAlways() {
Salvador Molina
committed
if ($this->usesMore()) {
return $this->getOption('use_more_always');
}
return FALSE;
}
/**
* Does the display have custom link text?
*/
Daniel Wehner
committed
public function useMoreText() {
Salvador Molina
committed
if ($this->usesMore()) {
return $this->getOption('use_more_text');
Damian Lee
committed
* Determines whether this display can use attachments.
*
* @return bool
Daniel Wehner
committed
public function acceptAttachments() {
Angie Byron
committed
// 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)) {
Angie Byron
committed
Daniel Wehner
committed
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)) {
Angie Byron
committed
Damian Lee
committed
/**
* Returns whether the display can use attachments.
*
* @return bool
*/
Daniel Wehner
committed
public function usesAttachments() {
Damian Lee
committed
return $this->usesAttachments;
}
Angie Byron
committed
/**
* Returns whether the display can use areas.
*
* @return bool
* TRUE if the display can use areas, or FALSE otherwise.
*/
public function usesAreas() {
return $this->usesAreas;
}
/**
* Allow displays to attach to other views.
*/
public function attachTo(ViewExecutable $view, $display_id) { }
/**
* Static member function to list which sections are defaultable
* and what items each section contains.
*/
Daniel Wehner
committed
public function defaultableSections($section = NULL) {
'access' => array('access'),
'cache' => array('cache'),
'title' => array('title'),
'css_class' => array('css_class'),
'use_ajax' => array('use_ajax'),
'hide_attachment_summary' => array('hide_attachment_summary'),
Angie Byron
committed
'show_admin_links' => array('show_admin_links'),
'group_by' => array('group_by'),
'query' => array('query'),
'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
Daniel Wehner
committed
'use_more_always' => array('use_more', 'use_more_always', 'use_more_text'),
'use_more_text' => array('use_more', 'use_more_always', 'use_more_text'),
'link_display' => array('link_display', 'link_url'),
// Force these to cascade properly.
'style' => array('style', 'row'),
'row' => array('style', 'row'),
'pager' => array('pager', 'pager_options'),
'pager_options' => array('pager', 'pager_options'),
'exposed_form' => array('exposed_form', 'exposed_form_options'),
'exposed_form_options' => array('exposed_form', 'exposed_form_options'),
// These guys are special
'header' => array('header'),
'footer' => array('footer'),
'empty' => array('empty'),
'relationships' => array('relationships'),
'fields' => array('fields'),
'sorts' => array('sorts'),
'arguments' => array('arguments'),
'filters' => array('filters', 'filter_groups'),
'filter_groups' => array('filters', 'filter_groups'),
);
// If the display cannot use a pager, then we cannot default it.
Salvador Molina
committed
if (!$this->usesPager()) {
unset($sections['pager']);
unset($sections['items_per_page']);
}
foreach ($this->extender as $extender) {
Daniel Wehner
committed
$extender->defaultableSections($sections, $section);
}
if ($section) {
if (!empty($sections[$section])) {
return $sections[$section];
}
}
else {
return $sections;
}
}
protected function defineOptions() {
$options = array(
'defaults' => array(
'default' => array(
'access' => TRUE,
'cache' => TRUE,
'query' => TRUE,
'title' => TRUE,
'css_class' => TRUE,
'display_description' => FALSE,
'use_ajax' => TRUE,
'hide_attachment_summary' => TRUE,
Angie Byron
committed
'show_admin_links' => TRUE,
'pager' => TRUE,
'use_more' => TRUE,
'use_more_always' => TRUE,
'use_more_text' => TRUE,
'exposed_form' => TRUE,
'link_display' => TRUE,
'link_url' => '',
'group_by' => TRUE,
'style' => TRUE,
'row' => TRUE,
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
'header' => TRUE,
'footer' => TRUE,
'empty' => TRUE,
'relationships' => TRUE,
'fields' => TRUE,
'sorts' => TRUE,
'arguments' => TRUE,
'filters' => TRUE,
'filter_groups' => TRUE,
),
),
'title' => array(
'default' => '',
'translatable' => TRUE,
),
'enabled' => array(
'default' => TRUE,
'translatable' => FALSE,
'bool' => TRUE,
),
'display_comment' => array(
'default' => '',
),
'css_class' => array(
'default' => '',
'translatable' => FALSE,
),
'display_description' => array(
'default' => '',
'translatable' => TRUE,
),
'use_ajax' => array(
'default' => FALSE,
'bool' => TRUE,
),
'hide_attachment_summary' => array(
'default' => FALSE,
'bool' => TRUE,
),
Angie Byron
committed
'show_admin_links' => array(
'default' => TRUE,
Damian Lee
committed
'bool' => TRUE,
),
'use_more' => array(
'default' => FALSE,
'bool' => TRUE,
),
'use_more_always' => array(
'default' => FALSE,
Daniel Wehner
committed
'bool' => TRUE,
),
'use_more_text' => array(
'default' => 'more',
'translatable' => TRUE,
),
'link_display' => array(
'default' => '',
),
'link_url' => array(
'default' => '',
),
'group_by' => array(
'default' => FALSE,
'bool' => TRUE,
),
'field_langcode' => array(
'default' => '***CURRENT_LANGUAGE***',
),
'field_langcode_add_to_query' => array(
'default' => TRUE,
'bool' => TRUE,
),
// These types are all plugins that can have individual settings
// and therefore need special handling.
'access' => array(
'contains' => array(
Tim Plunkett
committed
'type' => array('default' => 'none'),
'options' => array('default' => array()),
),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
),
'cache' => array(
'contains' => array(
Tim Plunkett
committed
'type' => array('default' => 'none'),
'options' => array('default' => array()),
),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
),
'query' => array(
'contains' => array(
Tim Plunkett
committed
'type' => array('default' => 'views_query'),
'options' => array('default' => array()),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
),
'exposed_form' => array(
'contains' => array(
Tim Plunkett
committed
'type' => array('default' => 'basic'),
'options' => array('default' => array()),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
),
'pager' => array(
'contains' => array(
'type' => array('default' => 'mini'),
Tim Plunkett
committed
'options' => array('default' => array()),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
'style' => array(
'contains' => array(
'type' => array('default' => 'default'),
'options' => array('default' => array()),
),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
'row' => array(
'contains' => array(
'type' => array('default' => 'fields'),
'options' => array('default' => array()),
),
Alex Pott
committed
'merge_defaults' => array($this, 'mergePlugin'),
),
'exposed_block' => array(
'default' => FALSE,
),
'header' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
'footer' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
'empty' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
// We want these to export last.
// These are the 5 handler types.
'relationships' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
'fields' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
'sorts' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
'arguments' => array(
'default' => array(),
Alex Pott
committed
'merge_defaults' => array($this, 'mergeHandler'),
),
'filter_groups' => array(
'contains' => array(
'operator' => array('default' => 'AND'),
'groups' => array('default' => array(1 => 'AND')),
),
),
'filters' => array(
'default' => array(),
),
);
Salvador Molina
committed
if (!$this->usesPager()) {
$options['defaults']['default']['use_pager'] = FALSE;
$options['defaults']['default']['items_per_page'] = FALSE;
$options['defaults']['default']['offset'] = FALSE;
$options['defaults']['default']['pager'] = FALSE;
$options['pager']['contains']['type']['default'] = 'some';
}
Daniel Wehner
committed
if ($this->isDefaultDisplay()) {
unset($options['defaults']);
}
foreach ($this->extender as $extender) {
Daniel Wehner
committed
$extender->defineOptionsAlter($options);
}
return $options;
}
/**
* Check to see if the display has a 'path' field.
*
* This is a pure function and not just a setting on the definition
* because some displays (such as a panel pane) may have a path based
* upon configuration.
*
* By default, displays do not have a path.
*/
Daniel Wehner
committed
public function hasPath() { return FALSE; }
/**
* Check to see if the display has some need to link to another display.
*
* For the most part, displays without a path will use a link display. However,
* sometimes displays that have a path might also need to link to another display.
* This is true for feeds.
*/
Daniel Wehner
committed
public function usesLinkDisplay() { return !$this->hasPath(); }
/**
* Check to see if the display can put the exposed formin a block.
*
* By default, displays that do not have a path cannot disconnect
* the exposed form and put it in a block, because the form has no
* place to go and Views really wants the forms to go to a specific
* page.
*/
Daniel Wehner
committed
public function usesExposedFormInBlock() { return $this->hasPath(); }
catch
committed
/**
* Find out all displays which are attached to this display.
*
* The method is just using the pure storage object to avoid loading of the
* sub displays which would kill lazy loading.
*/
public function getAttachedDisplays() {
$current_display_id = $this->display['id'];
$attached_displays = array();
// Go through all displays and search displays which link to this one.
foreach ($this->view->storage->get('display') as $display_id => $display) {
if (isset($display['display_options']['displays'])) {
$displays = $display['display_options']['displays'];
if (isset($displays[$current_display_id])) {
$attached_displays[] = $display_id;
}
}
}
return $attached_displays;
}
/**
* Check to see which display to use when creating links within
* a view using this display.
*/
Daniel Wehner
committed
public function getLinkDisplay() {
$display_id = $this->getOption('link_display');
if (empty($display_id) || !$this->view->displayHandlers->has($display_id)) {
Daniel Wehner
committed
foreach ($this->view->displayHandlers as $display_id => $display) {
if (!empty($display) && $display->hasPath()) {
return $display_id;
}
}
}
else {
return $display_id;
}
// fall-through returns NULL
}
/**
* Return the base path to use for this display.
*
* This can be overridden for displays that do strange things
* with the path.
*/
Daniel Wehner
committed
public function getPath() {
if ($this->hasPath()) {
return $this->getOption('path');
Daniel Wehner
committed
$display_id = $this->getLinkDisplay();
if ($display_id && $this->view->displayHandlers->has($display_id) && is_object($this->view->displayHandlers->get($display_id))) {
return $this->view->displayHandlers->get($display_id)->getPath();
Daniel Wehner
committed
public function getUrl() {
Damian Lee
committed
return $this->view->getUrl();
}
/**
* Check to see if the display needs a breadcrumb
*
* By default, displays do not need breadcrumbs
*/
Daniel Wehner
committed
public function usesBreadcrumb() { return FALSE; }
/**
* Determine if a given option is set to use the default display or the
* current display
*
* @return
* TRUE for the default display
*/
Daniel Wehner
committed
public function isDefaulted($option) {
return !$this->isDefaultDisplay() && !empty($this->default_display) && !empty($this->options['defaults'][$option]);
}
/**
* Intelligently get an option either from this display or from the
* default display, if directed to do so.
*/
Daniel Wehner
committed
public function getOption($option) {
if ($this->isDefaulted($option)) {
return $this->default_display->getOption($option);
}
if (array_key_exists($option, $this->options)) {
return $this->options[$option];
}
}
/**
* Determine if the display's style uses fields.
*
* @return bool
Daniel Wehner
committed
public function usesFields() {
Tim Plunkett
committed
return $this->getPlugin('style')->usesFields();
}
/**
* Get the instance of a plugin, for example style or row.
*
* @param string $type
* The type of the plugin.
*
Angie Byron
committed
* @return \Drupal\views\Plugin\views\PluginBase
Tim Plunkett
committed
*/
public function getPlugin($type) {
Tim Plunkett
committed
// Look up the plugin name to use for this instance.
Tim Plunkett
committed
$options = $this->getOption($type);
// Return now if no options have been loaded.
if (empty($options) || !isset($options['type'])) {
return;
}
Tim Plunkett
committed
// Query plugins allow specifying a specific query class per base table.
if ($type == 'query') {
Dries Buytaert
committed
$views_data = Views::viewsData()->get($this->view->storage->get('base_table'));
catch
committed
$name = isset($views_data['table']['base']['query_id']) ? $views_data['table']['base']['query_id'] : 'views_query';
Tim Plunkett
committed
}
else {
$name = $options['type'];
}
Tim Plunkett
committed
// Plugin instances are stored on the display for re-use.
if (!isset($this->plugins[$type][$name])) {
Dries Buytaert
committed
$plugin = Views::pluginManager($type)->createInstance($name);
catch
committed
// Initialize the plugin.
$plugin->init($this->view, $this, $options['options']);
Tim Plunkett
committed
Tim Plunkett
committed
$this->plugins[$type][$name] = $plugin;
Tim Plunkett
committed
return $this->plugins[$type][$name];
}
/**
* Get the handler object for a single handler.
*/
Daniel Wehner
committed
public function &getHandler($type, $id) {
Daniel Wehner
committed
$this->getHandlers($type);
}
if (isset($this->handlers[$type][$id])) {
return $this->handlers[$type][$id];
}
// So we can return a reference.
$null = NULL;
return $null;
}
/**
* Get a full array of handlers for $type. This caches them.
*/
Daniel Wehner
committed
public function getHandlers($type) {
if (!isset($this->handlers[$type])) {
$this->handlers[$type] = array();
Daniel Wehner
committed
$types = ViewExecutable::viewsHandlerTypes();
Daniel Wehner
committed
foreach ($this->getOption($plural) as $id => $info) {
// If this is during form submission and there are temporary options
// which can only appear if the view is in the edit cache, use those
// options instead. This is used for AJAX multi-step stuff.
if (\Drupal::request()->request->get('form_id') && isset($this->view->temporary_options[$type][$id])) {
$info = $this->view->temporary_options[$type][$id];
}
if ($info['id'] != $id) {
$info['id'] = $id;
}
// If aggregation is on, the group type might override the actual
// handler that is in use. This piece of code checks that and,
// if necessary, sets the override handler.
$override = NULL;
Daniel Wehner
committed
if ($this->useGroupBy() && !empty($info['group_type'])) {
Damian Lee
committed
$this->view->initQuery();
$aggregate = $this->view->query->getAggregationInfo();
if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
$override = $aggregate[$info['group_type']]['handler'][$type];
}
}
if (!empty($types[$type]['type'])) {
$handler_type = $types[$type]['type'];
}
else {
$handler_type = $type;
}
Dries Buytaert
committed
if ($handler = Views::handlerManager($handler_type)->getHandler($info, $override)) {
// Special override for area types so they know where they come from.
if ($handler instanceof AreaPluginBase) {
$handler->areaType = $type;
$handler->init($this->view, $this, $info);
$this->handlers[$type][$id] = &$handler;
}
// Prevent reference problems.
unset($handler);
}
}
return $this->handlers[$type];
}
/**
* Retrieves a list of fields for the current display.
*
* This also takes into account any associated relationships, if they exist.
*
* @param bool $groupable_only
* (optional) TRUE to only return an array of field labels from handlers
Alex Pott
committed
* that support the useStringGroupBy method, defaults to FALSE.
*
* @return array
* An array of applicable field options, keyed by ID.
public function getFieldLabels($groupable_only = FALSE) {
Daniel Wehner
committed
foreach ($this->getHandlers('relationship') as $relationship => $handler) {
Alex Pott
committed
$relationships[$relationship] = $handler->adminLabel();
Daniel Wehner
committed
foreach ($this->getHandlers('field') as $id => $handler) {
Alex Pott
committed
if ($groupable_only && !$handler->useStringGroupBy()) {
// Continue to next handler if it's not groupable.
continue;
}
if ($label = $handler->label()) {
$options[$id] = $label;
}
else {
$options[$id] = $handler->adminLabel();
}
if (!empty($handler->options['relationship']) && !empty($relationships[$handler->options['relationship']])) {
$options[$id] = '(' . $relationships[$handler->options['relationship']] . ') ' . $options[$id];
}
}
return $options;
}
/**
* Intelligently set an option either from this display or from the
* default display, if directed to do so.
*/
Daniel Wehner
committed
public function setOption($option, $value) {
if ($this->isDefaulted($option)) {
return $this->default_display->setOption($option, $value);
}
// Set this in two places: On the handler where we'll notice it
// but also on the display object so it gets saved. This should
// only be a temporary fix.
Daniel Wehner
committed
$this->display['display_options'][$option] = $value;
return $this->options[$option] = $value;
}
/**
* Set an option and force it to be an override.
*/
Daniel Wehner
committed
public function overrideOption($option, $value) {
$this->setOverride($option, FALSE);
$this->setOption($option, $value);
}
/**
* Because forms may be split up into sections, this provides
* an easy URL to exactly the right section. Don't override this.
*/
Daniel Wehner
committed
public function optionLink($text, $section, $class = '', $title = '') {
if (!empty($class)) {
$text = '<span>' . $text . '</span>';