00001 <?php
00026 class views_plugin_display extends views_plugin {
00032 var $view = NULL;
00033
00034 var $handlers = array();
00035
00039 var $extender = array();
00040
00041 function init(&$view, &$display, $options = NULL) {
00042 $this->view = &$view;
00043 $this->display = &$display;
00044
00045
00046 $changed = FALSE;
00047
00048
00049 if (!isset($options) && isset($display->display_options)) {
00050 $options = $display->display_options;
00051 }
00052
00053 if ($this->is_default_display() && isset($options['defaults'])) {
00054 unset($options['defaults']);
00055 }
00056
00057
00058 static $unpack_options = array();
00059 if (empty($view->editing)) {
00060 $cid = 'unpack_options:' . md5(serialize(array($this->options, $options)));
00061 if (empty($unpack_options[$cid])) {
00062 $cache = views_cache_get($cid, TRUE);
00063 if (!empty($cache->data)) {
00064 $this->options = $cache->data;
00065 }
00066 else {
00067 $this->unpack_options($this->options, $options);
00068 views_cache_set($cid, $this->options, TRUE);
00069 }
00070 $unpack_options[$cid] = $this->options;
00071 }
00072 else {
00073 $this->options = $unpack_options[$cid];
00074 }
00075 }
00076 else {
00077 $this->unpack_options($this->options, $options);
00078 }
00079
00080
00081 $items_per_page = $this->get_option('items_per_page');
00082 $offset = $this->get_option('offset');
00083 $use_pager = $this->get_option('use_pager');
00084 $pager = $this->get_option('pager');
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 if (((!empty($items_per_page) && $items_per_page != 10) || !empty($offset) || !empty($use_pager))
00095 || (!empty($view->api_version) && $view->api_version == 2)) {
00096
00097
00098 if ($use_pager) {
00099 $type = 'full';
00100 }
00101
00102
00103 else {
00104 $type = $items_per_page ? 'some' : 'none';
00105 }
00106
00107
00108 $pager = array(
00109 'type' => $type,
00110 'options' => array(
00111 'offset' => intval($offset)
00112 ),
00113 );
00114
00115 if ($items_per_page) {
00116 $pager['options']['items_per_page'] = $items_per_page;
00117 }
00118
00119 if ($id = $this->get_option('pager_element')) {
00120 $pager['options']['id'] = $id;
00121 }
00122
00123
00124
00125 $this->set_option('items_per_page', NULL);
00126 $this->set_option('offset', NULL);
00127 $this->set_option('use_pager', NULL);
00128 $this->set_option('pager', $pager);
00129 $changed = TRUE;
00130 }
00131
00132
00133
00134
00135
00136 foreach (array('header', 'footer', 'empty') as $area) {
00137 $converted = FALSE;
00138 if (isset($this->options[$area]) && !is_array($this->options[$area])) {
00139 if (!empty($this->options[$area])) {
00140 $content = $this->get_option($area);
00141 if (!empty($content) && !is_array($content)) {
00142 $format = $this->get_option($area . '_format');
00143 $options = array(
00144 'id' => 'area',
00145 'table' => 'views',
00146 'field' => 'area',
00147 'label' => '',
00148 'relationship' => 'none',
00149 'group_type' => 'group',
00150 'content' => $content,
00151 'format' => !empty($format) ? $format : filter_default_format(),
00152 );
00153
00154 if ($area != 'empty' && $empty = $this->get_option($area . '_empty')) {
00155 $options['empty'] = $empty;
00156 }
00157 $this->set_option($area, array('text' => $options));
00158 $converted = TRUE;
00159 $changed = TRUE;
00160 }
00161 }
00162
00163 if (!$converted) {
00164 $this->set_option($area, array());
00165 }
00166 }
00167 }
00168
00169
00170 $distinct = $this->get_option('distinct');
00171 if (!empty($distinct)) {
00172 $query_settings = $this->get_option('query');
00173 $query_settings['options']['distinct'] = $distinct;
00174 $this->set_option('query', $query_settings);
00175
00176 $this->set_option('distinct', NULL);
00177 $changed = TRUE;
00178 }
00179
00180
00181 $query_options = $this->get_option('query');
00182 if (isset($query_options['options']['field_language'])) {
00183 $this->set_option('field_language', $query_options['options']['field_language']);
00184 unset($query_options['options']['field_language']);
00185 $changed = TRUE;
00186 }
00187 if (isset($query_options['options']['field_language_add_to_query'])) {
00188 $this->set_option('field_language_add_to_query', $query_options['options']['field_language_add_to_query']);
00189 unset($query_options['options']['field_language_add_to_query']);
00190 $changed = TRUE;
00191 }
00192 $this->set_option('query', $query_options);
00193
00194
00195 $filter_groups = $this->get_option('filter_groups');
00196
00197 if (isset($filter_groups['groups'][0])) {
00198
00199 $filter_groups ['groups'] = views_array_key_plus($filter_groups['groups']);
00200 $this->set_option('filter_groups', $filter_groups);
00201
00202 $filters = $this->get_option('filters');
00203 foreach ($filters as &$filter) {
00204 if (isset($filter['group'])) {
00205 $filter['group']++;
00206 }
00207 else {
00208 $filter['group'] = 1;
00209 }
00210 }
00211 $this->set_option('filters', $filters);
00212 $changed = TRUE;
00213 }
00214
00215
00216 if ($changed) {
00217 $this->view->changed = TRUE;
00218 }
00219 }
00220
00221 function construct() {
00222
00223 $this->extender = array();
00224 $extenders = views_get_enabled_display_extenders();
00225
00226 if (!empty($extenders) && class_exists('views_plugin_display_extender')) {
00227 foreach ($extenders as $extender) {
00228 $data = views_fetch_plugin_data('display_extender', $extender);
00229 if (isset($data['handler']) && class_exists($data['handler'])) {
00230 $this->extender[$extender] = new $data['handler']($this->view, $this);
00231 }
00232 else {
00233 vpr('Invalid display extender @extender', array('@handler' => $extender));
00234 }
00235 }
00236 }
00237 parent::construct();
00238 }
00239
00240 function destroy() {
00241 parent::destroy();
00242
00243 foreach ($this->handlers as $type => $handlers) {
00244 foreach ($handlers as $id => $handler) {
00245 if (is_object($handler)) {
00246 $this->handlers[$type][$id]->destroy();
00247 }
00248 }
00249 }
00250
00251 if (isset($this->default_display)) {
00252 unset($this->default_display);
00253 }
00254
00255 foreach ($this->extender as $extender) {
00256 $extender->destroy();
00257 }
00258 }
00259
00264 function is_default_display() { return FALSE; }
00265
00270 function uses_exposed() {
00271 if (!isset($this->has_exposed)) {
00272 foreach ($this->handlers as $type => $value) {
00273 foreach ($this->view->$type as $id => $handler) {
00274 if ($handler->can_expose() && $handler->is_exposed()) {
00275
00276 $this->has_exposed = TRUE;
00277 return TRUE;
00278 }
00279 }
00280 }
00281 $pager = $this->get_plugin('pager');
00282 if (isset($pager) && $pager->uses_exposed()) {
00283 $this->has_exposed = TRUE;
00284 return TRUE;
00285 }
00286 $this->has_exposed = FALSE;
00287 }
00288
00289 return $this->has_exposed;
00290 }
00291
00301 function displays_exposed() {
00302 return TRUE;
00303 }
00304
00308 function use_ajax() {
00309 if (!empty($this->definition['use ajax'])) {
00310 return $this->get_option('use_ajax');
00311 }
00312 return FALSE;
00313 }
00314
00318 function use_pager() {
00319 $pager = $this->get_plugin('pager');
00320 if ($pager) {
00321 return $pager->use_pager();
00322 }
00323 }
00324
00328 function use_more() {
00329 if (!empty($this->definition['use more'])) {
00330 return $this->get_option('use_more');
00331 }
00332 return FALSE;
00333 }
00334
00338 function use_group_by() {
00339 return $this->get_option('group_by');
00340 }
00341
00345 function use_more_always() {
00346 if (!empty($this->definition['use more'])) {
00347 return $this->get_option('use_more_always');
00348 }
00349 return FALSE;
00350 }
00351
00355 function use_more_text() {
00356 if (!empty($this->definition['use more'])) {
00357 return $this->get_option('use_more_text');
00358 }
00359 return FALSE;
00360 }
00361
00365 function accept_attachments() {
00366 if (empty($this->definition['accept attachments'])) {
00367 return FALSE;
00368 }
00369 if (!empty($this->view->argument) && $this->get_option('hide_attachment_summary')) {
00370 foreach ($this->view->argument as $argument_id => $argument) {
00371 if ($argument->needs_style_plugin() && empty($argument->argument_validated)) {
00372 return FALSE;
00373 }
00374 }
00375 }
00376 return TRUE;
00377 }
00378
00382 function attach_to($display_id) { }
00383
00388 function defaultable_sections($section = NULL) {
00389 $sections = array(
00390 'access' => array('access', 'access_options'),
00391 'access_options' => array('access', 'access_options'),
00392 'cache' => array('cache', 'cache_options'),
00393 'cache_options' => array('cache', 'cache_options'),
00394 'title' => array('title'),
00395 'css_class' => array('css_class'),
00396 'use_ajax' => array('use_ajax'),
00397 'hide_attachment_summary' => array('hide_attachment_summary'),
00398 'group_by' => array('group_by'),
00399 'query' => array('query'),
00400 'use_more' => array('use_more', 'use_more_always', 'use_more_text'),
00401 'link_display' => array('link_display', 'link_url'),
00402
00403
00404 'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00405 'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00406 'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00407 'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
00408
00409 'pager' => array('pager', 'pager_options'),
00410 'pager_options' => array('pager', 'pager_options'),
00411
00412 'exposed_form' => array('exposed_form', 'exposed_form_options'),
00413 'exposed_form_options' => array('exposed_form', 'exposed_form_options'),
00414
00415
00416 'header' => array('header'),
00417 'footer' => array('footer'),
00418 'empty' => array('empty'),
00419 'relationships' => array('relationships'),
00420 'fields' => array('fields'),
00421 'sorts' => array('sorts'),
00422 'arguments' => array('arguments'),
00423 'filters' => array('filters', 'filter_groups'),
00424 );
00425
00426
00427 if (empty($this->definition['use pager'])) {
00428 unset($sections['pager']);
00429 unset($sections['items_per_page']);
00430 }
00431
00432 foreach ($this->extender as $extender) {
00433 $extender->defaultable_sections($sections, $section);
00434 }
00435
00436 if ($section) {
00437 if (!empty($sections[$section])) {
00438 return $sections[$section];
00439 }
00440 }
00441 else {
00442 return $sections;
00443 }
00444 }
00445
00446 function option_definition() {
00447 $options = array(
00448 'defaults' => array(
00449 'default' => array(
00450 'access' => TRUE,
00451 'cache' => TRUE,
00452 'query' => TRUE,
00453 'title' => TRUE,
00454 'css_class' => TRUE,
00455
00456 'display_description' => FALSE,
00457 'use_ajax' => TRUE,
00458 'hide_attachment_summary' => TRUE,
00459 'pager' => TRUE,
00460 'pager_options' => TRUE,
00461 'use_more' => TRUE,
00462 'use_more_always' => TRUE,
00463 'use_more_text' => TRUE,
00464 'exposed_form' => TRUE,
00465 'exposed_form_options' => TRUE,
00466
00467 'link_display' => TRUE,
00468 'link_url' => '',
00469 'group_by' => TRUE,
00470
00471 'style_plugin' => TRUE,
00472 'style_options' => TRUE,
00473 'row_plugin' => TRUE,
00474 'row_options' => TRUE,
00475
00476 'header' => TRUE,
00477 'footer' => TRUE,
00478 'empty' => TRUE,
00479
00480 'relationships' => TRUE,
00481 'fields' => TRUE,
00482 'sorts' => TRUE,
00483 'arguments' => TRUE,
00484 'filters' => TRUE,
00485 'filter_groups' => TRUE,
00486 ),
00487 'export' => FALSE,
00488 ),
00489
00490 'title' => array(
00491 'default' => '',
00492 'translatable' => TRUE,
00493 ),
00494 'enabled' => array(
00495 'default' => TRUE,
00496 'translatable' => FALSE,
00497 'bool' => TRUE,
00498 ),
00499 'display_comment' => array(
00500 'default' => '',
00501 ),
00502 'css_class' => array(
00503 'default' => '',
00504 'translatable' => FALSE,
00505 ),
00506 'display_description' => array(
00507 'default' => '',
00508 'translatable' => TRUE,
00509 ),
00510 'use_ajax' => array(
00511 'default' => FALSE,
00512 'bool' => TRUE,
00513 ),
00514 'hide_attachment_summary' => array(
00515 'default' => FALSE,
00516 'bool' => TRUE,
00517 ),
00518
00519
00520
00521
00522 'items_per_page' => array(
00523 'default' => 10,
00524 ),
00525 'offset' => array(
00526 'default' => 0,
00527 ),
00528 'use_pager' => array(
00529 'default' => FALSE,
00530 'bool' => TRUE,
00531 ),
00532 'use_more' => array(
00533 'default' => FALSE,
00534 'bool' => TRUE,
00535 ),
00536 'use_more_always' => array(
00537 'default' => FALSE,
00538 'bool' => FALSE,
00539 ),
00540 'use_more_text' => array(
00541 'default' => 'more',
00542 'translatable' => TRUE,
00543 ),
00544 'link_display' => array(
00545 'default' => '',
00546 ),
00547 'link_url' => array(
00548 'default' => '',
00549 ),
00550 'group_by' => array(
00551 'default' => FALSE,
00552 'bool' => TRUE,
00553 ),
00554 'field_language' => array(
00555 'default' => '***CURRENT_LANGUAGE***',
00556 ),
00557 'field_language_add_to_query' => array(
00558 'default' => 1,
00559 ),
00560
00561
00562
00563 'access' => array(
00564 'contains' => array(
00565 'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
00566 ),
00567 ),
00568 'cache' => array(
00569 'contains' => array(
00570 'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
00571 ),
00572 ),
00573 'query' => array(
00574 'contains' => array(
00575 'type' => array('default' => 'views_query', 'export' => 'export_plugin'),
00576 'options' => array('default' => array(), 'export' => FALSE),
00577 ),
00578 ),
00579
00580
00581
00582
00583
00584
00585 'exposed_form' => array(
00586 'contains' => array(
00587 'type' => array('default' => 'basic', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
00588 'options' => array('default' => array(), 'export' => FALSE),
00589 ),
00590 ),
00591 'pager' => array(
00592 'contains' => array(
00593 'type' => array('default' => 'full', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'),
00594 'options' => array('default' => array(), 'export' => FALSE),
00595 ),
00596 ),
00597
00598
00599
00600
00601 'style_plugin' => array(
00602 'default' => 'default',
00603 'export' => 'export_style',
00604 'unpack_translatable' => 'unpack_style',
00605 ),
00606 'style_options' => array(
00607 'default' => array(),
00608 'export' => FALSE,
00609 ),
00610 'row_plugin' => array(
00611 'default' => 'fields',
00612 'export' => 'export_style',
00613 'unpack_translatable' => 'unpack_style',
00614 ),
00615 'row_options' => array(
00616 'default' => array(),
00617 'export' => FALSE,
00618 ),
00619
00620 'exposed_block' => array(
00621 'default' => FALSE,
00622 ),
00623
00624 'header' => array(
00625 'default' => array(),
00626 'export' => 'export_handler',
00627 'unpack_translatable' => 'unpack_handler',
00628 ),
00629 'footer' => array(
00630 'default' => array(),
00631 'export' => 'export_handler',
00632 'unpack_translatable' => 'unpack_handler',
00633 ),
00634 'empty' => array(
00635 'default' => array(),
00636 'export' => 'export_handler',
00637 'unpack_translatable' => 'unpack_handler',
00638 ),
00639
00640
00641
00642 'relationships' => array(
00643 'default' => array(),
00644 'export' => 'export_handler',
00645 'unpack_translatable' => 'unpack_handler',
00646
00647 ),
00648 'fields' => array(
00649 'default' => array(),
00650 'export' => 'export_handler',
00651 'unpack_translatable' => 'unpack_handler',
00652 ),
00653 'sorts' => array(
00654 'default' => array(),
00655 'export' => 'export_handler',
00656 'unpack_translatable' => 'unpack_handler',
00657 ),
00658 'arguments' => array(
00659 'default' => array(),
00660 'export' => 'export_handler',
00661 'unpack_translatable' => 'unpack_handler',
00662 ),
00663 'filter_groups' => array(
00664 'contains' => array(
00665 'operator' => array('default' => 'AND'),
00666 'groups' => array('default' => array(1 => 'AND')),
00667 ),
00668 ),
00669 'filters' => array(
00670 'default' => array(),
00671 'export' => 'export_handler',
00672 'unpack_translatable' => 'unpack_handler',
00673 ),
00674 );
00675
00676 if (empty($this->definition['use pager'])) {
00677 $options['defaults']['default']['use_pager'] = FALSE;
00678 $options['defaults']['default']['items_per_page'] = FALSE;
00679 $options['defaults']['default']['offset'] = FALSE;
00680 $options['defaults']['default']['pager'] = FALSE;
00681 $options['pager']['contains']['type']['default'] = 'some';
00682 }
00683
00684 if ($this->is_default_display()) {
00685 unset($options['defaults']);
00686 }
00687
00688 foreach ($this->extender as $extender) {
00689 $extender->option_definition($options);
00690 }
00691
00692 return $options;
00693 }
00694
00704 function has_path() { return FALSE; }
00705
00713 function uses_link_display() { return !$this->has_path(); }
00714
00723 function uses_exposed_form_in_block() { return $this->has_path(); }
00724
00729 function get_link_display() {
00730 $display_id = $this->get_option('link_display');
00731
00732 if (empty($display_id) || empty($this->view->display[$display_id])) {
00733 foreach ($this->view->display as $display_id => $display) {
00734 if (!empty($display->handler) && $display->handler->has_path()) {
00735 return $display_id;
00736 }
00737 }
00738 }
00739 else {
00740 return $display_id;
00741 }
00742
00743 }
00744
00751 function get_path() {
00752 if ($this->has_path()) {
00753 return $this->get_option('path');
00754 }
00755
00756 $display_id = $this->get_link_display();
00757 if ($display_id && !empty($this->view->display[$display_id]) && is_object($this->view->display[$display_id]->handler)) {
00758 return $this->view->display[$display_id]->handler->get_path();
00759 }
00760 }
00761
00767 function uses_breadcrumb() { return FALSE; }
00768
00776 function is_defaulted($option) {
00777 return !$this->is_default_display() && !empty($this->default_display) && !empty($this->options['defaults'][$option]);
00778 }
00779
00784 function get_option($option) {
00785 if ($this->is_defaulted($option)) {
00786 return $this->default_display->get_option($option);
00787 }
00788
00789 if (array_key_exists($option, $this->options)) {
00790 return $this->options[$option];
00791 }
00792 }
00793
00797 function uses_fields() {
00798 $plugin = $this->get_plugin();
00799 if ($plugin) {
00800 return $plugin->uses_fields();
00801 }
00802 }
00803
00814 function get_plugin($type = 'style', $name = NULL) {
00815 static $cache = array();
00816 if (!isset($cache[$type][$name])) {
00817 switch ($type) {
00818 case 'style':
00819 case 'row':
00820 $option_name = $type . '_plugin';
00821 $options = $this->get_option($type . '_options');
00822 if (!$name) {
00823 $name = $this->get_option($option_name);
00824 }
00825
00826 break;
00827 case 'query':
00828 $views_data = views_fetch_data($this->view->base_table);
00829 $name = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query';
00830 default:
00831 $option_name = $type;
00832 $options = $this->get_option($type);
00833 if (!$name) {
00834 $name = $options['type'];
00835 }
00836
00837
00838
00839 if ($type != 'access' && $type != 'cache') {
00840 $options = $options['options'];
00841 }
00842 }
00843 $plugin = views_get_plugin($type, $name);
00844
00845 if (!$plugin) {
00846 return;
00847 }
00848 if ($type != 'query') {
00849 $plugin->init($this->view, $this->display, $options);
00850 }
00851 else {
00852 $display_id = $this->is_defaulted($option_name) ? $this->display->id : 'default';
00853 $plugin->localization_keys = array($display_id, $type);
00854
00855 if (!isset($this->base_field)) {
00856 $views_data = views_fetch_data($this->view->base_table);
00857 $this->view->base_field = !empty($views_data['table']['base']['field']) ? $views_data['table']['base']['field'] : '';
00858 }
00859 $plugin->init($this->view->base_table, $this->view->base_field, $options);
00860 }
00861 $cache[$type][$name] = $plugin;
00862 }
00863
00864 return $cache[$type][$name];
00865 }
00866
00870 function &get_handler($type, $id) {
00871 if (!isset($this->handlers[$type])) {
00872 $this->get_handlers($type);
00873 }
00874
00875 if (isset($this->handlers[$type][$id])) {
00876 return $this->handlers[$type][$id];
00877 }
00878
00879
00880 $null = NULL;
00881 return $null;
00882 }
00883
00887 function get_handlers($type) {
00888 if (!isset($this->handlers[$type])) {
00889 $this->handlers[$type] = array();
00890 $types = views_object_types();
00891 $plural = $types[$type]['plural'];
00892
00893 foreach ($this->get_option($plural) as $id => $info) {
00894
00895
00896
00897 if (isset($_POST['form_id']) && isset($this->view->temporary_options[$type][$id])) {
00898 $info = $this->view->temporary_options[$type][$id];
00899 }
00900
00901 if ($info['id'] != $id) {
00902 $info['id'] = $id;
00903 }
00904
00905
00906
00907
00908 $override = NULL;
00909 if ($this->use_group_by() && !empty($info['group_type'])) {
00910 if (empty($this->view->query)) {
00911 $this->view->init_query();
00912 }
00913 $aggregate = $this->view->query->get_aggregation_info();
00914 if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
00915 $override = $aggregate[$info['group_type']]['handler'][$type];
00916 }
00917 }
00918
00919 if (!empty($types[$type]['type'])) {
00920 $handler_type = $types[$type]['type'];
00921 }
00922 else {
00923 $handler_type = $type;
00924 }
00925
00926 $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
00927 if ($handler) {
00928
00929 if ($handler_type == 'area') {
00930 $handler->handler_type = $type;
00931 }
00932
00933 $handler->init($this->view, $info);
00934 $this->handlers[$type][$id] = &$handler;
00935 }
00936
00937
00938 unset($handler);
00939 }
00940 }
00941
00942 return $this->handlers[$type];
00943 }
00944
00949 function get_field_labels() {
00950 $options = array();
00951 foreach ($this->get_handlers('relationship') as $relationship => $handler) {
00952 if ($label = $handler->label()) {
00953 $relationships[$relationship] = $label;
00954 }
00955 else {
00956 $relationships[$relationship] = $handler->ui_name();
00957 }
00958 }
00959
00960 foreach ($this->get_handlers('field') as $id => $handler) {
00961 if ($label = $handler->label()) {
00962 $options[$id] = $label;
00963 }
00964 else {
00965 $options[$id] = $handler->ui_name();
00966 }
00967 if (!empty($handler->options['relationship']) && !empty($relationships[$handler->options['relationship']])) {
00968 $options[$id] = '(' . $relationships[$handler->options['relationship']] . ') ' . $options[$id];
00969 }
00970 }
00971 return $options;
00972 }
00973
00978 function set_option($option, $value) {
00979 if ($this->is_defaulted($option)) {
00980 return $this->default_display->set_option($option, $value);
00981 }
00982
00983
00984
00985
00986 $this->display->display_options[$option] = $value;
00987 return $this->options[$option] = $value;
00988 }
00989
00993 function override_option($option, $value) {
00994 $this->set_override($option, FALSE);
00995 $this->set_option($option, $value);
00996 }
00997
01002 function option_link($text, $section, $class = '', $title = '') {
01003 views_add_js('ajax');
01004 if (!empty($class)) {
01005 $text = '<span>' . $text . '</span>';
01006 }
01007
01008 if (!trim($text)) {
01009 $text = t('Broken field');
01010 }
01011
01012 if (empty($title)) {
01013 $title = $text;
01014 }
01015
01016 return l($text, 'admin/structure/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link ' . $class, 'title' => $title, 'id' => drupal_html_id('views-' . $this->display->id . '-' . $section)), 'html' => TRUE));
01017 }
01018
01025 function get_arguments_tokens() {
01026 $tokens = array();
01027 if (!empty($this->view->build_info['substitutions'])) {
01028 $tokens = $this->view->build_info['substitutions'];
01029 }
01030 $count = 0;
01031 foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
01032 $token = '%' . ++$count;
01033 if (!isset($tokens[$token])) {
01034 $tokens[$token] = '';
01035 }
01036
01037
01038
01039
01040 $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(decode_entities($this->view->args[$count - 1])) : '';
01041 }
01042
01043 return $tokens;
01044 }
01045
01051 function options_summary(&$categories, &$options) {
01052 $categories = array(
01053 'title' => array(
01054 'title' => t('Title'),
01055 'column' => 'first',
01056 ),
01057 'format' => array(
01058 'title' => t('Format'),
01059 'column' => 'first',
01060 ),
01061 'filters' => array(
01062 'title' => t('Filters'),
01063 'column' => 'first',
01064 ),
01065 'fields' => array(
01066 'title' => t('Fields'),
01067 'column' => 'first',
01068 ),
01069 'pager' => array(
01070 'title' => t('Pager'),
01071 'column' => 'second',
01072 ),
01073 'exposed' => array(
01074 'title' => t('Exposed form'),
01075 'column' => 'third',
01076 'build' => array(
01077 '#weight' => 1,
01078 ),
01079 ),
01080 'access' => array(
01081 'title' => '',
01082 'column' => 'second',
01083 'build' => array(
01084 '#weight' => -5,
01085 ),
01086 ),
01087 'other' => array(
01088 'title' => t('Other'),
01089 'column' => 'third',
01090 'build' => array(
01091 '#weight' => 2,
01092 ),
01093 ),
01094 );
01095
01096 if ($this->display->id != 'default') {
01097 $options['display_id'] = array(
01098 'category' => 'other',
01099 'title' => t('Machine Name'),
01100 'value' => !empty($this->display->new_id) ? check_plain($this->display->new_id) : check_plain($this->display->id),
01101 'desc' => t('Change the machine name of this display.'),
01102 );
01103 }
01104
01105 $display_comment = check_plain(drupal_substr($this->get_option('display_comment'), 0, 10));
01106 $options['display_comment'] = array(
01107 'category' => 'other',
01108 'title' => t('Comment'),
01109 'value' => !empty($display_comment) ? $display_comment : t('No comment'),
01110 'desc' => t('Comment or document this display.'),
01111 );
01112
01113 $title = strip_tags($this->get_option('title'));
01114 if (!$title) {
01115 $title = t('None');
01116 }
01117
01118 $options['title'] = array(
01119 'category' => 'title',
01120 'title' => t('Title'),
01121 'value' => $title,
01122 'desc' => t('Change the title that this display will use.'),
01123 );
01124
01125 $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
01126 $style_plugin_instance = $this->get_plugin('style');
01127 $style_summary = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin_instance->summary_title();
01128 $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin_instance->plugin_title();
01129
01130 $style = '';
01131
01132 $options['style_plugin'] = array(
01133 'category' => 'format',
01134 'title' => t('Format'),
01135 'value' => $style_title,
01136 'setting' => $style_summary,
01137 'desc' => t('Change the way content is formatted.'),
01138 );
01139
01140
01141 if (!empty($style_plugin['uses options'])) {
01142 $options['style_plugin']['links']['style_options'] = t('Change settings for this format');
01143 }
01144
01145 if (!empty($style_plugin['uses row plugin'])) {
01146 $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
01147 $row_plugin_instance = $this->get_plugin('row');
01148 $row_summary = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin_instance->summary_title();
01149 $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin_instance->plugin_title();
01150
01151 $options['row_plugin'] = array(
01152 'category' => 'format',
01153 'title' => t('Show'),
01154 'value' => $row_title,
01155 'setting' => $row_summary,
01156 'desc' => t('Change the way each row in the view is styled.'),
01157 );
01158
01159 if (!empty($row_plugin['uses options'])) {
01160 $options['row_plugin']['links']['row_options'] = t('Change settings for this style');
01161 }
01162 }
01163 if (!empty($this->definition['use ajax'])) {
01164 $options['use_ajax'] = array(
01165 'category' => 'other',
01166 'title' => t('Use AJAX'),
01167 'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
01168 'desc' => t('Change whether or not this display will use AJAX.'),
01169 );
01170 }
01171 if (!empty($this->definition['accept attachments'])) {
01172 $options['hide_attachment_summary'] = array(
01173 'category' => 'other',
01174 'title' => t('Hide attachments in summary'),
01175 'value' => $this->get_option('hide_attachment_summary') ? t('Yes') : t('No'),
01176 'desc' => t('Change whether or not to display attachments when displaying a contextual filter summary.'),
01177 );
01178 }
01179
01180 $pager_plugin = $this->get_plugin('pager');
01181 if (!$pager_plugin) {
01182
01183 $pager_plugin = views_get_plugin('pager', 'none');
01184 }
01185
01186 $pager_str = $pager_plugin->summary_title();
01187
01188 $options['pager'] = array(
01189 'category' => 'pager',
01190 'title' => t('Use pager'),
01191 'value' => $pager_plugin->plugin_title(),
01192 'setting' => $pager_str,
01193 'desc' => t("Change this display's pager setting."),
01194 );
01195
01196
01197 if (empty($this->definition['use pager'])) {
01198 $options['pager']['title'] = t('Items to display');
01199 }
01200
01201 if (!empty($pager_plugin->definition['uses options'])) {
01202 $options['pager']['links']['pager_options'] = t('Change settings for this pager type.');
01203 }
01204
01205 if (!empty($this->definition['use more'])) {
01206 $options['use_more'] = array(
01207 'category' => 'pager',
01208 'title' => t('More link'),
01209 'value' => $this->get_option('use_more') ? t('Yes') : t('No'),
01210 'desc' => t('Specify whether this display will provide a "more" link.'),
01211 );
01212 }
01213
01214 $this->view->init_query();
01215 if ($this->view->query->get_aggregation_info()) {
01216 $options['group_by'] = array(
01217 'category' => 'other',
01218 'title' => t('Use aggregation'),
01219 'value' => $this->get_option('group_by') ? t('Yes') : t('No'),
01220 'desc' => t('Allow grouping and aggregation (calculation) of fields.'),
01221 );
01222 }
01223
01224 $options['query'] = array(
01225 'category' => 'other',
01226 'title' => t('Query settings'),
01227 'value' => t('Settings'),
01228 'desc' => t('Allow to set some advanced settings for the query plugin'),
01229 );
01230
01231 $languages = array(
01232 '***CURRENT_LANGUAGE***' => t("Current user's language"),
01233 '***DEFAULT_LANGUAGE***' => t("Default site language"),
01234 LANGUAGE_NONE => t('Language neutral'),
01235 );
01236 if (module_exists('locale')) {
01237 $languages = array_merge($languages, locale_language_list());
01238 }
01239 $field_language = array();
01240 $options['field_language'] = array(
01241 'category' => 'other',
01242 'title' => t('Field Language'),
01243 'value' => $languages[$this->get_option('field_language')],
01244 'desc' => t('All fields which support translations will be displayed in the selected language.'),
01245 );
01246
01247 $access_plugin = $this->get_plugin('access');
01248 if (!$access_plugin) {
01249
01250 $access_plugin = views_get_plugin('access', 'none');
01251 }
01252
01253 $access_str = $access_plugin->summary_title();
01254
01255 $options['access'] = array(
01256 'category' => 'access',
01257 'title' => t('Access'),
01258 'value' => $access_plugin->plugin_title(),
01259 'setting' => $access_str,
01260 'desc' => t('Specify access control type for this display.'),
01261 );
01262
01263 if (!empty($access_plugin->definition['uses options'])) {
01264 $options['access']['links']['access_options'] = t('Change settings for this access type.');
01265 }
01266
01267 $cache_plugin = $this->get_plugin('cache');
01268 if (!$cache_plugin) {
01269
01270 $cache_plugin = views_get_plugin('cache', 'none');
01271 }
01272
01273 $cache_str = $cache_plugin->summary_title();
01274
01275 $options['cache'] = array(
01276 'category' => 'other',
01277 'title' => t('Caching'),
01278 'value' => $cache_plugin->plugin_title(),
01279 'setting' => $cache_str,
01280 'desc' => t('Specify caching type for this display.'),
01281 );
01282
01283 if (!empty($cache_plugin->definition['uses options'])) {
01284 $options['cache']['links']['cache_options'] = t('Change settings for this caching type.');
01285 }
01286
01287 if (!empty($access_plugin->definition['uses options'])) {
01288 $options['access']['links']['access_options'] = t('Change settings for this access type.');
01289 }
01290
01291 if ($this->uses_link_display()) {
01292 $display_id = $this->get_link_display();
01293 $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title);
01294 $link_display = $this->get_option('link_display') == 'custom_url' ? t('Custom URL') : $link_display;
01295 $options['link_display'] = array(
01296 'category' => 'other',
01297 'title' => t('Link display'),
01298 'value' => $link_display,
01299 'desc' => t('Specify which display or custom url this display will link to.'),
01300 );
01301 }
01302
01303 if ($this->uses_exposed_form_in_block()) {
01304 $options['exposed_block'] = array(
01305 'category' => 'exposed',
01306 'title' => t('Exposed form in block'),
01307 'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'),
01308 'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
01309 );
01310 }
01311
01312 $exposed_form_plugin = $this->get_plugin('exposed_form');
01313 if (!$exposed_form_plugin) {
01314
01315 $exposed_form_plugin = views_get_plugin('exposed_form', 'basic');
01316 }
01317
01318 $exposed_form_str = $exposed_form_plugin->summary_title();
01319
01320 $options['exposed_form'] = array(
01321 'category' => 'exposed',
01322 'title' => t('Exposed form style'),
01323 'value' => $exposed_form_plugin->plugin_title(),
01324 'setting' => $exposed_form_str,
01325 'desc' => t('Select the kind of exposed filter to use.'),
01326 );
01327
01328 if (!empty($exposed_form_plugin->definition['uses options'])) {
01329 $options['exposed_form']['links']['exposed_form_options'] = t('Exposed form settings for this exposed form style.');
01330 }
01331
01332 $css_class = check_plain(trim($this->get_option('css_class')));
01333 if (!$css_class) {
01334 $css_class = t('None');
01335 }
01336
01337 $options['css_class'] = array(
01338 'category' => 'other',
01339 'title' => t('CSS class'),
01340 'value' => $css_class,
01341 'desc' => t('Change the CSS class name(s) that will be added to this display.'),
01342 );
01343
01344 $options['analyze-theme'] = array(
01345 'category' => 'other',
01346 'title' => t('Theme'),
01347 'value' => t('Information'),
01348 'desc' => t('Get information on how to theme this display'),
01349 );
01350
01351 foreach ($this->extender as $extender) {
01352 $extender->options_summary($categories, $options);
01353 }
01354 }
01355
01359 function options_form(&$form, &$form_state) {
01360 parent::options_form($form, $form_state);
01361 if ($this->defaultable_sections($form_state['section'])) {
01362 views_ui_standard_display_dropdown($form, $form_state, $form_state['section']);
01363 }
01364 $form['#title'] = check_plain($this->display->display_title) . ': ';
01365
01366
01367
01368
01369
01370 if (!empty($this->options['defaults'][$form_state['section']])) {
01371 $form['#section'] = 'default-' . $form_state['section'];
01372 }
01373 else {
01374 $form['#section'] = $this->display->id . '-' . $form_state['section'];
01375 }
01376
01377 switch ($form_state['section']) {
01378 case 'display_id':
01379 $form['#title'] .= t('The machine name of this display');
01380 $form['display_id'] = array(
01381 '#type' => 'textfield',
01382 '#description' => t('This is machine name of the display.'),
01383 '#default_value' => !empty($this->display->new_id) ? $this->display->new_id : $this->display->id,
01384 '#required' => TRUE,
01385 '#size' => 64,
01386 );
01387 break;
01388 case 'display_title':
01389 $form['#title'] .= t('The name and the description of this display');
01390 $form['display_title'] = array(
01391 '#title' => t('Name'),
01392 '#type' => 'textfield',
01393 '#description' => t('This name will appear only in the administrative interface for the View.'),
01394 '#default_value' => $this->display->display_title,
01395 );
01396 $form['display_description'] = array(
01397 '#title' => t('Description'),
01398 '#type' => 'textfield',
01399 '#description' => t('This description will appear only in the administrative interface for the View.'),
01400 '#default_value' => $this->get_option('display_description'),
01401 );
01402 break;
01403 case 'display_comment':
01404 $form['#title'] .= t("This display's comments");
01405 $form['display_comment'] = array(
01406 '#type' => 'textarea',
01407 '#description' => t('This value will be seen and used only within the Views UI and can be used to document this display. You can use this to provide notes for other or future maintainers of your site about how or why this display is configured.'),
01408 '#default_value' => $this->get_option('display_comment'),
01409 );
01410 break;
01411 case 'title':
01412 $form['#title'] .= t('The title of this view');
01413 $form['title'] = array(
01414 '#type' => 'textfield',
01415 '#description' => t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'),
01416 '#default_value' => $this->get_option('title'),
01417 );
01418 break;
01419 case 'css_class':
01420 $form['#title'] .= t('CSS class');
01421 $form['css_class'] = array(
01422 '#type' => 'textfield',
01423 '#description' => t('The CSS class names will be added to the view. This enables you to use specific CSS code for each view. You may define multiples classes separated by spaces.'),
01424 '#default_value' => $this->get_option('css_class'),
01425 );
01426 break;
01427 case 'use_ajax':
01428 $form['#title'] .= t('Use AJAX when available to load this view');
01429 $form['description'] = array(
01430 '#markup' => '<div class="description form-item">' . 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.') . '</div>',
01431 );
01432 $form['use_ajax'] = array(
01433 '#type' => 'radios',
01434 '#options' => array(1 => t('Yes'), 0 => t('No')),
01435 '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
01436 );
01437 break;
01438 case 'hide_attachment_summary':
01439 $form['#title'] .= t('Hide attachments when displaying a contextual filter summary');
01440 $form['hide_attachment_summary'] = array(
01441 '#type' => 'radios',
01442 '#options' => array(1 => t('Yes'), 0 => t('No')),
01443 '#default_value' => $this->get_option('hide_attachment_summary') ? 1 : 0,
01444 );
01445 break;
01446 case 'use_more':
01447 $form['#title'] .= t('Add a more link to the bottom of the display.');
01448 $form['use_more'] = array(
01449 '#type' => 'checkbox',
01450 '#title' => t('Create more link'),
01451 '#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. You can override the url at the link display setting."),
01452 '#default_value' => $this->get_option('use_more'),
01453 );
01454 $form['use_more_always'] = array(
01455 '#type' => 'checkbox',
01456 '#title' => t('Do not display more link unless there is more content'),
01457 '#description' => t("This will display the more link even if there are no more items to display."),
01458 '#default_value' => !$this->get_option('use_more_always'),
01459 '#dependency' => array(
01460 'edit-use-more' => array(TRUE),
01461 ),
01462 );
01463 $form['use_more_text'] = array(
01464 '#type' => 'textfield',
01465 '#title' => t('More link text'),
01466 '#description' => t("The text to display for the more link."),
01467 '#default_value' => $this->get_option('use_more_text'),
01468 '#dependency' => array(
01469 'edit-use-more' => array(TRUE),
01470 ),
01471 );
01472 break;
01473 case 'group_by':
01474 $form['#title'] .= t('Allow grouping and aggregation (calculation) of fields.');
01475 $form['group_by'] = array(
01476 '#type' => 'checkbox',
01477 '#title' => t('Aggregate'),
01478 '#description' => t('If enabled, some fields may become unavailable. All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.'),
01479 '#default_value' => $this->get_option('group_by'),
01480 );
01481 break;
01482 case 'access':
01483 $form['#title'] .= t('Access restrictions');
01484 $form['access'] = array(
01485 '#prefix' => '<div class="clearfix">',
01486 '#suffix' => '</div>',
01487 '#tree' => TRUE,
01488 );
01489
01490 $access = $this->get_option('access');
01491 $form['access']['type'] = array(
01492 '#type' => 'radios',
01493 '#options' => views_fetch_plugin_names('access', NULL, array($this->view->base_table)),
01494 '#default_value' => $access['type'],
01495 );
01496
01497 $access_plugin = views_fetch_plugin_data('access', $access['type']);
01498 if (!empty($access_plugin['uses options'])) {
01499 $form['markup'] = array(
01500 '#prefix' => '<div class="form-item description">',
01501 '#markup' => t('You may also adjust the !settings for the currently selected access restriction.', array('!settings' => $this->option_link(t('settings'), 'access_options'))),
01502 '#suffix' => '</div>',
01503 );
01504 }
01505
01506 break;
01507 case 'access_options':
01508 $access = $this->get_option('access');
01509 $plugin = $this->get_plugin('access');
01510 $form['#title'] .= t('Access options');
01511 if ($plugin) {
01512 $form['#help_topic'] = $plugin->definition['help topic'];
01513 $form['#help_module'] = $plugin->definition['module'];
01514
01515 $form['access_options'] = array(
01516 '#tree' => TRUE,
01517 );
01518 $form['access_options']['type'] = array(
01519 '#type' => 'value',
01520 '#value' => $access['type'],
01521 );
01522 $plugin->options_form($form['access_options'], $form_state);
01523 }
01524 break;
01525 case 'cache':
01526 $form['#title'] .= t('Caching');
01527 $form['cache'] = array(
01528 '#prefix' => '<div class="clearfix">',
01529 '#suffix' => '</div>',
01530 '#tree' => TRUE,
01531 );
01532
01533 $cache = $this->get_option('cache');
01534 $form['cache']['type'] = array(
01535 '#type' => 'radios',
01536 '#options' => views_fetch_plugin_names('cache', NULL, array($this->view->base_table)),
01537 '#default_value' => $cache['type'],
01538 );
01539
01540 $cache_plugin = views_fetch_plugin_data('cache', $cache['type']);
01541 if (!empty($cache_plugin['uses options'])) {
01542 $form['markup'] = array(
01543 '#prefix' => '<div class="form-item description">',
01544 '#suffix' => '</div>',
01545 '#markup' => t('You may also adjust the !settings for the currently selected cache mechanism.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))),
01546 );
01547 }
01548 break;
01549 case 'cache_options':
01550 $cache = $this->get_option('cache');
01551 $plugin = $this->get_plugin('cache');
01552 $form['#title'] .= t('Caching options');
01553 if ($plugin) {
01554 $form['#help_topic'] = $plugin->definition['help topic'];
01555 $form['#help_module'] = $plugin->definition['module'];
01556
01557 $form['cache_options'] = array(
01558 '#tree' => TRUE,
01559 );
01560 $form['cache_options']['type'] = array(
01561 '#type' => 'value',
01562 '#value' => $cache['type'],
01563 );
01564 $plugin->options_form($form['cache_options'], $form_state);
01565 }
01566 break;
01567 case 'query':
01568 $query_options = $this->get_option('query');
01569 $plugin_name = $query_options['type'];
01570
01571 $form['#title'] .= t('Query options');
01572 $this->view->init_query();
01573 if ($this->view->query) {
01574 if (isset($this->view->query->definition['help topic'])) {
01575 $form['#help_topic'] = $this->view->query->definition['help topic'];
01576 }
01577
01578 if (isset($this->view->query->definition['module'])) {
01579 $form['#help_module'] = $this->view->query->definition['module'];
01580 }
01581
01582 $form['query'] = array(
01583 '#tree' => TRUE,
01584 'type' => array(
01585 '#type' => 'value',
01586 '#value' => $plugin_name,
01587 ),
01588 'options' => array(
01589 '#tree' => TRUE,
01590 ),
01591 );
01592
01593 $this->view->query->options_form($form['query']['options'], $form_state);
01594 }
01595 break;
01596 case 'field_language':
01597 $form['#title'] .= t('Field Language');
01598
01599 $entities = entity_get_info();
01600 $entity_tables = array();
01601 $has_translation_handlers = FALSE;
01602 foreach ($entities as $type => $entity_info) {
01603 $entity_tables[] = $entity_info['base table'];
01604
01605 if (!empty($entity_info['translation'])) {
01606 $has_translation_handlers = TRUE;
01607 }
01608 }
01609
01610
01611
01612
01613 if (in_array($this->view->base_table, $entity_tables) && $has_translation_handlers) {
01614 $languages = array(
01615 '***CURRENT_LANGUAGE***' => t("Current user's language"),
01616 '***DEFAULT_LANGUAGE***' => t("Default site language"),
01617 LANGUAGE_NONE => t('Language neutral'),
01618 );
01619 $languages = array_merge($languages, views_language_list());
01620
01621 $form['field_language'] = array(
01622 '#type' => 'select',
01623 '#title' => t('Field Language'),
01624 '#description' => t('All fields which support translations will be displayed in the selected language.'),
01625 '#options' => $languages,
01626 '#default_value' => $this->get_option('field_language'),
01627 );
01628 $form['field_language_add_to_query'] = array(
01629 '#type' => 'checkbox',
01630 '#title' => t('When needed, add the field language condition to the query'),
01631 '#default_value' => $this->get_option('field_language_add_to_query'),
01632 );
01633 }
01634 else {
01635 $form['field_language']['#markup'] = t("You don't have translatable entity types.");
01636 }
01637 break;
01638 case 'style_plugin':
01639 $form['#title'] .= t('How should this view be styled');
01640 $form['#help_topic'] = 'style';
01641 $form['style_plugin'] = array(
01642 '#type' => 'radios',
01643 '#options' => views_fetch_plugin_names('style', $this->get_style_type(), array($this->view->base_table)),
01644 '#default_value' => $this->get_option('style_plugin'),
01645 '#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.'),
01646 );
01647
01648 $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin'));
01649 if (!empty($style_plugin['uses options'])) {
01650 $form['markup'] = array(
01651 '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected style.', array('!settings' => $this->option_link(t('settings'), 'style_options'))) . '</div>',
01652 );
01653 }
01654
01655 break;
01656 case 'style_options':
01657 $form['#title'] .= t('Style options');
01658 $style = TRUE;
01659 $type = 'style_plugin';
01660 $name = $this->get_option('style_plugin');
01661
01662 case 'row_options':
01663 if (!isset($name)) {
01664 $name = $this->get_option('row_plugin');
01665 }
01666
01667 if (empty($style)) {
01668 $form['#title'] .= t('Row style options');
01669 $type = 'row_plugin';
01670 }
01671 $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
01672 if ($plugin) {
01673 if (isset($plugin->definition['help topic'])) {
01674 $form['#help_topic'] = $plugin->definition['help topic'];
01675 $form['#help_module'] = $plugin->definition['module'];
01676 }
01677 $form[$form_state['section']] = array(
01678 '#tree' => TRUE,
01679 );
01680 $plugin->options_form($form[$form_state['section']], $form_state);
01681 }
01682 break;
01683 case 'row_plugin':
01684 $form['#title'] .= t('How should each row in this view be styled');
01685 $form['#help_topic'] = 'style-row';
01686 $form['row_plugin'] = array(
01687 '#type' => 'radios',
01688 '#options' => views_fetch_plugin_names('row', $this->get_style_type(), array($this->view->base_table)),
01689 '#default_value' => $this->get_option('row_plugin'),
01690 );
01691
01692 $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin'));
01693 if (!empty($row_plugin['uses options'])) {
01694 $form['markup'] = array(
01695 '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected row style.', array('!settings' => $this->option_link(t('settings'), 'row_options'))) . '</div>',
01696 );
01697 }
01698
01699 break;
01700 case 'link_display':
01701 $form['#title'] .= t('Which display to use for path');
01702 foreach ($this->view->display as $display_id => $display) {
01703 if ($display->handler->has_path()) {
01704 $options[$display_id] = $display->display_title;
01705 }
01706 }
01707 $options['custom_url'] = t('Custom URL');
01708 if (count($options)) {
01709 $form['link_display'] = array(
01710 '#type' => 'radios',
01711 '#options' => $options,
01712 '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."),
01713 '#default_value' => $this->get_option('link_display'),
01714 );
01715 }
01716
01717 $options = array();
01718 $count = 0;
01719 foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
01720 $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
01721 $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
01722 }
01723
01724
01725
01726 $output = '';
01727 if (!empty($options)) {
01728 $output = t('<p>The following tokens are available for this link.</p>');
01729 foreach (array_keys($options) as $type) {
01730 if (!empty($options[$type])) {
01731 $items = array();
01732 foreach ($options[$type] as $key => $value) {
01733 $items[] = $key . ' == ' . $value;
01734 }
01735 $output .= theme('item_list',
01736 array(
01737 'items' => $items,
01738 'type' => $type
01739 ));
01740 }
01741 }
01742 }
01743
01744 $form['link_url'] = array(
01745 '#type' => 'textfield',
01746 '#title' => t('Custom URL'),
01747 '#default_value' => $this->get_option('link_url'),
01748 '#description' => t('A Drupal path or external URL the more link will point to. Note that this will override the link display setting above.') . $output,
01749 '#dependency' => array('radio:link_display' => array('custom_url')),
01750 );
01751 break;
01752 case 'analyze-theme':
01753 $form['#title'] .= t('Theming information');
01754 $form['#help_topic'] = 'analyze-theme';
01755
01756 if (isset($_POST['theme'])) {
01757 $this->theme = $_POST['theme'];
01758 }
01759 elseif (empty($this->theme)) {
01760 $this->theme = variable_get('theme_default', 'bartik');
01761 }
01762
01763 if (isset($GLOBALS['theme']) && $GLOBALS['theme'] == $this->theme) {
01764 $this->theme_registry = theme_get_registry();
01765 $theme_engine = $GLOBALS['theme_engine'];
01766 }
01767 else {
01768 $themes = list_themes();
01769 $theme = $themes[$this->theme];
01770
01771
01772 $base_theme = array();
01773 $ancestor = $this->theme;
01774 while ($ancestor && isset($themes[$ancestor]->base_theme)) {
01775 $ancestor = $themes[$ancestor]->base_theme;
01776 $base_theme[] = $themes[$ancestor];
01777 }
01778
01779
01780 $base_theme = array_reverse($base_theme);
01781
01782
01783 $theme_engine = NULL;
01784
01785
01786 if (isset($theme->engine)) {
01787
01788 include_once DRUPAL_ROOT . '/' . $theme->owner;
01789
01790 $theme_engine = $theme->engine;
01791 if (function_exists($theme_engine . '_init')) {
01792 foreach ($base_theme as $base) {
01793 call_user_func($theme_engine . '_init', $base);
01794 }
01795 call_user_func($theme_engine . '_init', $theme);
01796 }
01797 }
01798 else {
01799
01800 foreach ($base_theme as $base) {
01801
01802 if (!empty($base->owner)) {
01803 include_once DRUPAL_ROOT . '/' . $base->owner;
01804 }
01805 }
01806
01807 if (!empty($theme->owner)) {
01808 include_once DRUPAL_ROOT . '/' . $theme->owner;
01809 }
01810 }
01811 $this->theme_registry = _theme_load_registry($theme, $base_theme, $theme_engine);
01812 }
01813
01814
01815
01816 $this->theme_extension = '.tpl.php';
01817 if (isset($theme_engine)) {
01818 $extension_function = $theme_engine . '_extension';
01819 if (function_exists($extension_function)) {
01820 $this->theme_extension = $extension_function();
01821 }
01822 }
01823
01824 $funcs = array();
01825
01826
01827
01828 if (!empty($this->definition['theme'])) {
01829 $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': ' . $this->format_themes($this->theme_functions());
01830 $themes = $this->additional_theme_functions();
01831 if ($themes) {
01832 foreach ($themes as $theme) {
01833 $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': ' . $this->format_themes($theme);
01834 }
01835 }
01836 }
01837
01838 $plugin = $this->get_plugin();
01839 if ($plugin) {
01840 $funcs[] = $this->option_link(t('Style output'), 'analyze-theme-style') . ': ' . $this->format_themes($plugin->theme_functions(), $plugin->additional_theme_functions());
01841 $themes = $plugin->additional_theme_functions();
01842 if ($themes) {
01843 foreach ($themes as $theme) {
01844 $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': ' . $this->format_themes($theme);
01845 }
01846 }
01847
01848 if ($plugin->uses_row_plugin()) {
01849 $row_plugin = $this->get_plugin('row');
01850 if ($row_plugin) {
01851 $funcs[] = $this->option_link(t('Row style output'), 'analyze-theme-row') . ': ' . $this->format_themes($row_plugin->theme_functions());
01852 $themes = $row_plugin->additional_theme_functions();
01853 if ($themes) {
01854 foreach ($themes as $theme) {
01855 $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': ' . $this->format_themes($theme);
01856 }
01857 }
01858 }
01859 }
01860
01861 if ($plugin->uses_fields()) {
01862 foreach ($this->get_handlers('field') as $id => $handler) {
01863 $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());
01864 }
01865 }
01866 }
01867
01868 $form['important'] = array(
01869 '#markup' => '<div class="form-item description"><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></div>',
01870 );
01871
01872 if (isset($this->view->display[$this->view->current_display]->new_id)) {
01873 $form['important']['new_id'] = array(
01874 '#prefix' => '<div class="description">',
01875 '#suffix' => '</div>',
01876 '#value' => t("<strong>Important!</strong> You have changed the display's machine name. Anything that attached to this display specifically, such as theming, may stop working until it is updated. To see theme suggestions for it, you need to save the view."),
01877 );
01878 }
01879
01880 foreach (list_themes() as $key => $theme) {
01881 if (!empty($theme->info['hidden'])) {
01882 continue;
01883 }
01884 $options[$key] = $theme->info['name'];
01885 }
01886
01887 $form['box'] = array(
01888 '#prefix' => '<div class="container-inline">',
01889 '#suffix' => '</div>',
01890 );
01891 $form['box']['theme'] = array(
01892 '#type' => 'select',
01893 '#options' => $options,
01894 '#default_value' => $this->theme,
01895 );
01896
01897 $form['box']['change'] = array(
01898 '#type' => 'submit',
01899 '#value' => t('Change theme'),
01900 '#submit' => array('views_ui_edit_display_form_change_theme'),
01901 );
01902
01903 $form['analysis'] = array(
01904 '#markup' => '<div class="form-item">' . theme('item_list', array('items' => $funcs)) . '</div>',
01905 );
01906
01907 $form['rescan_button'] = array(
01908 '#prefix' => '<div class="form-item">',
01909 '#suffix' => '</div>',
01910 );
01911 $form['rescan_button']['button'] = array(
01912 '#type' => 'submit',
01913 '#value' => t('Rescan template files'),
01914 '#submit' => array('views_ui_config_item_form_rescan'),
01915 );
01916 $form['rescan_button']['markup'] = array(
01917 '#markup' => '<div class="description">' . 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.") . '</div>',
01918 );
01919
01920 $form_state['ok_button'] = TRUE;
01921 break;
01922 case 'analyze-theme-display':
01923 $form['#title'] .= t('Theming information (display)');
01924 $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01925
01926 if (empty($this->definition['theme'])) {
01927 $output .= t('This display has no theming information');
01928 }
01929 else {
01930 $output .= '<p>' . t('This is the default theme template used for this display.') . '</p>';
01931 $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($this->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
01932 }
01933
01934 if (!empty($this->definition['additional themes'])) {
01935 foreach ($this->definition['additional themes'] as $theme => $type) {
01936 $output .= '<p>' . t('This is an alternative template for this display.') . '</p>';
01937 $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
01938 }
01939 }
01940
01941 $form['analysis'] = array(
01942 '#markup' => '<div class="form-item">' . $output . '</div>',
01943 );
01944
01945 $form_state['ok_button'] = TRUE;
01946 break;
01947 case 'analyze-theme-style':
01948 $form['#title'] .= t('Theming information (style)');
01949 $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01950
01951 $plugin = $this->get_plugin();
01952
01953 if (empty($plugin->definition['theme'])) {
01954 $output .= t('This display has no style theming information');
01955 }
01956 else {
01957 $output .= '<p>' . t('This is the default theme template used for this style.') . '</p>';
01958 $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
01959 }
01960
01961 if (!empty($plugin->definition['additional themes'])) {
01962 foreach ($plugin->definition['additional themes'] as $theme => $type) {
01963 $output .= '<p>' . t('This is an alternative template for this style.') . '</p>';
01964 $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
01965 }
01966 }
01967
01968 $form['analysis'] = array(
01969 '#markup' => '<div class="form-item">' . $output . '</div>',
01970 );
01971
01972 $form_state['ok_button'] = TRUE;
01973 break;
01974 case 'analyze-theme-row':
01975 $form['#title'] .= t('Theming information (row style)');
01976 $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
01977
01978 $plugin = $this->get_plugin('row');
01979
01980 if (empty($plugin->definition['theme'])) {
01981 $output .= t('This display has no row style theming information');
01982 }
01983 else {
01984 $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
01985 $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>';
01986 }
01987
01988 if (!empty($plugin->definition['additional themes'])) {
01989 foreach ($plugin->definition['additional themes'] as $theme => $type) {
01990 $output .= '<p>' . t('This is an alternative template for this row style.') . '</p>';
01991 $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>';
01992 }
01993 }
01994
01995 $form['analysis'] = array(
01996 '#markup' => '<div class="form-item">' . $output . '</div>',
01997 );
01998
01999 $form_state['ok_button'] = TRUE;
02000 break;
02001 case 'analyze-theme-field':
02002 $form['#title'] .= t('Theming information (row style)');
02003 $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>';
02004
02005 $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>';
02006
02007
02008
02009 $output .= '<pre>' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/theme/views-view-field.tpl.php')) . '</pre>';
02010
02011 $form['analysis'] = array(
02012 '#markup' => '<div class="form-item">' . $output . '</div>',
02013 );
02014 $form_state['ok_button'] = TRUE;
02015 break;
02016
02017 case 'exposed_block':
02018 $form['#title'] .= t('Put the exposed form in a block');
02019 $form['description'] = array(
02020 '#markup' => '<div class="description form-item">' . 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.') . '</div>',
02021 );
02022 $form['exposed_block'] = array(
02023 '#type' => 'radios',
02024 '#options' => array(1 => t('Yes'), 0 => t('No')),
02025 '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
02026 );
02027 break;
02028 case 'exposed_form':
02029 $form['#title'] .= t('Exposed Form');
02030 $form['exposed_form'] = array(
02031 '#prefix' => '<div class="clearfix">',
02032 '#suffix' => '</div>',
02033 '#tree' => TRUE,
02034 );
02035
02036 $exposed_form = $this->get_option('exposed_form');
02037 $form['exposed_form']['type'] = array(
02038 '#type' => 'radios',
02039 '#options' => views_fetch_plugin_names('exposed_form', NULL, array($this->view->base_table)),
02040 '#default_value' => $exposed_form['type'],
02041 );
02042
02043 $exposed_form_plugin = views_fetch_plugin_data('exposed_form', $exposed_form['type']);
02044 if (!empty($exposed_form_plugin['uses options'])) {
02045 $form['markup'] = array(
02046 '#prefix' => '<div class="form-item description">',
02047 '#suffix' => '</div>',
02048 '#markup' => t('You may also adjust the !settings for the currently selected style.', array('!settings' => $this->option_link(t('settings'), 'exposed_form_options'))),
02049 );
02050 }
02051 break;
02052 case 'exposed_form_options':
02053 $plugin = $this->get_plugin('exposed_form');
02054 $form['#title'] .= t('Exposed form options');
02055 if ($plugin) {
02056 $form['#help_topic'] = $plugin->definition['help topic'];
02057
02058 $form['exposed_form_options'] = array(
02059 '#tree' => TRUE,
02060 );
02061 $plugin->options_form($form['exposed_form_options'], $form_state);
02062 }
02063 break;
02064 case 'pager':
02065 $form['#title'] .= t('Select which pager, if any, to use for this view');
02066 $form['pager'] = array(
02067 '#prefix' => '<div class="clearfix">',
02068 '#suffix' => '</div>',
02069 '#tree' => TRUE,
02070 );
02071
02072 $pager = $this->get_option('pager');
02073 $form['pager']['type'] = array(
02074 '#type' => 'radios',
02075 '#options' => views_fetch_plugin_names('pager', empty($this->definition['use pager']) ? 'basic' : NULL, array($this->view->base_table)),
02076 '#default_value' => $pager['type'],
02077 );
02078
02079 $pager_plugin = views_fetch_plugin_data('pager', $pager['type'], array($this->view->base_table));
02080 if (!empty($pager_plugin['uses options'])) {
02081 $form['markup'] = array(
02082 '#prefix' => '<div class="form-item description">',
02083 '#suffix' => '</div>',
02084 '#markup' => t('You may also adjust the !settings for the currently selected pager.', array('!settings' => $this->option_link(t('settings'), 'pager_options'))),
02085 );
02086 }
02087
02088 break;
02089 case 'pager_options':
02090 $plugin = $this->get_plugin('pager');
02091 $form['#title'] .= t('Pager options');
02092 if ($plugin) {
02093 $form['#help_topic'] = $plugin->definition['help topic'];
02094
02095 $form['pager_options'] = array(
02096 '#tree' => TRUE,
02097 );
02098 $plugin->options_form($form['pager_options'], $form_state);
02099 }
02100 break;
02101 }
02102
02103 foreach ($this->extender as $extender) {
02104 $extender->options_form($form, $form_state);
02105 }
02106 }
02107
02111 function format_themes($themes) {
02112 $registry = $this->theme_registry;
02113 $extension = $this->theme_extension;
02114
02115 $output = '';
02116 $picked = FALSE;
02117 foreach ($themes as $theme) {
02118 $template = strtr($theme, '_', '-') . $extension;
02119 if (!$picked && !empty($registry[$theme])) {
02120 $template_path = isset($registry[$theme]['path']) ? $registry[$theme]['path'] . '/' : './';
02121 if (file_exists($template_path . $template)) {
02122 $hint = t('File found in folder @template-path', array('@template-path' => $template_path));
02123 $template = '<strong title="'. $hint .'">' . $template . '</strong>';
02124 }
02125 else {
02126 $template = '<strong class="error">' . $template . ' ' . t('(File not found, in folder @template-path)', array('@template-path' => $template_path)) . '</strong>';
02127 }
02128 $picked = TRUE;
02129 }
02130 $fixed[] = $template;
02131 }
02132
02133 return implode(', ', array_reverse($fixed));
02134 }
02135
02139 function options_validate(&$form, &$form_state) {
02140 switch ($form_state['section']) {
02141 case 'display_title':
02142 if (empty($form_state['values']['display_title'])) {
02143 form_error($form['display_title'], t('Display title may not be empty.'));
02144 }
02145 break;
02146 case 'css_class':
02147 $css_class = $form_state['values']['css_class'];
02148 if (preg_match('/[^a-zA-Z0-9-_ ]/', $css_class)) {
02149 form_error($form['css_class'], t('CSS classes must be alphanumeric or dashes only.'));
02150 }
02151 break;
02152 case 'display_id':
02153 if ($form_state['values']['display_id']) {
02154 if (preg_match('/[^a-z0-9_]/', $form_state['values']['display_id'])) {
02155 form_error($form['display_id'], t('Display name must be letters, numbers, or underscores only.'));
02156 }
02157
02158 foreach ($this->view->display as $id => $display) {
02159 if ($id != $this->view->current_display && ($form_state['values']['display_id'] == $id || (isset($display->new_id) && $form_state['values']['display_id'] == $display->new_id))) {
02160 form_error($form['display_id'], t('Display id should be unique.'));
02161 }
02162 }
02163 }
02164 break;
02165 case 'style_options':
02166 $style = TRUE;
02167 case 'row_options':
02168
02169 $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
02170 if ($plugin) {
02171 $plugin->options_validate($form[$form_state['section']], $form_state);
02172 }
02173 break;
02174 case 'access_options':
02175 $plugin = $this->get_plugin('access');
02176 if ($plugin) {
02177 $plugin->options_validate($form['access_options'], $form_state);
02178 }
02179 break;
02180 case 'query':
02181 if ($this->view->query) {
02182 $this->view->query->options_validate($form['query'], $form_state);
02183 }
02184 break;
02185 case 'cache_options':
02186 $plugin = $this->get_plugin('cache');
02187 if ($plugin) {
02188 $plugin->options_validate($form['cache_options'], $form_state);
02189 }
02190 break;
02191 case 'exposed_form_options':
02192 $plugin = $this->get_plugin('exposed_form');
02193 if ($plugin) {
02194 $plugin->options_validate($form['exposed_form_options'], $form_state);
02195 }
02196 break;
02197 case 'pager_options':
02198 $plugin = $this->get_plugin('pager');
02199 if ($plugin) {
02200 $plugin->options_validate($form['pager_options'], $form_state);
02201 }
02202 break;
02203 }
02204
02205 foreach ($this->extender as $extender) {
02206 $extender->options_validate($form, $form_state);
02207 }
02208 }
02209
02214 function options_submit(&$form, &$form_state) {
02215
02216 $cache_plugin = $this->get_plugin('cache');
02217 if ($cache_plugin) {
02218 $cache_plugin->cache_flush();
02219 }
02220
02221 $section = $form_state['section'];
02222 switch ($section) {
02223 case 'display_id':
02224 if (isset($form_state['values']['display_id'])) {
02225 $this->display->new_id = $form_state['values']['display_id'];
02226 }
02227 break;
02228 case 'display_title':
02229 $this->display->display_title = $form_state['values']['display_title'];
02230 $this->set_option('display_description', $form_state['values']['display_description']);
02231 break;
02232 case 'access':
02233 $access = $this->get_option('access');
02234 if ($access['type'] != $form_state['values']['access']['type']) {
02235 $plugin = views_get_plugin('access', $form_state['values']['access']['type']);
02236 if ($plugin) {
02237 $access = array('type' => $form_state['values']['access']['type']);
02238 $this->set_option('access', $access);
02239 if (!empty($plugin->definition['uses options'])) {
02240 views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('access_options'));
02241 }
02242 }
02243 }
02244
02245 break;
02246 case 'access_options':
02247 $plugin = views_get_plugin('access', $form_state['values'][$section]['type']);
02248 if ($plugin) {
02249 $plugin->options_submit($form['access_options'], $form_state);
02250 $this->set_option('access', $form_state['values'][$section]);
02251 }
02252 break;
02253 case 'cache':
02254 $cache = $this->get_option('cache');
02255 if ($cache['type'] != $form_state['values']['cache']['type']) {
02256 $plugin = views_get_plugin('cache', $form_state['values']['cache']['type']);
02257 if ($plugin) {
02258 $cache = array('type' => $form_state['values']['cache']['type']);
02259 $this->set_option('cache', $cache);
02260 if (!empty($plugin->definition['uses options'])) {
02261 views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('cache_options'));
02262 }
02263 }
02264 }
02265
02266 break;
02267 case 'cache_options':
02268 $plugin = views_get_plugin('cache', $form_state['values'][$section]['type']);
02269 if ($plugin) {
02270 $plugin->options_submit($form['cache_options'], $form_state);
02271 $this->set_option('cache', $form_state['values'][$section]);
02272 }
02273 break;
02274 case 'query':
02275 $plugin = $this->get_plugin('query');
02276 if ($plugin) {
02277 $plugin->options_submit($form['query']['options'], $form_state);
02278 $this->set_option('query', $form_state['values'][$section]);
02279 }
02280 break;
02281
02282 case 'link_display':
02283 $this->set_option('link_url', $form_state['values']['link_url']);
02284 case 'title':
02285 case 'css_class':
02286 case 'display_comment':
02287 $this->set_option($section, $form_state['values'][$section]);
02288 break;
02289 case 'field_language':
02290 $this->set_option('field_language', $form_state['values']['field_language']);
02291 $this->set_option('field_language_add_to_query', $form_state['values']['field_language_add_to_query']);
02292 break;
02293 case 'use_ajax':
02294 case 'hide_attachment_summary':
02295 $this->set_option($section, (bool)$form_state['values'][$section]);
02296 break;
02297 case 'use_more':
02298 $this->set_option($section, intval($form_state['values'][$section]));
02299 $this->set_option('use_more_always', !intval($form_state['values']['use_more_always']));
02300 $this->set_option('use_more_text', $form_state['values']['use_more_text']);
02301 case 'distinct':
02302 $this->set_option($section, $form_state['values'][$section]);
02303 break;
02304 case 'group_by':
02305 $this->set_option($section, $form_state['values'][$section]);
02306 break;
02307 case 'row_plugin':
02308
02309
02310 if ($this->get_option($section) != $form_state['values'][$section]) {
02311 $plugin = views_get_plugin('row', $form_state['values'][$section]);
02312 if ($plugin) {
02313 $this->set_option($section, $form_state['values'][$section]);
02314 $this->set_option('row_options', array());
02315
02316
02317 if (!empty($plugin->definition['uses options'])) {
02318 views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('row_options'));
02319 }
02320 }
02321 }
02322 break;
02323 case 'style_plugin':
02324
02325
02326 if ($this->get_option($section) != $form_state['values'][$section]) {
02327 $plugin = views_get_plugin('style', $form_state['values'][$section]);
02328 if ($plugin) {
02329 $this->set_option($section, $form_state['values'][$section]);
02330 $this->set_option('style_options', array());
02331
02332 if (!empty($plugin->definition['uses options'])) {
02333 views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('style_options'));
02334 }
02335 }
02336 }
02337 break;
02338 case 'style_options':
02339 $style = TRUE;
02340 case 'row_options':
02341
02342 $plugin = $this->get_plugin(empty($style) ? 'row' : 'style');
02343 if ($plugin) {
02344 $plugin->options_submit($form['options'][$section], $form_state);
02345 }
02346 $this->set_option($section, $form_state['values'][$section]);
02347 break;
02348 case 'exposed_block':
02349 $this->set_option($section, (bool) $form_state['values'][$section]);
02350 break;
02351 case 'exposed_form':
02352 $exposed_form = $this->get_option('exposed_form');
02353 if ($exposed_form['type'] != $form_state['values']['exposed_form']['type']) {
02354 $plugin = views_get_plugin('exposed_form', $form_state['values']['exposed_form']['type']);
02355 if ($plugin) {
02356 $exposed_form = array('type' => $form_state['values']['exposed_form']['type'], 'options' => array());
02357 $this->set_option('exposed_form', $exposed_form);
02358 if (!empty($plugin->definition['uses options'])) {
02359 views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('exposed_form_options'));
02360 }
02361 }
02362 }
02363
02364 break;
02365 case 'exposed_form_options':
02366 $plugin = $this->get_plugin('exposed_form');
02367 if ($plugin) {
02368 $exposed_form = $this->get_option('exposed_form');
02369 $plugin->options_submit($form['exposed_form_options'], $form_state);
02370 $exposed_form['options'] = $form_state['values'][$section];
02371 $this->set_option('exposed_form', $exposed_form);
02372 }
02373 break;
02374 case 'pager':
02375 $pager = $this->get_option('pager');
02376 if ($pager['type'] != $form_state['values']['pager']['type']) {
02377 $plugin = views_get_plugin('pager', $form_state['values']['pager']['type']);
02378 if ($plugin) {
02379
02380
02381 $plugin->init($this->view, $this->display, $pager['options']);
02382
02383 $pager = array('type' => $form_state['values']['pager']['type'], 'options' => $plugin->options);
02384 $this->set_option('pager', $pager);
02385 if (!empty($plugin->definition['uses options'])) {
02386 views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('pager_options'));
02387 }
02388 }
02389 }
02390
02391 break;
02392 case 'pager_options':
02393 $plugin = $this->get_plugin('pager');
02394 if ($plugin) {
02395 $pager = $this->get_option('pager');
02396 $plugin->options_submit($form['pager_options'], $form_state);
02397 $pager['options'] = $form_state['values'][$section];
02398 $this->set_option('pager', $pager);
02399 }
02400 break;
02401 }
02402
02403 foreach ($this->extender as $extender) {
02404 $extender->options_submit($form, $form_state);
02405 }
02406 }
02407
02411 function options_override($form, &$form_state) {
02412 $this->set_override($form_state['section']);
02413 }
02414
02418 function set_override($section, $new_state = NULL) {
02419 $options = $this->defaultable_sections($section);
02420 if (!$options) {
02421 return;
02422 }
02423
02424 if (!isset($new_state)) {
02425 $new_state = empty($this->options['defaults'][$section]);
02426 }
02427
02428
02429 foreach ($options as $option) {
02430 if ($new_state) {
02431
02432 unset($this->options[$option]);
02433 unset($this->display->display_options[$option]);
02434 }
02435 else {
02436
02437 $this->options[$option] = $this->get_option($option);
02438 $this->display->display_options[$option] = $this->options[$option];
02439 }
02440 $this->options['defaults'][$option] = $new_state;
02441 $this->display->display_options['defaults'][$option] = $new_state;
02442 }
02443 }
02444
02448 function query() {
02449 foreach ($this->extender as $extender) {
02450 $extender->query();
02451 }
02452 }
02453
02457 function render_filters() { }
02458
02462 function render_pager() {
02463 return TRUE;
02464 }
02465
02469 function render_more_link() {
02470 if ($this->use_more() && ($this->use_more_always() || (!empty($this->view->query->pager) && $this->view->query->pager->has_more_records()))) {
02471 $path = $this->get_path();
02472
02473 if ($this->get_option('link_display') == 'custom_url' && $override_path = $this->get_option('link_url')) {
02474 $tokens = $this->get_arguments_tokens();
02475 $path = strtr($override_path, $tokens);
02476 }
02477
02478 if ($path) {
02479 if (empty($override_path)) {
02480 $path = $this->view->get_url(NULL, $path);
02481 }
02482 $url_options = array();
02483 if (!empty($this->view->exposed_raw_input)) {
02484 $url_options['query'] = $this->view->exposed_raw_input;
02485 }
02486 $theme = views_theme_functions('views_more', $this->view, $this->display);
02487 $path = check_url(url($path, $url_options));
02488
02489 return theme($theme, array('more_url' => $path, 'link_text' => check_plain($this->use_more_text()), 'view' => $this->view));
02490 }
02491 }
02492 }
02493
02494
02502 function render_header() {
02503 $empty = !empty($this->view->result);
02504 return $this->render_area('header', $empty);
02505 }
02506
02510 function render_footer() {
02511 $empty = !empty($this->view->result);
02512 return $this->render_area('footer', $empty);
02513 }
02514
02515 function render_empty() {
02516 return $this->render_area('empty');
02517 }
02518
02522 function hook_block_list($delta = 0, $edit = array()) { return array(); }
02523
02527 function hook_menu() { return array(); }
02528
02532 function render() {
02533 return theme($this->theme_functions(), array('view' => $this->view));
02534 }
02535
02536 function render_area($area, $empty = FALSE) {
02537 $return = '';
02538 foreach ($this->get_handlers($area) as $area) {
02539 $return .= $area->render($empty);
02540 }
02541 return $return;
02542 }
02543
02544
02548 function access($account = NULL) {
02549 if (!isset($account)) {
02550 global $user;
02551 $account = $user;
02552 }
02553
02554
02555 if (user_access('access all views', $account)) {
02556 return TRUE;
02557 }
02558
02559 $plugin = $this->get_plugin('access');
02560 if ($plugin) {
02561 return $plugin->access($account);
02562 }
02563
02564
02565 return TRUE;
02566 }
02567
02573 function pre_execute() {
02574 $this->view->set_use_ajax($this->use_ajax());
02575 if ($this->use_more() && !$this->use_more_always()) {
02576 $this->view->get_total_rows = TRUE;
02577 }
02578 $this->view->init_handlers();
02579 if ($this->uses_exposed()) {
02580 $exposed_form = $this->get_plugin('exposed_form');
02581 $exposed_form->pre_execute();
02582 }
02583
02584 foreach ($this->extender as $extender) {
02585 $extender->pre_execute();
02586 }
02587 }
02588
02595 function execute() { }
02596
02601 function preview() { return $this->view->render(); }
02602
02607 function get_style_type() { return 'normal'; }
02608
02615 function validate() {
02616 $errors = array();
02617
02618 if ($this->uses_fields()) {
02619 $fields = FALSE;
02620 foreach ($this->get_handlers('field') as $field) {
02621 if (empty($field->options['exclude'])) {
02622 $fields = TRUE;
02623 }
02624 }
02625
02626 if (!$fields) {
02627 $errors[] = t('Display "@display" uses fields but there are none defined for it or all are excluded.', array('@display' => $this->display->display_title));
02628 }
02629 }
02630
02631 if ($this->has_path() && !$this->get_option('path')) {
02632 $errors[] = t('Display "@display" uses a path but the path is undefined.', array('@display' => $this->display->display_title));
02633 }
02634
02635
02636 $style = $this->get_plugin();
02637 if (empty($style)) {
02638 $errors[] = t('Display "@display" has an invalid style plugin.', array('@display' => $this->display->display_title));
02639 }
02640 else {
02641 $result = $style->validate();
02642 if (!empty($result) && is_array($result)) {
02643 $errors = array_merge($errors, $result);
02644 }
02645 }
02646
02647
02648 $query = $this->get_plugin('query');
02649 $result = $query->validate();
02650 if (!empty($result) && is_array($result)) {
02651 $errors = array_merge($errors, $result);
02652 }
02653
02654
02655 foreach (views_object_types() as $type => $info) {
02656 foreach ($this->get_handlers($type) as $handler) {
02657 $result = $handler->validate();
02658 if (!empty($result) && is_array($result)) {
02659 $errors = array_merge($errors, $result);
02660 }
02661 }
02662 }
02663
02664 return $errors;
02665 }
02666
02670 function is_identifier_unique($id, $identifier) {
02671 foreach (views_object_types() as $type => $info) {
02672 foreach ($this->get_handlers($type) as $key => $handler) {
02673 if ($handler->can_expose() && $handler->is_exposed()) {
02674 if ($id != $key && $identifier == $handler->options['expose']['identifier']) {
02675 return FALSE;
02676 }
02677 }
02678 }
02679 }
02680 return TRUE;
02681 }
02682
02686 function get_special_blocks() {
02687 $blocks = array();
02688
02689 if ($this->uses_exposed_form_in_block()) {
02690 $delta = '-exp-' . $this->view->name . '-' . $this->display->id;
02691 $desc = t('Exposed form: @view-@display_id', array('@view' => $this->view->name, '@display_id' => $this->display->id));
02692
02693 $blocks[$delta] = array(
02694 'info' => $desc,
02695 'cache' => DRUPAL_NO_CACHE,
02696 );
02697 }
02698
02699 return $blocks;
02700 }
02701
02705 function view_special_blocks($type) {
02706 if ($type == '-exp') {
02707
02708 if (arg(0) == 'admin' && arg(1) == 'structure' && arg(2) == 'views') {
02709 return;
02710 }
02711 $this->view->init_handlers();
02712
02713 if ($this->uses_exposed() && $this->get_option('exposed_block')) {
02714 $exposed_form = $this->get_plugin('exposed_form');
02715 return array(
02716 'content' => $exposed_form->render_exposed_form(TRUE),
02717 );
02718 }
02719 }
02720 }
02721
02728 function export_option($indent, $prefix, $storage, $option, $definition, $parents) {
02729
02730 $prefix = '$handler->display->display_options';
02731 $output = '';
02732 if (!$parents && !$this->is_default_display()) {
02733
02734 if ($this->is_defaulted($option)) {
02735 return;
02736 }
02737
02738
02739
02740 if ($this->defaultable_sections($option)) {
02741 $output .= $indent . $prefix . "['defaults']['$option'] = FALSE;\n";
02742 }
02743 }
02744
02745 $output .= parent::export_option($indent, $prefix, $storage, $option, $definition, $parents);
02746 return $output;
02747 }
02748
02757 function export_handler($indent, $prefix, $storage, $option, $definition, $parents) {
02758 $output = '';
02759
02760
02761
02762 if ($option != 'header' && $option != 'footer' && $option != 'empty') {
02763 $type = substr($option, 0, -1);
02764 }
02765 else {
02766 $type = $option;
02767 }
02768 $types = views_object_types();
02769 foreach ($storage[$option] as $id => $info) {
02770 if (!empty($types[$type]['type'])) {
02771 $handler_type = $types[$type]['type'];
02772 }
02773 else {
02774 $handler_type = $type;
02775 }
02776
02777
02778
02779 $override = NULL;
02780 if ($this->use_group_by() && !empty($info['group_type'])) {
02781 if (empty($this->view->query)) {
02782 $this->view->init_query();
02783 }
02784 $aggregate = $this->view->query->get_aggregation_info();
02785 if (!empty($aggregate[$info['group_type']]['handler'][$type])) {
02786 $override = $aggregate[$info['group_type']]['handler'][$type];
02787 }
02788 }
02789 $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override);
02790 if ($handler) {
02791 $handler->init($this->view, $info);
02792 $output .= $indent . '/* ' . $types[$type]['stitle'] . ': ' . $handler->ui_name() . " */\n";
02793 $output .= $handler->export_options($indent, $prefix . "['$option']['$id']");
02794 }
02795
02796
02797 unset($handler);
02798 }
02799
02800 return $output;
02801 }
02802
02810 function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
02811 $output = '';
02812 $style_plugin = $this->get_plugin();
02813 if ($option == 'style_plugin') {
02814 $type = 'style';
02815 $options_field = 'style_options';
02816 $plugin = $style_plugin;
02817 }
02818 else {
02819 if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
02820 return;
02821 }
02822
02823 $type = 'row';
02824 $options_field = 'row_options';
02825 $plugin = $this->get_plugin('row');
02826
02827 }
02828
02829 if ($plugin) {
02830
02831 $value = $this->get_option($option);
02832 $output .= $indent . $prefix . "['$option'] = '$value';\n";
02833
02834
02835 $output .= $plugin->export_options($indent, $prefix . "['$options_field']");
02836 }
02837
02838 return $output;
02839 }
02840
02849 function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
02850 $output = '';
02851 $plugin_type = end($parents);
02852 $plugin = $this->get_plugin($plugin_type);
02853 if ($plugin) {
02854
02855 $value = $storage[$option];
02856 $new_prefix = $prefix . "['$plugin_type']";
02857
02858 $output .= $indent . $new_prefix . "['$option'] = '$value';\n";
02859
02860 if ($plugin_type != 'access' && $plugin_type!= 'cache') {
02861 $new_prefix .= "['options']";
02862 }
02863
02864
02865 $output .= $plugin->export_options($indent, $new_prefix);
02866 }
02867
02868 return $output;
02869 }
02870
02871 function unpack_style($indent, $prefix, $storage, $option, $definition, $parents) {
02872 $output = '';
02873 $style_plugin = $this->get_plugin();
02874 if ($option == 'style_plugin') {
02875 $type = 'style';
02876 $options_field = 'style_options';
02877 $plugin = $style_plugin;
02878 }
02879 else {
02880 if (!$style_plugin || !$style_plugin->uses_row_plugin()) {
02881 return;
02882 }
02883
02884 $type = 'row';
02885 $options_field = 'row_options';
02886 $plugin = $this->get_plugin('row');
02887
02888 }
02889
02890 if ($plugin) {
02891 return $plugin->unpack_translatables($translatable, $parents);
02892 }
02893 }
02894
02898 function unpack_plugin(&$translatable, $storage, $option, $definition, $parents) {
02899 $plugin_type = end($parents);
02900 $plugin = $this->get_plugin($plugin_type);
02901 if ($plugin) {
02902
02903 return $plugin->unpack_translatables($translatable, $parents);
02904 }
02905 }
02906
02915 function unpack_handler(&$translatable, $storage, $option, $definition, $parents) {
02916 $output = '';
02917
02918
02919
02920 if ($option != 'header' && $option != 'footer' && $option != 'empty') {
02921 $type = substr($option, 0, -1);
02922 }
02923 else {
02924 $type = $option;
02925 }
02926 $types = views_object_types();
02927 foreach ($storage[$option] as $id => $info) {
02928 if (!empty($types[$type]['type'])) {
02929 $handler_type = $types[$type]['type'];
02930 }
02931 else {
02932 $handler_type = $type;
02933 }
02934 $handler = views_get_handler($info['table'], $info['field'], $handler_type);
02935 if ($handler) {
02936 $handler->init($this->view, $info);
02937 $handler->unpack_translatables($translatable, array_merge($parents, array($type, $info['table'], $info['id'])));
02938 }
02939
02940
02941 unset($handler);
02942 }
02943
02944 return $output;
02945 }
02946
02958 function get_argument_text() {
02959 return array(
02960 'filter value not present' => t('When the filter value is <em>NOT</em> available'),
02961 'filter value present' => t('When the filter value <em>IS</em> available or a default is provided'),
02962 'description' => t("This display does not have a source for contextual filters, so no contextual filter value will be available unless you select 'Provide default'."),
02963 );
02964 }
02965
02972 function get_pager_text() {
02973 return array(
02974 'items per page title' => t('Items to display'),
02975 'items per page description' => t('The number of items to display. Enter 0 for no limit.')
02976 );
02977 }
02978 }
02979
02980