Skip to content
plugins.inc 129 KiB
Newer Older
 * @file plugins.inc
 * Built in plugins for Views output handling.
 * Implementation of hook_views_plugins
 */
function views_views_plugins() {
  $path = drupal_get_path('module', 'views') . '/js';
  return array(
    'module' => 'views', // This just tells our themes are elsewhere.
    'display' => array(
Earl Miles's avatar
Earl Miles committed
      'default' => array(
        'title' => t('Defaults'),
        'help' => t('Default settings for this view.'),
        'handler' => 'views_plugin_display_default',
Earl Miles's avatar
Earl Miles committed
        'no ui' => TRUE,
        'no remove' => TRUE,
        'js' => array('misc/collapse.js', 'misc/textarea.js', 'misc/tabledrag.js', 'misc/autocomplete.js', "$path/dependent.js"),
        'use pager' => TRUE,
        'help topic' => 'display-default',
Earl Miles's avatar
Earl Miles committed
      ),
      'page' => array(
        'title' => t('Page'),
Earl Miles's avatar
Earl Miles committed
        'help' => t('Display the view as a page, with a URL and menu links.'),
        'handler' => 'views_plugin_display_page',
        'use pager' => TRUE,
        'help topic' => 'display-page',
      ),
      'block' => array(
Earl Miles's avatar
Earl Miles committed
        'help' => t('Display the view as a block.'),
        'handler' => 'views_plugin_display_block',
        'use ajax' => TRUE,
        'use pager' => TRUE,
        'help topic' => 'display-block',
      ),
      'attachment' => array(
        'title' => t('Attachment'),
        'help' => t('Attachments added to other displays to achieve multiple views in the same view.'),
        'handler' => 'views_plugin_display_attachment',
        'help topic' => 'display-attachment',
Earl Miles's avatar
Earl Miles committed
      'feed' => array(
        'title' => t('Feed'),
        'help' => t('Display the view as a feed, such as an RSS feed.'),
        'handler' => 'views_plugin_display_feed',
        'uses hook menu' => TRUE,
        'use ajax' => FALSE,
        'use pager' => FALSE,
        'accept attachments' => FALSE,
        'help topic' => 'display-feed',
Earl Miles's avatar
Earl Miles committed
      ),
    ),
    'style' => array(
      'default' => array(
        'help' => t('Displays rows one after another.'),
        'handler' => 'views_plugin_style_default',
        'theme' => 'views_view_unformatted',
        'uses options' => TRUE,
        'uses grouping' => TRUE,
Earl Miles's avatar
Earl Miles committed
        'type' => 'normal',
      ),
      'list' => array(
        'title' => t('List'),
        'help' => t('Displays rows as an HTML list.'),
        'handler' => 'views_plugin_style_list',
        'theme' => 'views_view_list',
        'uses row plugin' => TRUE,
        'uses options' => TRUE,
Earl Miles's avatar
Earl Miles committed
        'type' => 'normal',
      'grid' => array(
        'title' => t('Grid'),
        'help' => t('Displays rows in a grid.'),
        'handler' => 'views_plugin_style_grid',
        'theme' => 'views_view_grid',
        'uses row plugin' => TRUE,
        'uses options' => TRUE,
        'type' => 'normal',
      ),
      'table' => array(
        'title' => t('Table'),
        'help' => t('Displays rows in a table.'),
        'handler' => 'views_plugin_style_table',
        'theme' => 'views_view_table',
        'uses row plugin' => FALSE,
        'uses fields' => TRUE,
Earl Miles's avatar
Earl Miles committed
        'type' => 'normal',
        'title' => t('List'),
        'help' => t('Displays the default summary summary as a list.'),
        'handler' => 'views_plugin_style_summary',
Earl Miles's avatar
Earl Miles committed
        'type' => 'summary', // only shows up as a summary style
        'uses options' => TRUE,
      ),
      'unformatted_summary' => array(
        'title' => t('Unformatted'),
        'help' => t('Displays the summary unformatted, with option for one after another or inline.'),
        'handler' => 'views_plugin_style_summary_unformatted',
        'theme' => 'views_view_summary_unformatted',
        'type' => 'summary', // only shows up as a summary style
        'uses options' => TRUE,
      ),
Earl Miles's avatar
Earl Miles committed
      'rss' => array(
        'title' => t('RSS Feed'),
        'help' => t('Generates an RSS feed from a view.'),
        'handler' => 'views_plugin_style_rss',
        'theme' => 'views_view_rss',
        'uses row plugin' => TRUE,
Earl Miles's avatar
Earl Miles committed
        'type' => 'feed',
    ),
    'row' => array(
      'fields' => array(
        'title' => t('Fields'),
        'help' => t('Displays the fields with an optional template.'),
        'handler' => 'views_plugin_row_fields',
Earl Miles's avatar
Earl Miles committed
        'theme' => 'views_view_fields',
        'uses options' => TRUE,
Earl Miles's avatar
Earl Miles committed
        'type' => 'normal',
    'argument default' => array(
      'fixed' => array(
        'title' => t('Fixed entry'),
        'handler' => 'views_plugin_argument_default',
      ),
      'php' => array(
        'title' => t('PHP Code'),
        'handler' => 'views_plugin_argument_default_php',
      ),
    ),
    'argument validator' => array(
      'php' => array(
        'title' => t('PHP Code'),
        'handler' => 'views_plugin_argument_validate_php',
      ),
      'numeric' => array(
        'title' => t('Numeric'),
        'handler' => 'views_plugin_argument_validate_numeric',
      ),
    ),
/**
 * Builds and return a list of all plugins available in the system.
 *
 * @return Nested array of plugins, grouped by type and
 */
function views_discover_plugins() {
  $cache = array('display' => array(), 'style' => array(), 'row' => array());
  // Get plugins from all mdoules.
  foreach (module_implements('views_plugins') as $module) {
    $function = $module . '_views_plugins';
    $result = $function();
    if (!is_array($result)) {
      continue;
    }

    $module_dir = isset($result['module']) ? $result['module'] : $module;
    // Setup automatic path/file finding for theme registration
    if ($module_dir == 'views') {
      $path = drupal_get_path('module', $module_dir) . '/theme';
      $file = 'theme.inc';
    }
    else {
      $path = drupal_get_path('module', $module_dir);
      $file = "$module.views.inc";
    }
    foreach ($result as $type => $info) {
      if ($type == 'module') {
        continue;
      }
      foreach ($info as $plugin => $def) {
        $def['module'] = $module_dir;
        if (isset($def['theme']) && !isset($def['path'])) {
          $def['path'] = $path;
          $def['file'] = $file;
        }
        // merge the new data in
        $cache[$type][$plugin] = $def;
      }
    }
  }
  return $cache;
}

/**
 * Abstract base class to provide interface common to all plugins.
 */
class views_plugin extends views_object {
  /**
   * Init will be called after construct, when the plugin is attached to a
   * view and a display.
   */
  function init(&$view, &$display) {
    $this->view = &$view;
    $this->display = &$display;
  }

  /**
   * Provide a form to edit options for this plugin.
   */
  function options_form(&$form, &$form_state) { }

  /**
   * Validate the options form.
   */
  function options_validate(&$form, &$form_state) { }

  /**
   * Handle any special handling on the validate form.
   */
  function options_submit(&$form, &$form_state) { }

  /**
   * Add anything to the query that we might need to.
   */
  function query() { }

  /**
   * Provide a full list of possible theme templates used by this style.
   */
  function theme_functions() {
    return views_theme_functions($this->definition['theme'], $this->view, $this->display);
  }

  /**
   * Provide a list of additional theme functions for the theme information page
   */
  function additional_theme_functions() {
    $funcs = array();
    if (!empty($this->definition['additional themes'])) {
      foreach ($this->definition['additional themes'] as $theme) {
        $funcs[] = views_theme_functions($theme, $this->view, $this->display);
      }
    }
    return $funcs;
  }

Earl Miles's avatar
Earl Miles committed
  /**
   * Validate that the plugin is correct and can be saved.
   *
   * @return
   *   An array of error strings to tell the user what is wrong with this
   *   plugin.
   */
  function validate() { return array(); }
 * @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, such as
 * a Panels pane, or an insert view, or a CCK field type.
 *
 * @see hook_views_plugins
/**
 * The default display plugin handler. Display plugins handle options and
 * basic mechanisms for different output methods.
 */
class views_plugin_display extends views_plugin {
  function init(&$view, &$display, $options = NULL) {
    $this->view = &$view;
    $this->display = &$display;

    // Make some modifications:
    if (!isset($options)) {
      $options = $display->display_options;
    }

    if ($this->is_default_display() && isset($options['defaults'])) {
      unset($options['defaults']);
    }

    $this->unpack_options($this->options, $options);
  }

    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);
    }
  }

  /**
   * Determine if this display is the 'default' display which contains
   * fallback settings
   */
  function is_default_display() { return FALSE; }

  /**
   * Determine if this display uses exposed filters, so the view
   * will know whether or not to build them.
   */
Earl Miles's avatar
Earl Miles committed
  function uses_exposed() {
    if (!isset($this->has_exposed)) {
      foreach (array('field', 'filter') as $type) {
        foreach ($this->view->$type as $key => $handler) {
          if ($handler->is_exposed()) {
            // one is all we need; if we find it, return true.
            $this->has_exposed = TRUE;
            return TRUE;
          }
        }
      }
      $this->has_exposed = FALSE;
    }
Earl Miles's avatar
Earl Miles committed

    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
   * displayed unless uses_exposed() returns TRUE.
   */
  function displays_exposed() {
    return TRUE;
  }

  /**
   * Does the display use AJAX?
   */
  function use_ajax() {
    if (!empty($this->definition['use ajax'])) {
      return $this->get_option('use_ajax');
    }
    return FALSE;
  }

Earl Miles's avatar
Earl Miles committed
  /**
   * Does the display have a pager enabled?
   */
  function use_pager() {
    if (!empty($this->definition['use pager'])) {
      return $this->get_option('use_pager');
    }
    return FALSE;
  }

  /**
   * Does the display have a more link enabled?
   */
  function use_more() {
    if (!empty($this->definition['use more'])) {
      return $this->get_option('use_more');
    }
    return FALSE;
  }

  /**
   * Can this display accept attachments?
   */
  function accept_attachments() {
    return !empty($this->definition['accept attachments']);
  }

  /**
   * Allow displays to attach to other views.
   */
  function attach_to($display_id) { }

  /**
   * Static member function to list which sections are defaultable
   * and what items each section contains.
   */
  function defaultable_sections($section = NULL) {
    $sections = array(
      'access' => array('access'),
      'title' => array('title'),
      'header' => array('header', 'header_format', 'header_empty'),
      'footer' => array('footer', 'footer_format', 'footer_empty'),
      'empty' => array('empty', 'empty_format'),
      'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
      'use_pager' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
      'use_more' => array('use_more'),
Earl Miles's avatar
Earl Miles committed
      'link_display' => array('link_display'),
      'distinct' => array('distinct'),
      // Force these to cascade properly.
      'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
      'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
      'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
      'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
      'relationships' => array('relationships'),
      'fields' => array('fields'),
      'sorts' => array('sorts'),
      'arguments' => array('arguments'),
      'filters' => array('filters'),
    );
    if ($section) {
      if (!empty($sections[$section])) {
        return $sections[$section];
      }
    }
    else {
      return $sections;
    }
  }

  /**
   * Set default options.
   *
   * Displays put their options in a different place than everything else; also
   * displays spread their options out. We don't want to set defaults for
   * items that are normally defaulted elsewhere.
   */
  function _set_option_defaults(&$storage, $options, $level = 0) {
    foreach ($options as $option => $definition) {
      // If defaulted to elsewhere and we're not the default display, skip.
      if ($level == 0 && !$this->is_default_display() && !empty($options['defaults']['default'][$option])) {
        continue;
      }

      if (isset($definition['contains']) && is_array($definition['contains'])) {
        $storage[$option] = array();
        $this->_set_option_defaults($storage[$option], $definition['contains'], $level++);
      }
      else {
        $storage[$option] = isset($definition['default']) ? $definition['default'] : NULL;
      }
    }
  }

  function option_definition() {
    $options = array(
      'defaults' => array(
        'default' => array(
          'access' => TRUE,
          'title' => TRUE,
          'header' => TRUE,
          'header_format' => TRUE,
          'header_empty' => TRUE,
          'footer' => TRUE,
          'footer_format' => TRUE,
          'footer_empty' => TRUE,
          'empty' => TRUE,
          'empty_format' => TRUE,

          'use_ajax' => TRUE,
          'items_per_page' => TRUE,
          'offset' => TRUE,
          'use_pager' => TRUE,
          'pager_element'  => TRUE,
          'use_more' => TRUE,
          'distinct' => TRUE,

          'link_display' => TRUE,

          'style_plugin' => TRUE,
          'style_options' => TRUE,
          'row_plugin' => TRUE,
          'row_options' => TRUE,

          'relationships' => TRUE,
          'fields' => TRUE,
          'sorts' => TRUE,
          'arguments' => TRUE,
          'filters' => TRUE,
        ),
      ),
      'relationships' => array(
        'default' => array(),
        'export' => 'export_item',
      ),
      'fields' => array(
        'default' => array(),
        'export' => 'export_item',
      ),
      'sorts' => array(
        'default' => array(),
        'export' => 'export_item',
      ),
      'arguments' => array(
        'default' => array(),
        'export' => 'export_item',
      ),
      'filters' => array(
        'default' => array(),
        'export' => 'export_item',
      ),
      'access' => array(
        'contains' => array(
          'type' => array('default' => 'none'),
          'role' => array('default' => array()),
          'perm' => array('default' => ''),
         ),
      ),
      'title' => array(
        'default' => '',
        'translatable' => TRUE,
      ),
      'header' => array(
        'default' => '',
        'translatable' => TRUE,
      ),
      'header_format' => array(
        'default' => FILTER_FORMAT_DEFAULT,
      ),
      'header_empty' => array(
        'default' => FALSE,
      ),
      'footer' => array(
        'default' => '',
        'translatable' => TRUE,
      ),
      'footer_format' => array(
        'default' => FILTER_FORMAT_DEFAULT,
      ),
      'footer_empty' => array(
        'default' => FALSE,
      ),
      'empty' => array(
        'default' => '',
        'translatable' => TRUE,
      ),
      'empty_format' => array(
        'default' => FILTER_FORMAT_DEFAULT,
      ),
      'use_ajax' => array(
        'default' => FALSE,
      ),
      'items_per_page' => array(
        'default' => 10,
      ),
      'offset' => array(
        'default' => 0,
      ),
      'use_pager' => array(
        'default' => FALSE,
      ),
      'pager_element' => array(
        'default' => 0,
      ),
      'use_more' => array(
        'default' => FALSE,
      ),
      'link_display' => array(
        'default' => '',
      ),
      'distinct' => array(
        'default' => FALSE,
      ),

      'style_plugin' => array(
        'default' => 'default',
      ),
      'style_options' => array(
        'default' => array(),
      ),
      'row_plugin' => array(
        'default' => 'fields',
      ),
      'row_options' => array(
        'default' => array(),
      ),
    if ($this->is_default_display()) {
      unset($options['defaults']);
    }
    return $options;
Earl Miles's avatar
Earl Miles committed
  /**
   * 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.
   */
  function has_path() { return FALSE; }

Earl Miles's avatar
Earl Miles committed
  /**
   * 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.
   */
  function uses_link_display() { return !$this->has_path(); }

Earl Miles's avatar
Earl Miles committed
  /**
   * Check to see which display to use when creating links within
   * a view using this display.
   */
  function get_link_display() {
    $display_id = $this->get_option('link_display');
    // If unknown, pick the first one.
    if (empty($display_id) || empty($this->view->display[$display_id])) {
      foreach ($this->view->display as $display_id => $display) {
        if ($display->handler->has_path()) {
          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.
   */
  function get_path() {
    if ($this->has_path()) {
      return $this->get_option('path');
    }

    $display_id = $this->get_link_display();
    if ($display_id && !empty($this->view->display[$display_id])) {
      return $this->view->display[$display_id]->handler->get_path();
    }
  }

  /**
   * Check to see if the display needs a breadcrumb
   *
   * By default, displays do not need breadcrumbs
   */
  function uses_breadcrumb() { return FALSE; }

  /**
   * Determine if a given option is set to use the default display or the
   * current display
   *
   * @return
   *   TRUE for the default display
   */
  function is_defaulted($option) {
    return !$this->is_default_display() && !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.
   */
  function get_option($option) {
      return $this->default_display->get_option($option);
    if (array_key_exists($option, $this->options)) {
      return $this->options[$option];
  /**
   * Determine if the display's style uses fields.
   */
  function uses_fields() {
  /**
   * Get the display or row plugin, if it exists.
   */
  function get_plugin($type = 'style', $name = NULL) {
    if (!$name) {
      $name = $this->get_option($type . '_plugin');
    }

    $plugin = views_get_plugin($type, $name);
    if ($plugin) {
      $options = $this->get_option($type . '_options');
      $plugin->init($this->view, $this->display, $options);
      return $plugin;
    }
  }

  /**
   * Get the handler object for a single handler.
   */
  function &get_handler($type, $id) {
    if (!isset($this->handlers[$type])) {
      $this->get_handlers($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.
   */
  function get_handlers($type) {
    if (!isset($this->handlers[$type])) {
      $this->handlers[$type] = array();
      $types = views_object_types();
      $plural = $types[$type]['plural'];
      foreach ($this->get_option($plural) as $id => $info) {
        $handler = views_get_handler($info['table'], $info['field'], $type);
        if ($handler) {
          $handler->init($this->view, $info);
          $this->handlers[$type][$id] = &$handler;
        }

        // Prevent reference problems.
        unset($handler);
      }
    }

    return $this->handlers[$type];
  }

  /**
   * Intelligently set an option either from this display or from the
   * default display, if directed to do so.
   */
  function set_option($option, $value) {
      return $this->default_display->set_option($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.
    $this->display->display_options[$option] = $value;
    return $this->options[$option] = $value;
  /**
   * Set an option and force it to be an override.
   */
  function override_option($option, $value) {
    $this->set_override($option, FALSE);
    $this->set_option($option, $value);
  }

Earl Miles's avatar
Earl Miles committed
  /**
   * Because forms may be split up into sections, this provides
   * an easy URL to exactly the right section. Don't override this.
   */
  function option_link($text, $section, $class = '', $title = '') {
    if (!empty($class)) {
      $text = '<span>' . $text . '</span>';
    }

    if (empty($text)) {
      $text = t('Broken field');
    }

    if (empty($title)) {
      $title = $text;
    }

    return l($text, 'admin/build/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link ' . $class, 'title' => $title), 'html' => TRUE));
Earl Miles's avatar
Earl Miles committed
  }

  /**
   * Provide the default summary for options in the views UI.
Earl Miles's avatar
Earl Miles committed
   */
  function options_summary(&$categories, &$options) {
    $categories['basic'] = array(
      'title' => t('Basic settings'),
    );

    $options['display_title'] = array(
      'category' => 'basic',
      'title' => t('Name'),
      'value' => $this->display->display_title,
      'desc' => t('Change the name of this display.'),

    $title = $this->get_option('title');
    if (!$title) {
      $title = t('None');
    }

    $options['title'] = array(
      'category' => 'basic',
      'title' => t('Title'),
      'value' => $title,
      'desc' => t('Change the title that this display will use.'),

    $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
    $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title'];

    $style = '';

    $options['style_plugin'] = array(
      'category' => 'basic',
      'title' => t('Style'),
      'value' => $style_title,
    );

    // This adds a 'Settings' link to the style_options setting if the style has options.
    if (!empty($style_plugin['uses options'])) {
      $options['style_plugin']['links']['style_options'] = t('Change settings for this style');
    }

    if (!empty($style_plugin['uses row plugin'])) {
      $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
      $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin['title'];

      $options['row_plugin'] = array(
        'category' => 'basic',
        'title' => t('Row style'),
        'value' => $row_title,
      );
      // This adds a 'Settings' link to the row_options setting if the row style has options.
      if (!empty($row_plugin['uses options'])) {
        $options['row_plugin']['links']['row_options'] = t('Change settings for this style');
    if (!empty($this->definition['use ajax'])) {
      $options['use_ajax'] = array(
        'category' => 'basic',
        'title' => t('Use AJAX'),
        'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
        'desc' => t('Change whether or not this display will use AJAX.'),
    if (!empty($this->definition['use pager'])) {
      $options['use_pager'] = array(
        'category' => 'basic',
        'title' => t('Use pager'),
        'value' => $this->get_option('use_pager') ? ($this->get_option('use_pager') === 'mini' ? t('Mini') : t('Yes')) : t('No'),
        'desc' => t("Change this display's pager setting."),
Earl Miles's avatar
Earl Miles committed
    $items = intval($this->get_option('items_per_page'));
    $options['items_per_page'] = array(
      'category' => 'basic',
      'title' => $this->use_pager() ? t('Items per page') : t('Items to display'),
Earl Miles's avatar
Earl Miles committed
      'value' => $items ? $items : t('Unlimited'),
      'desc' => t('Change how many items to display.'),
    if (!empty($this->definition['use more'])) {
      $options['use_more'] = array(
        'category' => 'basic',
        'title' => t('More link'),
        'value' => $this->get_option('use_more') ? t('Yes') : t('No'),
        'desc' => t('Specify whether this display will provide a "more" link.'),
    $options['distinct'] = array(
      'category' => 'basic',
      'title' => t('Distinct'),
      'value' => $this->get_option('distinct') ? t('Yes') : t('No'),
      'desc' => t('Display only distinct items, without duplicates.'),
    );

    // @todo -- this should be no longer necessary
    if (!is_array($access)) {
      $access = array('type' => 'none');
    }
    switch($access['type']) {
      case 'none':
      default:
        $access_str = t('Unrestricted');
        break;
      case 'perm':
        $access_str = $access['perm'];
        break;
      case 'role':
        $roles = array_keys(array_filter($access['role']));
        if (count($roles) > 1) {
          $access_str = t('Multiple roles');
        }
        else {
          $rids = views_ui_get_roles();
          $rid = array_shift($roles);
          $access_str = $rids[$rid];
        }
        break;
    }

    $options['access'] = array(
      'category' => 'basic',
      'title' => t('Access'),
      'value' => $access_str,
      'desc' => t('Specify access control settings for this display.'),
Earl Miles's avatar
Earl Miles committed
    if ($this->uses_link_display()) {
Earl Miles's avatar
Earl Miles committed
      // Only show the 'link display' if there is more than one option.
      $count = 0;
      foreach ($this->view->display as $display_id => $display) {
        if ($display->handler->has_path()) {
          $count++;
        }
        if ($count > 1) {
          break;
        }
      }

      if ($count > 1) {
        $display_id = $this->get_link_display();
        $link_display = empty($this->view->display[$display_id]) ? t('None') : $this->view->display[$display_id]->display_title;
        $options['link_display'] = array(
          'category' => 'basic',
          'title' => t('Link display'),
          'value' => $link_display,
          'desc' => t('Specify which display this display will link to.'),
    foreach (array('header' => t('Header'), 'footer' => t('Footer'), 'empty' => t('Empty text')) as $type => $name) {
      if (!$this->get_option($type)) {
        $field = t('None');
      }
      else {
        // A lot of code to get the name of the filter format.
        $fmt_string = $this->get_option($type . '_format');
        if (empty($fmt_string)) {
          $fmt_string = FILTER_FORMAT_DEFAULT;
        }
        $format_val = filter_resolve_format($fmt_string);
        $format = filter_formats($format_val);
        if ($format) {
          $field = $format->name;
        }
        else {
          $field = t('Unknown/missing filter');
        }
      $options[$type] = array(
        'category' => 'basic',