plugins/views_plugin_display.inc

Go to the documentation of this file.
00001 <?php
00002 // $Id: views_plugin_display.inc,v 1.27.2.6 2009/11/30 19:05:47 merlinofchaos Exp $
00027 class views_plugin_display extends views_plugin {
00028   var $handlers = array();
00029 
00030   function init(&$view, &$display, $options = NULL) {
00031     $this->view = &$view;
00032     $this->display = &$display;
00033 
00034     // Make some modifications:
00035     if (!isset($options)) {
00036       $options = $display->display_options;
00037     }
00038 
00039     if ($this->is_default_display() && isset($options['defaults'])) {
00040       unset($options['defaults']);
00041     }
00042 
00043     $this->unpack_options($this->options, $options);
00044   }
00045 
00046   function destroy() {
00047     parent::destroy();
00048 
00049     foreach ($this->handlers as $type => $handlers) {
00050       foreach ($handlers as $id => $handler) {
00051         if (is_object($handler)) {
00052           $this->handlers[$type][$id]->destroy();
00053         }
00054       }
00055     }
00056 
00057     if (isset($this->default_display)) {
00058       unset($this->default_display);
00059     }
00060   }
00061 
00066   function is_default_display() { return FALSE; }
00067 
00072   function uses_exposed() {
00073     if (!isset($this->has_exposed)) {
00074       foreach (array('field', 'filter') as $type) {
00075         foreach ($this->view->$type as $key => $handler) {
00076           if ($handler->is_exposed()) {
00077             // one is all we need; if we find it, return true.
00078             $this->has_exposed = TRUE;
00079             return TRUE;
00080           }
00081         }
00082       }
00083       $this->has_exposed = FALSE;
00084     }
00085 
00086     return $this->has_exposed;
00087   }
00088 
00098   function displays_exposed() {
00099     return TRUE;
00100   }
00101 
00105   function use_ajax() {
00106     if (!empty($this->definition['use ajax'])) {
00107       return $this->get_option('use_ajax');
00108     }
00109     return FALSE;
00110   }
00111 
00115   function use_pager() {
00116     if (!empty($this->definition['use pager'])) {
00117       return $this->get_option('use_pager');
00118     }
00119     return FALSE;
00120   }
00121 
00125   function render_pager() {
00126     return $this->use_pager();
00127   }
00128 
00132   function use_more() {
00133     if (!empty($this->definition['use more'])) {
00134       return $this->get_option('use_more');
00135     }
00136     return FALSE;
00137   }
00138 
00142   function use_more_always() {
00143     if (!empty($this->definition['use more'])) {
00144       return $this->get_option('use_more_always');
00145     }
00146     return FALSE;
00147   }
00148 
00152   function use_more_text() {
00153     if (!empty($this->definition['use more'])) {
00154       return $this->get_option('use_more_text');
00155     }
00156     return FALSE;
00157   }
00158 
00162   function accept_attachments() {
00163     return !empty($this->definition['accept attachments']);
00164   }
00165 
00169   function attach_to($display_id) { }
00170 
00175   function defaultable_sections($section = NULL) {
00176     $sections = array(
00177       'access' => array('access'),
00178       'cache' => array('cache'),
00179       'title' => array('title'),
00180       'header' => array('header', 'header_format', 'header_empty'),
00181       'footer' => array('footer', 'footer_format', 'footer_empty'),
00182       'empty' => array('empty', 'empty_format'),
00183       'use_ajax' => array('use_ajax'),
00184       'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
00185       'use_pager' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
00186       'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
00187       'link_display' => array('link_display'),
00188       'distinct' => array('distinct'),
00189       'exposed_block' => array('exposed_block'),
00190 
00191       // Force these to cascade properly.
00192       'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00193       'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00194       'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00195       'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00196 
00197       // These guys are special
00198       'relationships' => array('relationships'),
00199       'fields' => array('fields'),
00200       'sorts' => array('sorts'),
00201       'arguments' => array('arguments'),
00202       'filters' => array('filters'),
00203     );
00204     if ($section) {
00205       if (!empty($sections[$section])) {
00206         return $sections[$section];
00207       }
00208     }
00209     else {
00210       return $sections;
00211     }
00212   }
00213 
00221   function _set_option_defaults(&$storage, $options, $level = 0) {
00222     foreach ($options as $option => $definition) {
00223       // If defaulted to elsewhere and we're not the default display, skip.
00224       if ($level == 0 && !$this->is_default_display() && !empty($options['defaults']['default'][$option])) {
00225         continue;
00226       }
00227 
00228       if (isset($definition['contains']) && is_array($definition['contains'])) {
00229         $storage[$option] = array();
00230         $this->_set_option_defaults($storage[$option], $definition['contains'], $level++);
00231       }
00232       else {
00233         $storage[$option] = isset($definition['default']) ? $definition['default'] : NULL;
00234       }
00235     }
00236   }
00237 
00238   function option_definition() {
00239     $options = array(
00240       'defaults' => array(
00241         'default' => array(
00242           'access' => TRUE,
00243           'cache' => TRUE,
00244           'title' => TRUE,
00245           'header' => TRUE,
00246           'header_format' => TRUE,
00247           'header_empty' => TRUE,
00248           'footer' => TRUE,
00249           'footer_format' => TRUE,
00250           'footer_empty' => TRUE,
00251           'empty' => TRUE,
00252           'empty_format' => TRUE,
00253 
00254           'use_ajax' => TRUE,
00255           'items_per_page' => TRUE,
00256           'offset' => TRUE,
00257           'use_pager' => TRUE,
00258           'pager_element'  => TRUE,
00259           'use_more' => TRUE,
00260           'use_more_always' => TRUE,
00261           'use_more_text' => TRUE,
00262           'distinct' => TRUE,
00263           'exposed_block' => TRUE,
00264 
00265           'link_display' => TRUE,
00266 
00267           'style_plugin' => TRUE,
00268           'style_options' => TRUE,
00269           'row_plugin' => TRUE,
00270           'row_options' => TRUE,
00271 
00272           'relationships' => TRUE,
00273           'fields' => TRUE,
00274           'sorts' => TRUE,
00275           'arguments' => TRUE,
00276           'filters' => TRUE,
00277         ),
00278       ),
00279       'relationships' => array(
00280         'default' => array(),
00281         'export' => 'export_item',
00282       ),
00283       'fields' => array(
00284         'default' => array(),
00285         'export' => 'export_item',
00286       ),
00287       'sorts' => array(
00288         'default' => array(),
00289         'export' => 'export_item',
00290       ),
00291       'arguments' => array(
00292         'default' => array(),
00293         'export' => 'export_item',
00294       ),
00295       'filters' => array(
00296         'default' => array(),
00297         'export' => 'export_item',
00298       ),
00299       'access' => array(
00300         'contains' => array(
00301           'type' => array('default' => 'none'),
00302          ),
00303       ),
00304       'cache' => array(
00305         'contains' => array(
00306           'type' => array('default' => 'none'),
00307          ),
00308       ),
00309       'title' => array(
00310         'default' => '',
00311         'translatable' => TRUE,
00312       ),
00313       'header' => array(
00314         'default' => '',
00315         'translatable' => TRUE,
00316       ),
00317       'header_format' => array(
00318         'default' => FILTER_FORMAT_DEFAULT,
00319       ),
00320       'header_empty' => array(
00321         'default' => FALSE,
00322       ),
00323       'footer' => array(
00324         'default' => '',
00325         'translatable' => TRUE,
00326       ),
00327       'footer_format' => array(
00328         'default' => FILTER_FORMAT_DEFAULT,
00329       ),
00330       'footer_empty' => array(
00331         'default' => FALSE,
00332       ),
00333       'empty' => array(
00334         'default' => '',
00335         'translatable' => TRUE,
00336       ),
00337       'empty_format' => array(
00338         'default' => FILTER_FORMAT_DEFAULT,
00339       ),
00340       'use_ajax' => array(
00341         'default' => FALSE,
00342       ),
00343       'items_per_page' => array(
00344         'default' => 10,
00345       ),
00346       'offset' => array(
00347         'default' => 0,
00348       ),
00349       'use_pager' => array(
00350         'default' => FALSE,
00351       ),
00352       'pager_element' => array(
00353         'default' => 0,
00354       ),
00355       'use_more' => array(
00356         'default' => FALSE,
00357       ),
00358       'use_more_always' => array(
00359         'default' => FALSE,
00360       ),
00361       'use_more_text' => array(
00362         'default' => 'more',
00363         'translatable' => TRUE,
00364       ),
00365       'link_display' => array(
00366         'default' => '',
00367       ),
00368       'distinct' => array(
00369         'default' => FALSE,
00370       ),
00371 
00372       'style_plugin' => array(
00373         'default' => 'default',
00374       ),
00375       'style_options' => array(
00376         'default' => array(),
00377       ),
00378       'row_plugin' => array(
00379         'default' => 'fields',
00380       ),
00381       'row_options' => array(
00382         'default' => array(),
00383       ),
00384 
00385       'exposed_block' => array(
00386         'default' => FALSE,
00387       ),
00388     );
00389 
00390     if ($this->is_default_display()) {
00391       unset($options['defaults']);
00392     }
00393     return $options;
00394   }
00395 
00405   function has_path() { return FALSE; }
00406 
00414   function uses_link_display() { return !$this->has_path(); }
00415 
00420   function get_link_display() {
00421     $display_id = $this->get_option('link_display');
00422     // If unknown, pick the first one.
00423     if (empty($display_id) || empty($this->view->display[$display_id])) {
00424       foreach ($this->view->display as $display_id => $display) {
00425         if (!empty($display->handler) && $display->handler->has_path()) {
00426           return $display_id;
00427         }
00428       }
00429     }
00430     else {
00431       return $display_id;
00432     }
00433     // fall-through returns NULL
00434   }
00435 
00442   function get_path() {
00443     if ($this->has_path()) {
00444       return $this->get_option('path');
00445     }
00446 
00447     $display_id = $this->get_link_display();
00448     if ($display_id && !empty($this->view->display[$display_id]) && is_object($this->view->display[$display_id]->handler)) {
00449       return $this->view->display[$display_id]->handler->get_path();
00450     }
00451   }
00452 
00458   function uses_breadcrumb() { return FALSE; }
00459 
00467   function is_defaulted($option) {
00468     return !$this->is_default_display() && !empty($this->default_display) && !empty($this->options['defaults'][$option]);
00469   }
00470 
00475   function get_option($option) {
00476     if ($this->is_defaulted($option)) {
00477       return $this->default_display->get_option($option);
00478     }
00479 
00480     if (array_key_exists($option, $this->options)) {
00481       return $this->options[$option];
00482     }
00483   }
00484 
00488   function uses_fields() {
00489     $plugin = $this->get_plugin();
00490     if ($plugin) {
00491       return $plugin->uses_fields();
00492     }
00493   }
00494 
00498   function get_plugin($type = 'style', $name = NULL) {
00499     if (!$name) {
00500       $name = $this->get_option($type . '_plugin');
00501     }
00502 
00503     $plugin = views_get_plugin($type, $name);
00504     if ($plugin) {
00505       $options = $this->get_option($type . '_options');
00506       $plugin->init($this->view, $this->display, $options);
00507       return $plugin;
00508     }
00509   }
00510 
00514   function get_access_plugin($name = NULL) {
00515     if (!$name) {
00516       $access = $this->get_option('access');
00517       $name = $access['type'];
00518     }
00519 
00520     $plugin = views_get_plugin('access', $name);
00521     if ($plugin) {
00522       $plugin->init($this->view, $this->display);
00523       return $plugin;
00524     }
00525   }
00526 
00530   function get_cache_plugin($name = NULL) {
00531     if (!$name) {
00532       $cache = $this->get_option('cache');
00533       $name = $cache['type'];
00534     }
00535 
00536     $plugin = views_get_plugin('cache', $name);
00537     if ($plugin) {
00538       $plugin->init($this->view, $this->display);
00539       return $plugin;
00540     }
00541   }
00542 
00546   function &get_handler($type, $id) {
00547     if (!isset($this->handlers[$type])) {
00548       $this->get_handlers($type);
00549     }
00550 
00551     if (isset($this->handlers[$type][$id])) {
00552       return $this->handlers[$type][$id];
00553     }
00554 
00555     // So we can return a reference.
00556     $null = NULL;
00557     return $null;
00558   }
00559 
00563   function get_handlers($type) {
00564     if (!isset($this->handlers[$type])) {
00565       $this->handlers[$type] = array();
00566       $types = views_object_types();
00567       $plural = $types[$type]['plural'];
00568       foreach ($this->get_option($plural) as $id => $info) {
00569         $handler = views_get_handler($info['table'], $info['field'], $type);
00570         if ($handler) {
00571           $handler->init($this->view, $info);
00572           $this->handlers[$type][$id] = &$handler;
00573         }
00574 
00575         // Prevent reference problems.
00576         unset($handler);
00577       }
00578     }
00579 
00580     return $this->handlers[$type];
00581   }
00582 
00587   function set_option($option, $value) {
00588     if ($this->is_defaulted($option)) {
00589       return $this->default_display->set_option($option, $value);
00590     }
00591 
00592     // Set this in two places: On the handler where we'll notice it
00593     // but also on the display object so it gets saved. This should
00594     // only be a temporary fix.
00595     $this->display->display_options[$option] = $value;
00596     return $this->options[$option] = $value;
00597   }
00598 
00602   function override_option($option, $value) {
00603     $this->set_override($option, FALSE);
00604     $this->set_option($option, $value);
00605   }
00606 
00611   function option_link($text, $section, $class = '', $title = '') {
00612     if (!empty($class)) {
00613       $text = '<span>' . $text . '</span>';
00614     }
00615 
00616     if (!trim($text)) {
00617       $text = t('Broken field');
00618     }
00619 
00620     if (empty($title)) {
00621       $title = $text;
00622     }
00623 
00624     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));
00625   }
00626 
00632   function options_summary(&$categories, &$options) {
00633     $categories['basic'] = array(
00634       'title' => t('Basic settings'),
00635     );
00636 
00637     $options['display_title'] = array(
00638       'category' => 'basic',
00639       'title' => t('Name'),
00640       'value' => check_plain($this->display->display_title),
00641       'desc' => t('Change the name of this display.'),
00642     );
00643 
00644     $title = strip_tags($this->get_option('title'));
00645     if (!$title) {
00646       $title = t('None');
00647     }
00648 
00649     $options['title'] = array(
00650       'category' => 'basic',
00651       'title' => t('Title'),
00652       'value' => $title,
00653       'desc' => t('Change the title that this display will use.'),
00654     );
00655 
00656     $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
00657     $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title'];
00658 
00659     $style = '';
00660 
00661     $options['style_plugin'] = array(
00662       'category' => 'basic',
00663       'title' => t('Style'),
00664       'value' => $style_title,
00665       'desc' => t('Change the style plugin.'),
00666     );
00667 
00668     // This adds a 'Settings' link to the style_options setting if the style has options.
00669     if (!empty($style_plugin['uses options'])) {
00670       $options['style_plugin']['links']['style_options'] = t('Change settings for this style');
00671     }
00672 
00673     if (!empty($style_plugin['uses row plugin'])) {
00674       $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
00675       $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin['title'];
00676 
00677       $options['row_plugin'] = array(
00678         'category' => 'basic',
00679         'title' => t('Row style'),
00680         'value' => $row_title,
00681         'desc' => t('Change the row plugin.'),
00682       );
00683       // This adds a 'Settings' link to the row_options setting if the row style has options.
00684       if (!empty($row_plugin['uses options'])) {
00685         $options['row_plugin']['links']['row_options'] = t('Change settings for this style');
00686       }
00687     }
00688     if (!empty($this->definition['use ajax'])) {
00689       $options['use_ajax'] = array(
00690         'category' => 'basic',
00691         'title' => t('Use AJAX'),
00692         'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
00693         'desc' => t('Change whether or not this display will use AJAX.'),
00694       );
00695     }
00696 
00697     if (!empty($this->definition['use pager'])) {
00698       $options['use_pager'] = array(
00699         'category' => 'basic',
00700         'title' => t('Use pager'),
00701         'value' => $this->get_option('use_pager') ? ($this->get_option('use_pager') === 'mini' ? t('Mini') : t('Yes')) : t('No'),
00702         'desc' => t("Change this display's pager setting."),
00703       );
00704     }
00705 
00706     $items = intval($this->get_option('items_per_page'));
00707     $options['items_per_page'] = array(
00708       'category' => 'basic',
00709       'title' => $this->use_pager() ? t('Items per page') : t('Items to display'),
00710       'value' => $items ? $items : t('Unlimited'),
00711       'desc' => t('Change how many items to display.'),
00712     );
00713 
00714     if (!empty($this->definition['use more'])) {
00715       $options['use_more'] = array(
00716         'category' => 'basic',
00717         'title' => t('More link'),
00718         'value' => $this->get_option('use_more') ? t('Yes') : t('No'),
00719         'desc' => t('Specify whether this display will provide a "more" link.'),
00720       );
00721     }
00722 
00723     $options['distinct'] = array(
00724       'category' => 'basic',
00725       'title' => t('Distinct'),
00726       'value' => $this->get_option('distinct') ? t('Yes') : t('No'),
00727       'desc' => t('Display only distinct items, without duplicates.'),
00728     );
00729 
00730     $access_plugin = $this->get_access_plugin();
00731     if (!$access_plugin) {
00732       // default to the no access control plugin.
00733       $access_plugin = views_get_plugin('access', 'none');
00734     }
00735 
00736     $access_str = $access_plugin->summary_title();
00737 
00738     $options['access'] = array(
00739       'category' => 'basic',
00740       'title' => t('Access'),
00741       'value' => $access_str,
00742       'desc' => t('Specify access control type for this display.'),
00743     );
00744 
00745     if (!empty($access_plugin->definition['uses options'])) {
00746       $options['access']['links']['access_options'] = t('Change settings for this access type.');
00747     }
00748 
00749     $cache_plugin = $this->get_cache_plugin();
00750     if (!$cache_plugin) {
00751       // default to the no cache control plugin.
00752       $cache_plugin = views_get_plugin('cache', 'none');
00753     }
00754 
00755     $cache_str = $cache_plugin->summary_title();
00756 
00757     $options['cache'] = array(
00758       'category' => 'basic',
00759       'title' => t('Caching'),
00760       'value' => $cache_str,
00761       'desc' => t('Specify caching type for this display.'),
00762     );
00763 
00764     if (!empty($cache_plugin->definition['uses options'])) {
00765       $options['cache']['links']['cache_options'] = t('Change settings for this caching type.');
00766     }
00767 
00768     if ($this->uses_link_display()) {
00769       // Only show the 'link display' if there is more than one option.
00770       $count = 0;
00771       foreach ($this->view->display as $display_id => $display) {
00772         if (is_object($display->handler) && $display->handler->has_path()) {
00773           $count++;
00774         }
00775         if ($count > 1) {
00776           break;
00777         }
00778       }
00779 
00780       if ($count > 1) {
00781         $display_id = $this->get_link_display();
00782         $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title);
00783         $options['link_display'] = array(
00784           'category' => 'basic',
00785           'title' => t('Link display'),
00786           'value' => $link_display,
00787           'desc' => t('Specify which display this display will link to.'),
00788         );
00789       }
00790     }
00791 
00792     $options['exposed_block'] = array(
00793       'category' => 'basic',
00794       'title' => t('Exposed form in block'),
00795       'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'),
00796       'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
00797     );
00798 
00799     foreach (array('header' => t('Header'), 'footer' => t('Footer'), 'empty' => t('Empty text')) as $type => $name) {
00800       if (!$this->get_option($type)) {
00801         $field = t('None');
00802       }
00803       else {
00804         // A lot of code to get the name of the filter format.
00805         $fmt_string = $this->get_option($type . '_format');
00806         if (empty($fmt_string)) {
00807           $fmt_string = FILTER_FORMAT_DEFAULT;
00808         }
00809         $format_val = filter_resolve_format($fmt_string);
00810         $format = filter_formats($format_val);
00811         if ($format) {
00812           $field = check_plain($format->name);
00813         }
00814         else {
00815           $field = t('Unknown/missing format');
00816         }
00817       }
00818 
00819       $options[$type] = array(
00820         'category' => 'basic',
00821         'title' => $name,
00822         'value' => $field,
00823         'desc' => t("Change this display's !name.", array('!name' => strtolower($name))),
00824       );
00825     }
00826 
00827     $options['analyze-theme'] = array(
00828       'category' => 'basic',
00829       'title' => t('Theme'),
00830       'value' => t('Information'),
00831       'desc' => t('Get information on how to theme this display'),
00832     );
00833   }
00834 
00838   function options_form(&$form, &$form_state) {
00839     if ($this->defaultable_sections($form_state['section'])) {
00840       $this->add_override_button($form, $form_state, $form_state['section']);
00841     }
00842     $form['#title'] = check_plain($this->display->display_title) . ': ';
00843 
00844     // Set the 'section' to hilite on the form.
00845     // If it's the item we're looking at is pulling from the default display,
00846     // reflect that. Don't use is_defaulted since we want it to show up even
00847     // on the default display.
00848     if (!empty($this->options['defaults'][$form_state['section']])) {
00849       $form['#section'] = 'default-' . $form_state['section'];
00850     }
00851     else {
00852       $form['#section'] = $this->display->id . '-' . $form_state['section'];
00853     }
00854 
00855     switch ($form_state['section']) {
00856       case 'display_title':
00857         $form['#title'] .= t('The name of this display');
00858         $form['display_title'] = array(
00859           '#type' => 'textfield',
00860           '#description' => t('This title will appear only in the administrative interface for the View.'),
00861           '#default_value' => $this->display->display_title,
00862         );
00863         break;
00864       case 'title':
00865         $form['#title'] .= t('The title of this view');
00866         $form['title'] = array(
00867           '#type' => 'textfield',
00868           '#description' => t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'),
00869           '#default_value' => $this->get_option('title'),
00870         );
00871         break;
00872       case 'use_ajax':
00873         $form['#title'] .= t('Use AJAX when available to load this view');
00874         $form['description'] = array(
00875           '#prefix' => '<div class="description form-item">',
00876           '#suffix' => '</div>',
00877           '#value' => t('If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content.'),
00878         );
00879         $form['use_ajax'] = array(
00880           '#type' => 'radios',
00881           '#options' => array(1 => t('Yes'), 0 => t('No')),
00882           '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
00883         );
00884         break;
00885       case 'use_pager':
00886         $form['#title'] .= t('Use a pager for this view');
00887         $form['use_pager'] = array(
00888           '#type' => 'radios',
00889           '#options' => array(TRUE => t('Full pager'), 'mini' => t('Mini pager'), 0 => t('No')),
00890           '#default_value' => $this->get_option('use_pager'),
00891         );
00892         $form['pager_element'] = array(
00893           '#type' => 'textfield',
00894           '#title' => t('Pager element'),
00895           '#description' => t("Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."),
00896           '#default_value' => intval($this->get_option('pager_element')),
00897         );
00898         break;
00899       case 'items_per_page':
00900         $form['#title'] .= $this->use_pager() ? t('Items per page') : t('Items to display');
00901 
00902         $form['items_per_page'] = array(
00903           '#type' => 'textfield',
00904           '#description' => t('The number of items to display per page. Enter 0 for no limit.'),
00905           '#default_value' => intval($this->get_option('items_per_page')),
00906         );
00907         $form['offset'] = array(
00908           '#type' => 'textfield',
00909           '#title' => t('Offset'),
00910           '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there.'),
00911           '#default_value' => intval($this->get_option('offset')),
00912         );
00913         break;
00914       case 'use_more':
00915         $form['#title'] .= t('Add a more link to the bottom of the display.');
00916         $form['use_more'] = array(
00917           '#type' => 'checkbox',
00918           '#title' => t('Create more link'),
00919           '#description' => t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above."),
00920           '#default_value' => $this->get_option('use_more'),
00921         );
00922         $form['use_more_always'] = array(
00923           '#type' => 'checkbox',
00924           '#title' => t('Always display more link'),
00925           '#description' => t("This will display the more link even if there are no more items to display."),
00926           '#default_value' => $this->get_option('use_more_always'),
00927         );
00928         $form['#title'] .= t('Text to use for the more link.');
00929         $form['use_more_text'] = array(
00930           '#type' => 'textfield',
00931           '#title' => t('More link text'),
00932           '#description' => t("The text to display for the more link."),
00933           '#default_value' => $this->get_option('use_more_text'),
00934         );
00935         break;
00936       case 'distinct':
00937         $form['#title'] .= t('Display only distinct items, without duplicates.');
00938         $form['distinct'] = array(
00939           '#type' => 'checkbox',
00940           '#title' => t('Distinct'),
00941           '#description' => t('This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution.'),
00942           '#default_value' => $this->get_option('distinct'),
00943         );
00944         break;
00945       case 'access':
00946         $form['#title'] .= t('Access restrictions');
00947         $form['access'] = array(
00948           '#prefix' => '<div class="clear-block">',
00949           '#suffix' => '</div>',
00950           '#tree' => TRUE,
00951         );
00952 
00953         $access = $this->get_option('access');
00954         $form['access']['type'] =  array(
00955           '#type' => 'radios',
00956           '#options' => views_fetch_plugin_names('access'),
00957           '#default_value' => $access['type'],
00958         );
00959 
00960         $access_plugin = views_fetch_plugin_data('access', $access['type']);
00961         if (!empty($access_plugin['uses options'])) {
00962           $form['markup'] = array(
00963             '#prefix' => '<div class="form-item description">',
00964             '#suffix' => '</div>',
00965             '#value' => t('You may also adjust the !settings for the currently selected access restriction by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'access_options'))),
00966           );
00967         }
00968 
00969         break;
00970       case 'access_options':
00971         $access = $this->get_option('access');
00972         $plugin = $this->get_access_plugin();
00973         $form['#title'] .= t('Access options');
00974         if ($plugin) {
00975           $form['#help_topic'] = $plugin->definition['help topic'];
00976           $form['#help_module'] = $plugin->definition['module'];
00977 
00978           $form['access_options'] = array(
00979             '#tree' => TRUE,
00980           );
00981           $form['access_options']['type'] = array(
00982             '#type' => 'value',
00983             '#value' => $access['type'],
00984           );
00985           $plugin->options_form($form['access_options'], $form_state);
00986         }
00987         break;
00988       case 'cache':
00989         $form['#title'] .= t('Caching');
00990         $form['cache'] = array(
00991           '#prefix' => '<div class="clear-block">',
00992           '#suffix' => '</div>',
00993           '#tree' => TRUE,
00994         );
00995 
00996         $cache = $this->get_option('cache');
00997         $form['cache']['type'] =  array(
00998           '#type' => 'radios',
00999           '#options' => views_fetch_plugin_names('cache'),
01000           '#default_value' => $cache['type'],
01001         );
01002 
01003         $cache_plugin = views_fetch_plugin_data('cache', $cache['type']);
01004         if (!empty($cache_plugin['uses options'])) {
01005           $form['markup'] = array(
01006             '#prefix' => '<div class="form-item description">',
01007             '#suffix' => '</div>',
01008             '#value' => t('You may also adjust the !settings for the currently selected cache mechanism by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))),
01009           );
01010         }
01011         break;
01012       case 'cache_options':
01013         $cache = $this->get_option('cache');
01014         $plugin = $this->get_cache_plugin();
01015         $form['#title'] .= t('Caching options');
01016         if ($plugin) {
01017           $form['#help_topic'] = $plugin->definition['help topic'];
01018           $form['#help_module'] = $plugin->definition['module'];
01019 
01020           $form['cache_options'] = array(
01021             '#tree' => TRUE,
01022           );
01023           $form['cache_options']['type'] = array(
01024             '#type' => 'value',
01025             '#value' => $cache['type'],
01026           );
01027           $plugin->options_form($form['cache_options'], $form_state);
01028         }
01029         break;
01030       case 'header':
01031         $form['#title'] .= t('Header');
01032         $form['header_empty'] = array(
01033           '#type' => 'checkbox',
01034           '#title' => t('Display even if view has no result'),
01035           '#default_value' => $this->get_option('header_empty'),
01036         );
01037         $form['header'] = array(
01038           '#type' => 'textarea',
01039           '#default_value' => $this->get_option('header'),
01040           '#rows' => 6,
01041           '#description' => t('Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional.'),
01042         );
01043 
01044         $form['header_format'] = filter_form($this->get_option('header_format'), NULL, array('header_format'));
01045         break;
01046       case 'footer':
01047         $form['#title'] .= t('Footer');
01048         $form['footer_empty'] = array(
01049           '#type' => 'checkbox',
01050           '#title' => t('Display even if view has no result'),
01051           '#default_value' => $this->get_option('footer_empty'),
01052         );
01053         $form['footer'] = array(
01054           '#type' => 'textarea',
01055           '#default_value' => $this->get_option('footer'),
01056           '#rows' => 6,
01057           '#description' => t('Text to display beneath the view. May contain an explanation or links or whatever you like. Optional.'),
01058         );
01059 
01060         $form['footer_format'] = filter_form($this->get_option('footer_format'), NULL, array('footer_format'));
01061         break;
01062       case 'empty':
01063         $form['#title'] .= t('Empty text');
01064         $form['empty'] = array(
01065           '#type' => 'textarea',
01066           '#default_value' => $this->get_option('empty'),
01067           '#rows' => 6,
01068           '#description' => t('Text to display if the view has no results. Optional.'),
01069         );
01070 
01071         $form['empty_format'] = filter_form($this->get_option('empty_format'), NULL, array('empty_format'));
01072         break;
01073       case 'style_plugin':
01074         $form['#title'] .= t('How should this view be styled');
01075         $form['#help_topic'] = 'style';
01076         $form['style_plugin'] =  array(
01077           '#type' => 'radios',
01078           '#options' => views_fetch_plugin_names('style', $this->get_style_type(), array($this->view->base_table)),
01079           '#default_value' => $this->get_option('style_plugin'),
01080           '#description' => t('If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary.'),
01081         );
01082 
01083         $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
01084         if (!empty($style_plugin['uses options'])) {
01085           $form['markup'] = array(
01086             '#prefix' => '<div class="form-item description">',
01087             '#suffix' => '</div>',
01088             '#value' => t('You may also adjust the !settings for the currently selected style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'style_options'))),
01089           );
01090         }
01091 
01092         break;
01093       case 'style_options':
01094         $form['#title'] .= t('Style options');
01095         $style = TRUE;
01096         $type = 'style_plugin';
01097         $name = $this->get_option('style_plugin');
01098 
01099       case 'row_options':
01100         if (!isset($name)) {
01101           $name = $this->get_option('row_plugin');
01102         }
01103         // if row, $style will be empty.
01104         if (empty($style)) {
01105           $form['#title'] .= t('Row style options');
01106           $type = 'row_plugin';
01107         }
01108         $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
01109         if ($plugin) {
01110           if (isset($plugin->definition['help topic'])) {
01111             $form['#help_topic'] = $plugin->definition['help topic'];
01112             $form['#help_module'] = $plugin->definition['module'];
01113           }
01114           $form[$form_state['section']] = array(
01115             '#tree' => TRUE,
01116           );
01117           $plugin->options_form($form[$form_state['section']], $form_state);
01118         }
01119         break;
01120       case 'row_plugin':
01121         $form['#title'] .= t('How should each row in this view be styled');
01122         $form['#help_topic'] = 'style-row';
01123         $form['row_plugin'] =  array(
01124           '#type' => 'radios',
01125           '#options' => views_fetch_plugin_names('row', $this->get_style_type(), array($this->view->base_table)),
01126           '#default_value' => $this->get_option('row_plugin'),
01127         );
01128 
01129         $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
01130         if (!empty($row_plugin['uses options'])) {
01131           $form['markup'] = array(
01132             '#prefix' => '<div class="form-item description">',
01133             '#suffix' => '</div>',
01134             '#value' => t('You may also adjust the !settings for the currently selected row style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'row_options'))),
01135           );
01136         }
01137 
01138         break;
01139       case 'link_display':
01140         $form['#title'] .= t('Which display to use for path');
01141         foreach ($this->view->display as $display_id => $display) {
01142           if ($display->handler->has_path()) {
01143             $options[$display_id] = $display->display_title;
01144           }
01145         }
01146         $form['link_display'] = array(
01147           '#type' => 'radios',
01148           '#options' => $options,
01149           '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
01150           '#default_value' => $this->get_link_display(),
01151         );
01152         break;
01153       case 'analyze-theme':
01154         $form['#title'] .= t('Theming information');
01155         $form['#help_topic'] = 'analyze-theme';
01156 
01157         if (isset($_POST['theme'])) {
01158           $this->view->theme = $_POST['theme'];
01159         }
01160         else if (empty($this->view->theme)) {
01161           $this->view->theme = variable_get('theme_default', 'garland');
01162         }
01163 
01164         global $custom_theme;
01165         $custom_theme = $this->view->theme;
01166         init_theme();
01167 
01168         $funcs = array();
01169         // Get theme functions for the display. Note that some displays may
01170         // not have themes. The 'feed' display, for example, completely
01171         // delegates to the style.
01172         if (!empty($this->definition['theme'])) {
01173           $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': '  . $this->format_themes($this->theme_functions());
01174           $themes = $this->additional_theme_functions();
01175           if ($themes) {
01176             foreach ($themes as $theme) {
01177               $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': '  . $this->format_themes($theme);
01178             }
01179           }
01180         }
01181 
01182         $plugin = $this->get_plugin();
01183         if ($plugin) {
01184           $funcs[] = $this->option_link(t('Style output'), 'analyze-theme-style') . ': ' . $this->format_themes($plugin->theme_functions(), $plugin->additional_theme_functions());
01185           $themes = $plugin->additional_theme_functions();
01186           if ($themes) {
01187             foreach ($themes as $theme) {
01188               $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': '  . $this->format_themes($theme);
01189             }
01190           }
01191 
01192           if ($plugin->uses_row_plugin()) {
01193             $row_plugin = $this->get_plugin('row');
01194             if ($row_plugin) {
01195               $funcs[] = $this->option_link(t('Row style output'), 'analyze-theme-row') . ': ' . $this->format_themes($row_plugin->theme_functions());
01196               $themes = $row_plugin->additional_theme_functions();
01197               if ($themes) {
01198                 foreach ($themes as $theme) {
01199                   $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': '  . $this->format_themes($theme);
01200                 }
01201               }
01202             }
01203           }
01204 
01205           if ($plugin->uses_fields()) {
01206             foreach ($this->get_handlers('field') as $id => $handler) {
01207               $funcs[] = $this->option_link(t('Field @field (ID: @id)', array('@field' => $handler->ui_name(), '@id' => $id)), 'analyze-theme-field') . ': ' . $this->format_themes($handler->theme_functions());
01208             }
01209           }
01210         }
01211 
01212         $form['important'] = array(
01213           '#prefix' => '<div class="form-item description">',
01214           '#suffix' => '</div>',
01215           '#value' => '<p>' . t('This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold.') . '</p>',
01216         );
01217 
01218         foreach (list_themes() as $key => $theme) {
01219           $options[$key] = $theme->info['name'];
01220         }
01221 
01222         $form['box'] = array(
01223           '#prefix' => '<div class="container-inline">',
01224           '#suffix' => '</div>',
01225         );
01226         $form['box']['theme'] = array(
01227           '#type' => 'select',
01228           '#options' => $options,
01229           '#default_value' => $this->view->theme,
01230         );
01231 
01232         $form['box']['change'] = array(
01233           '#type' => 'submit',
01234           '#value' => t('Change theme'),
01235           '#submit' => array('views_ui_edit_display_form_change_theme'),
01236         );
01237 
01238         $form['analysis'] = array(
01239           '#prefix' => '<div class="form-item">',
01240           '#suffix' => '</div>',
01241           '#value' => theme('item_list', $funcs),
01242         );
01243 
01244         $form['rescan_button'] = array(
01245           '#prefix' => '<div class="form-item">',
01246           '#suffix' => '</div>',
01247         );
01248         $form['rescan_button']['button'] = array(
01249           '#type' => 'submit',
01250           '#value' => t('Rescan template files'),
01251           '#submit' => array('views_ui_config_item_form_rescan'),
01252         );
01253         $form['rescan_button']['markup'] = array(
01254           '#prefix' => '<div class="description">',
01255           '#suffix' => '</div>',
01256           '#value' => t("<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system."),
01257         );
01258 
01259         $form_state['ok_button'] = TRUE;
01260         break;
01261       case 'analyze-theme-display':
01262         $form['#title'] .= t('Theming information (display)');
01263         $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01264 
01265         if (empty($this->definition['theme'])) {
01266           $output .= t('This display has no theming information');
01267         }
01268         else {
01269           $output .= '<p>' . t('This is the default theme template used for this display.') . '</p>';
01270           $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($this->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
01271         }
01272 
01273         if (!empty($this->definition['additional themes'])) {
01274           foreach ($this->definition['additional themes'] as $theme => $type) {
01275             $output .= '<p>' . t('This is an alternative template for this display.') . '</p>';
01276             $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
01277           }
01278         }
01279 
01280         $form['analysis'] = array(
01281           '#prefix' => '<div class="form-item">',
01282           '#suffix' => '</div>',
01283           '#value' => $output,
01284         );
01285 
01286         $form_state['ok_button'] = TRUE;
01287         break;
01288       case 'analyze-theme-style':
01289         $form['#title'] .= t('Theming information (style)');
01290         $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01291 
01292         $plugin = $this->get_plugin();
01293 
01294         if (empty($plugin->definition['theme'])) {
01295           $output .= t('This display has no style theming information');
01296         }
01297         else {
01298           $output .= '<p>' . t('This is the default theme template used for this style.') . '</p>';
01299           $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
01300         }
01301 
01302         if (!empty($plugin->definition['additional themes'])) {
01303           foreach ($plugin->definition['additional themes'] as $theme => $type) {
01304             $output .= '<p>' . t('This is an alternative template for this style.') . '</p>';
01305             $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
01306           }
01307         }
01308 
01309         $form['analysis'] = array(
01310           '#prefix' => '<div class="form-item">',
01311           '#suffix' => '</div>',
01312           '#value' => $output,
01313         );
01314 
01315         $form_state['ok_button'] = TRUE;
01316         break;
01317       case 'analyze-theme-row':
01318         $form['#title'] .= t('Theming information (row style)');
01319         $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01320 
01321         $plugin = $this->get_plugin('row');
01322 
01323         if (empty($plugin->definition['theme'])) {
01324           $output .= t('This display has no row style theming information');
01325         }
01326         else {
01327           $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
01328           $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
01329         }
01330 
01331         if (!empty($plugin->definition['additional themes'])) {
01332           foreach ($plugin->definition['additional themes'] as $theme => $type) {
01333             $output .= '<p>' . t('This is an alternative template for this row style.') . '</p>';
01334             $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
01335           }
01336         }
01337 
01338         $form['analysis'] = array(
01339           '#prefix' => '<div class="form-item">',
01340           '#suffix' => '</div>',
01341           '#value' => $output,
01342         );
01343 
01344         $form_state['ok_button'] = TRUE;
01345         break;
01346       case 'analyze-theme-field':
01347         $form['#title'] .= t('Theming information (row style)');
01348         $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01349 
01350         $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
01351 
01352         // Field templates aren't registered the normal way...and they're always
01353         // this one, anyhow.
01354         $output .= '<pre>' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/theme/views-view-field.tpl.php')) . '</pre>';
01355 
01356         $form['analysis'] = array(
01357           '#prefix' => '<div class="form-item">',
01358           '#suffix' => '</div>',
01359           '#value' => $output,
01360         );
01361         $form_state['ok_button'] = TRUE;
01362         break;
01363 
01364       case 'exposed_block':
01365         $form['#title'] .= t('Put the exposed form in a block');
01366         $form['description'] = array(
01367           '#prefix' => '<div class="description form-item">',
01368           '#suffix' => '</div>',
01369           '#value' => t('If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you.'),
01370         );
01371         $form['exposed_block'] = array(
01372           '#type' => 'radios',
01373           '#options' => array(1 => t('Yes'), 0 => t('No')),
01374           '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
01375         );
01376         break;
01377     }
01378   }
01379 
01383   function format_themes($themes) {
01384     $registry = theme_get_registry();
01385 
01386     // Run through the theme engine variables, if necessary
01387     global $theme_engine;
01388     $extension = '.tpl.php';
01389     if (isset($theme_engine)) {
01390       $extension_function = $theme_engine . '_extension';
01391       if (function_exists($extension_function)) {
01392         $extension = $extension_function();
01393       }
01394     }
01395 
01396     $output = '';
01397     $picked = FALSE;
01398     foreach ($themes as $theme) {
01399       $template = strtr($theme, '_', '-') . $extension;
01400       if (!$picked && !empty($registry[$theme])) {
01401         $template_path = isset($registry[$theme]['path']) ? $registry[$theme]['path'] . '/' : './';
01402         if (file_exists($template_path . $template)) {
01403           $hint = t('File found in folder @template-path', array('@template-path' => $template_path));
01404           $template = '<strong title="'. $hint .'">' . $template . '</strong>';
01405         }
01406         else {
01407           $template = '<strong class="error">' . $template . ' ' . t('(File not found, in folder @template-path)', array('@template-path' => $template_path)) . '</strong>';
01408         }
01409         $picked = TRUE;
01410       }
01411       $fixed[] = $template;
01412     }
01413 
01414     return implode(', ', array_reverse($fixed));
01415   }
01416 
01420   function options_validate(&$form, &$form_state) {
01421     switch ($form_state['section']) {
01422       case 'style_options':
01423         $style = TRUE;
01424       case 'row_options':
01425         // if row, $style will be empty.
01426         $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
01427         if ($plugin) {
01428           $plugin->options_validate($form[$form_state['section']], $form_state);
01429         }
01430         break;
01431       case 'access_options':
01432         $plugin = $this->get_access_plugin();
01433         if ($plugin) {
01434           $plugin->options_validate($form['access_options'], $form_state);
01435         }
01436         break;
01437       case 'cache_options':
01438         $plugin = $this->get_cache_plugin();
01439         if ($plugin) {
01440           $plugin->options_validate($form['cache_options'], $form_state);
01441         }
01442         break;
01443     }
01444   }
01445 
01450   function options_submit(&$form, &$form_state) {
01451     // Not sure I like this being here, but it seems (?) like a logical place.
01452     $cache_plugin = $this->get_cache_plugin();
01453     if ($cache_plugin) {
01454       $cache_plugin->cache_flush();
01455     }
01456 
01457     $section = $form_state['section'];
01458     switch ($section) {
01459       case 'display_title':
01460         $this->display->display_title = $form_state['values']['display_title'];
01461         break;
01462       case 'access':
01463         $access = $this->get_option('access');
01464         if ($access['type'] != $form_state['values']['access']['type']) {
01465           $plugin = views_get_plugin('access', $form_state['values']['access']['type']);
01466           if ($plugin) {
01467             $access = array('type' => $form_state['values']['access']['type']);
01468             $plugin->option_defaults($access);
01469             $this->set_option('access', $access);
01470             if (!empty($plugin->definition['uses options'])) {
01471               views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('access_options'));
01472             }
01473           }
01474         }
01475 
01476         break;
01477       case 'access_options':
01478         $plugin = views_get_plugin('access', $form_state['values'][$section]['type']);
01479         if ($plugin) {
01480           $plugin->options_submit($form['access_options'], $form_state);
01481           $this->set_option('access', $form_state['values'][$section]);
01482         }
01483         break;
01484       case 'cache':
01485         $cache = $this->get_option('cache');
01486         if ($cache['type'] != $form_state['values']['cache']['type']) {
01487           $plugin = views_get_plugin('cache', $form_state['values']['cache']['type']);
01488           if ($plugin) {
01489             $cache = array('type' => $form_state['values']['cache']['type']);
01490             $plugin->option_defaults($cache);
01491             $this->set_option('cache', $cache);
01492             if (!empty($plugin->definition['uses options'])) {
01493               views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('cache_options'));
01494             }
01495           }
01496         }
01497 
01498         break;
01499       case 'cache_options':
01500         $plugin = views_get_plugin('cache', $form_state['values'][$section]['type']);
01501         if ($plugin) {
01502           $plugin->options_submit($form['cache_options'], $form_state);
01503           $this->set_option('cache', $form_state['values'][$section]);
01504         }
01505         break;
01506       case 'title':
01507       case 'link_display':
01508         $this->set_option($section, $form_state['values'][$section]);
01509         break;
01510       case 'use_ajax':
01511         $this->set_option($section, (bool)$form_state['values'][$section]);
01512         break;
01513       case 'use_pager':
01514         $this->set_option($section, $form_state['values'][$section]);
01515         $this->set_option('pager_element', intval($form_state['values']['pager_element']));
01516         break;
01517       case 'items_per_page':
01518         $this->set_option($section, intval($form_state['values'][$section]));
01519         $this->set_option('offset', intval($form_state['values']['offset']));
01520         break;
01521       case 'use_more':
01522         $this->set_option($section, intval($form_state['values'][$section]));
01523         $this->set_option('use_more_always', intval($form_state['values']['use_more_always']));
01524         $this->set_option('use_more_text', $form_state['values']['use_more_text']);
01525       case 'distinct':
01526         $this->set_option($section, $form_state['values'][$section]);
01527         break;
01528       case 'row_plugin':
01529         // This if prevents resetting options to default if they don't change
01530         // the plugin.
01531         if ($this->get_option($section) != $form_state['values'][$section]) {
01532           $plugin = views_get_plugin('row', $form_state['values'][$section]);
01533           if ($plugin) {
01534             $this->set_option($section, $form_state['values'][$section]);
01535             $this->set_option('row_options', array());
01536 
01537             // send ajax form to options page if we use it.
01538             if (!empty($plugin->definition['uses options'])) {
01539               views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('row_options'));
01540             }
01541           }
01542         }
01543         break;
01544       case 'style_plugin':
01545         // This if prevents resetting options to default if they don't change
01546         // the plugin.
01547         if ($this->get_option($section) != $form_state['values'][$section]) {
01548           $plugin = views_get_plugin('style', $form_state['values'][$section]);
01549           if ($plugin) {
01550             $this->set_option($section, $form_state['values'][$section]);
01551             $this->set_option('style_options', array());
01552             // send ajax form to options page if we use it.
01553             if (!empty($plugin->definition['uses options'])) {
01554               views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('style_options'));
01555             }
01556           }
01557         }
01558         break;
01559       case 'style_options':
01560         $style = TRUE;
01561       case 'row_options':
01562         // if row, $style will be empty.
01563         $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
01564         if ($plugin) {
01565           $plugin->options_submit($form[$section], $form_state);
01566         }
01567         $this->set_option($section, $form_state['values'][$section]);
01568         break;
01569       case 'header':
01570       case 'footer':
01571       case 'empty':
01572         $this->set_option($section, $form_state['values'][$section]);
01573         $this->set_option($section . '_format', $form_state['values'][$section . '_format']);
01574         if ($section != 'empty') {
01575           $this->set_option($section . '_empty', $form_state['values'][$section . '_empty']);
01576         }
01577         break;
01578       case 'exposed_block':
01579         $this->set_option($section, (bool) $form_state['values'][$section]);
01580         break;
01581     }
01582   }
01583 
01589   function add_override_button(&$form, &$form_state, $section) {
01590     if ($this->is_default_display()) {
01591       return;
01592     }
01593 
01594     $form['override'] = array(
01595       '#prefix' => '<div class="views-override clear-block">',
01596       '#suffix' => '</div>',
01597     );
01598     if ($this->is_defaulted($section)) {
01599       $form['override']['button'] = array(
01600         '#type' => 'submit',
01601         '#value' => t('Override'),
01602         '#submit' => array('views_ui_edit_display_form_override'),
01603       );
01604       $form['override']['markup'] = array(
01605         '#prefix' => '<div class="description">',
01606         '#value' => theme('advanced_help_topic', 'views', 'overrides') . t('Status: using default values.'),
01607         '#suffix' => '</div>',
01608       );
01609 
01610       $form_state['update_name'] = t('Update default display');
01611     }
01612     else {
01613       $form['override']['button'] = array(
01614         '#type' => 'submit',
01615         '#value' => t('Use default'),
01616         '#submit' => array('views_ui_edit_display_form_override'),
01617       );
01618       $form['override']['markup'] = array(
01619         '#prefix' => '<div class="description">',
01620         '#value' => theme('advanced_help_topic', 'views', 'overrides') . t('Status: using overridden values.'),
01621         '#suffix' => '</div>',
01622       );
01623 
01624       $form_state['update_name'] = NULL;
01625     }
01626   }
01627 
01631   function options_override($form, &$form_state) {
01632     $this->set_override($form_state['section']);
01633   }
01634 
01638   function set_override($section, $new_state = NULL) {
01639     $options = $this->defaultable_sections($section);
01640     if (!$options) {
01641       return;
01642     }
01643 
01644     if (!isset($new_state)) {
01645       $new_state = empty($this->options['defaults'][$section]);
01646     }
01647 
01648     // For each option that is part of this group, fix our settings.
01649     foreach ($options as $option) {
01650       if ($new_state) {
01651         // Revert to defaults.
01652         unset($this->options[$option]);
01653         unset($this->display->display_options[$option]);
01654       }
01655       else {
01656         // copy existing values into our display.
01657         $this->options[$option] = $this->get_option($option);
01658         $this->display->display_options[$option] = $this->options[$option];
01659       }
01660       $this->options['defaults'][$option] = $new_state;
01661       $this->display->display_options['defaults'][$option] = $new_state;
01662     }
01663   }
01664 
01668   function query() {
01669     // Make the query distinct if the option was set.
01670     if ($this->get_option('distinct')) {
01671       $this->view->query->set_distinct();
01672     }
01673   }
01674 
01678   function render_filters() { }
01679 
01683   function render_more_link() {
01684     if ($this->use_more() && ($this->use_more_always() || !isset($this->view->total_rows) || $this->view->total_rows > $this->view->pager['items_per_page'])) {
01685       $path = $this->get_path();
01686       if ($path) {
01687         $path = $this->view->get_url(NULL, $path);
01688         $url_options = array();
01689         if (!empty($this->view->exposed_raw_input)) {
01690           $url_options['query'] = $this->view->exposed_raw_input;
01691         }
01692         $theme = views_theme_functions('views_more', $this->view, $this->display);
01693         $path = check_url(url($path, $url_options));
01694         return theme($theme, $path, $this->use_more_text());
01695       }
01696     }
01697   }
01698 
01702   function render_textarea($area) {
01703     static $formats = array();
01704 
01705     $value = $this->get_option($area);
01706     // Check to make sure the filter format exists; if not, we don't
01707     // display anything.
01708     $format = filter_resolve_format($this->get_option($area . '_format'));
01709 
01710     if (!array_key_exists($format, $formats)) {
01711       $formats[$format] = db_result(db_query("SELECT name FROM {filter_formats} WHERE format = %d", $format));
01712     }
01713 
01714     if (!$formats[$format]) {
01715       return;
01716     }
01717 
01718     if ($value) {
01719       return check_markup($value, $format, FALSE);
01720     }
01721   }
01722 
01726   function render_header() {
01727     if (!empty($this->view->result) || $this->get_option('header_empty')) {
01728       return $this->render_textarea('header');
01729     }
01730   }
01731 
01735   function render_footer() {
01736     if (!empty($this->view->result) || $this->get_option('footer_empty')) {
01737       return $this->render_textarea('footer');
01738     }
01739   }
01740 
01744   function render_empty() { return $this->render_textarea('empty'); }
01748   function hook_block($op = 'list', $delta = 0, $edit = array()) { return array(); }
01749 
01753   function hook_menu() { return array(); }
01754 
01758   function render() {
01759     return theme($this->theme_functions(), $this->view);
01760   }
01761 
01765   function access($account = NULL) {
01766     if (!isset($account)) {
01767       global $user;
01768       $account = $user;
01769     }
01770 
01771     // Full override.
01772     if (user_access('access all views', $account)) {
01773       return TRUE;
01774     }
01775 
01776     $plugin = $this->get_access_plugin();
01777     if ($plugin) {
01778       return $plugin->access($account);
01779     }
01780 
01781     // fallback to all access if no plugin.
01782     return TRUE;
01783   }
01784 
01790   function pre_execute() {
01791     $this->view->set_use_ajax($this->use_ajax());
01792     // Copy pager information from the display.
01793     $this->view->set_use_pager($this->use_pager());
01794     $this->view->set_pager_element($this->get_option('pager_element'));
01795     $this->view->set_items_per_page($this->get_option('items_per_page'));
01796     $this->view->set_offset($this->get_option('offset'));
01797     if ($this->use_more()) {
01798       $this->view->get_total_rows = TRUE;
01799     }
01800   }
01801 
01808   function execute() { }
01809 
01814   function preview() { return $this->view->render(); }
01815 
01820   function get_style_type() { return 'normal'; }
01821 
01828   function validate() {
01829     $errors = array();
01830     // Make sure displays that use fields HAVE fields.
01831     if ($this->uses_fields()) {
01832       $fields = FALSE;
01833       foreach ($this->get_handlers('field') as $field) {
01834         if (empty($field->options['exclude'])) {
01835           $fields = TRUE;
01836         }
01837       }
01838 
01839       if (!$fields) {
01840         $errors[] = t('Display "@display" uses fields but there are none defined for it or all are excluded.', array('@display' => $this->display->display_title));
01841       }
01842     }
01843 
01844     if ($this->has_path() && !$this->get_option('path')) {
01845       $errors[] = t('Display "@display" uses a path but the path is undefined.', array('@display' => $this->display->display_title));
01846     }
01847 
01848     // Validate style plugin
01849     $style = $this->get_plugin();
01850     if (empty($style)) {
01851       $errors[] = t('Display "@display" has an invalid style plugin.', array('@display' => $this->display->display_title));
01852     }
01853     else {
01854       $result = $style->validate();
01855       if (!empty($result) && is_array($result)) {
01856         $errors = array_merge($errors, $result);
01857       }
01858     }
01859 
01860     // Validate handlers
01861     foreach (views_object_types() as $type => $info) {
01862       foreach ($this->get_handlers($type) as $handler) {
01863         $result = $handler->validate();
01864         if (!empty($result) && is_array($result)) {
01865           $errors = array_merge($errors, $result);
01866         }
01867       }
01868     }
01869 
01870     return $errors;
01871   }
01872 
01876   function is_identifier_unique($id, $identifier) {
01877     foreach (views_object_types() as $type => $info) {
01878       foreach ($this->get_handlers($type) as $key => $handler) {
01879         if ($handler->can_expose() && $handler->is_exposed()) {
01880           if ($id != $key && $identifier == $handler->options['expose']['identifier']) {
01881             return FALSE;
01882           }
01883         }
01884       }
01885     }
01886     return TRUE;
01887   }
01888 
01892   function get_special_blocks() {
01893     $delta = '-exp-' . $this->view->name . '-' . $this->display->id;
01894     $desc = t('Exposed form: @view-@display_id', array('@view' => $this->view->name, '@display_id' => $this->display->id));
01895 
01896     return array(
01897       $delta => array(
01898         'info' => $desc,
01899       )
01900     );
01901   }
01902 
01906   function view_special_blocks($type) {
01907     if ($type == '-exp') {
01908       // avoid interfering with the admin forms.
01909       if (arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'views') {
01910         return;
01911       }
01912       $this->view->init_handlers();
01913       return array(
01914         'content' => $this->view->render_exposed_form(TRUE),
01915       );
01916     }
01917   }
01918 
01919 }
01920 
01921 

Generated on Mon Nov 30 15:06:00 2009 for Views by  doxygen 1.4.7