00001 <?php
00026 class views_handler_filter extends views_handler {
00031 var $value = NULL;
00032
00036 var $operator = '=';
00037
00042 var $always_multiple = FALSE;
00043
00048 var $no_operator = FALSE;
00049
00054 var $always_required = FALSE;
00055
00062 function init(&$view, &$options) {
00063 parent::init($view, $options);
00064
00065 $this->operator = $this->options['operator'];
00066 $this->value = $this->options['value'];
00067
00068
00069 if (!empty($options['exposed']) && !empty($options['expose']['optional']) && !isset($options['expose']['required'])) {
00070 $this->options['expose']['required'] = !$options['expose']['optional'];
00071 }
00072 if (!empty($options['exposed']) && !empty($options['expose']['single']) && !isset($options['expose']['multiple'])) {
00073 $this->options['expose']['multiple'] = !$options['expose']['single'];
00074 }
00075 if (!empty($options['exposed']) && !empty($options['expose']['operator']) && !isset($options['expose']['operator_id'])) {
00076 $this->options['expose']['operator_id'] = $options['expose']['operator_id'] = $options['expose']['operator'];
00077 }
00078
00079
00080
00081
00082 if ($this->view->display_handler->get_option('relationships')) {
00083 $this->definition['allow empty'] = TRUE;
00084 }
00085 }
00086
00087 function option_definition() {
00088 $options = parent::option_definition();
00089
00090 $options['operator'] = array('default' => '=');
00091 $options['value'] = array('default' => '');
00092 $options['group'] = array('default' => '1');
00093 $options['exposed'] = array('default' => FALSE);
00094 $options['expose'] = array(
00095 'contains' => array(
00096 'operator_id' => array('default' => FALSE),
00097 'label' => array('default' => '', 'translatable' => TRUE),
00098 'use_operator' => array('default' => 0),
00099 'operator' => array('default' => ''),
00100 'identifier' => array('default' => ''),
00101 'required' => array('default' => 0),
00102 'remember' => array('default' => 0),
00103 'multiple' => array('default' => 0),
00104 ),
00105 );
00106
00107 return $options;
00108 }
00109
00113 function admin_summary() {
00114 return check_plain((string) $this->operator) . ' ' . check_plain((string) $this->value);
00115 }
00116
00120 function can_expose() { return TRUE; }
00121
00128 function options_form(&$form, &$form_state) {
00129 parent::options_form($form, $form_state);
00130 if ($this->can_expose()) {
00131 $this->show_expose_button($form, $form_state);
00132 }
00133 $form['clear_markup_start'] = array(
00134 '#markup' => '<div class="clearfix">',
00135 );
00136
00137 $this->show_operator_form($form, $form_state);
00138
00139 $this->show_value_form($form, $form_state);
00140 $form['clear_markup_end'] = array(
00141 '#markup' => '</div>',
00142 );
00143 if ($this->can_expose()) {
00144
00145 $this->show_expose_form($form, $form_state);
00146 }
00147 }
00148
00152 function options_validate(&$form, &$form_state) {
00153 $this->operator_validate($form, $form_state);
00154 $this->value_validate($form, $form_state);
00155 if (!empty($this->options['exposed'])) {
00156 $this->expose_validate($form, $form_state);
00157 }
00158 }
00159
00163 function options_submit(&$form, &$form_state) {
00164 unset($form_state['values']['expose_button']);
00165 $this->operator_submit($form, $form_state);
00166 $this->value_submit($form, $form_state);
00167 if (!empty($this->options['exposed'])) {
00168 $this->expose_submit($form, $form_state);
00169 }
00170 }
00171
00175 function show_operator_form(&$form, &$form_state) {
00176 $this->operator_form($form, $form_state);
00177 $form['operator']['#prefix'] = '<div class="views-group-box views-left-30">';
00178 $form['operator']['#suffix'] = '</div>';
00179 }
00180
00189 function operator_form(&$form, &$form_state) {
00190 $options = $this->operator_options();
00191 if (!empty($options)) {
00192 $form['operator'] = array(
00193 '#type' => count($options) < 10 ? 'radios' : 'select',
00194 '#title' => t('Operator'),
00195 '#default_value' => $this->operator,
00196 '#options' => $options,
00197 );
00198 }
00199 }
00200
00205 function operator_options() { return array(); }
00206
00210 function operator_validate($form, &$form_state) { }
00211
00216 function operator_submit($form, &$form_state) { }
00217
00221 function show_value_form(&$form, &$form_state) {
00222 $this->value_form($form, $form_state);
00223 if (empty($this->no_operator)) {
00224 $form['value']['#prefix'] = '<div class="views-group-box views-right-70">' . (isset($form['value']['#prefix']) ? $form['value']['#prefix'] : '');
00225 $form['value']['#suffix'] = (isset($form['value']['#suffix']) ? $form['value']['#suffix'] : '') . '</div>';
00226 }
00227 }
00228
00237 function value_form(&$form, &$form_state) { $form['value'] = array(); }
00238
00242 function value_validate($form, &$form_state) { }
00243
00248 function value_submit($form, &$form_state) { }
00249
00253 function show_expose_button(&$form, &$form_state) {
00254 $form['expose_button'] = array(
00255 '#prefix' => '<div class="views-expose clearfix">',
00256 '#suffix' => '</div>',
00257
00258 '#weight' => -200,
00259 );
00260
00261
00262
00263 $form['expose_button']['checkbox'] = array(
00264 '#theme_wrappers' => array('container'),
00265 '#attributes' => array('class' => array('js-only')),
00266 );
00267 $form['expose_button']['checkbox']['checkbox'] = array(
00268 '#title' => t('Expose this filter to visitors, to allow them to change it'),
00269 '#type' => 'checkbox',
00270 );
00271
00272
00273 if (empty($this->options['exposed'])) {
00274 $form['expose_button']['markup'] = array(
00275 '#markup' => '<div class="description exposed-description">' . t('This filter is not exposed. Expose it to allow the users to change it.') . '</div>',
00276 );
00277 $form['expose_button']['button'] = array(
00278 '#limit_validation_errors' => array(),
00279 '#type' => 'submit',
00280 '#value' => t('Expose filter'),
00281 '#submit' => array('views_ui_config_item_form_expose'),
00282 );
00283 $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0;
00284 }
00285 else {
00286 $form['expose_button']['markup'] = array(
00287 '#markup' => '<div class="description exposed-description">' . t('This filter is exposed. If you hide it, users will not be able to change it.') . '</div>',
00288 );
00289 $form['expose_button']['button'] = array(
00290 '#limit_validation_errors' => array(),
00291 '#type' => 'submit',
00292 '#value' => t('Hide filter'),
00293 '#submit' => array('views_ui_config_item_form_expose'),
00294 );
00295 $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1;
00296 }
00297 }
00298
00304 function expose_form(&$form, &$form_state) {
00305 $form['#theme'] = 'views_ui_expose_filter_form';
00306
00307
00308
00309
00310 array_unshift($form['#pre_render'], 'views_ui_pre_render_flatten_data');
00311 $form['expose']['#flatten'] = TRUE;
00312
00313 if (empty($this->always_required)) {
00314 $form['expose']['required'] = array(
00315 '#type' => 'checkbox',
00316 '#title' => t('Required'),
00317 '#default_value' => $this->options['expose']['required'],
00318 );
00319 }
00320 else {
00321 $form['expose']['required'] = array(
00322 '#type' => 'value',
00323 '#value' => TRUE,
00324 );
00325 }
00326 $form['expose']['label'] = array(
00327 '#type' => 'textfield',
00328 '#default_value' => $this->options['expose']['label'],
00329 '#title' => t('Label'),
00330 '#size' => 40,
00331 );
00332
00333 if (!empty($form['operator']['#type'])) {
00334
00335 $form['operator']['#prefix'] = '<div class="views-group-box views-left-40">';
00336 $form['operator']['#suffix'] = '</div>';
00337 $form['value']['#prefix'] = '<div class="views-group-box views-right-60">';
00338 $form['value']['#suffix'] = '</div>';
00339
00340 $form['expose']['use_operator'] = array(
00341 '#type' => 'checkbox',
00342 '#title' => t('Expose operator'),
00343 '#description' => t('Allow the user to choose the operator.'),
00344 '#default_value' => !empty($this->options['expose']['use_operator']),
00345 );
00346 $form['expose']['operator_id'] = array(
00347 '#type' => 'textfield',
00348 '#default_value' => $this->options['expose']['operator_id'],
00349 '#title' => t('Operator identifier'),
00350 '#size' => 40,
00351 '#description' => t('This will appear in the URL after the ? to identify this operator.'),
00352 '#dependency' => array(
00353 'edit-options-expose-use-operator' => array(1)
00354 ),
00355 '#fieldset' => 'more',
00356 );
00357 }
00358 else {
00359 $form['expose']['operator_id'] = array(
00360 '#type' => 'value',
00361 '#value' => '',
00362 );
00363 }
00364
00365 if (empty($this->always_multiple)) {
00366 $form['expose']['multiple'] = array(
00367 '#type' => 'checkbox',
00368 '#title' => t('Allow multiple selections'),
00369 '#description' => t('Enable to allow users to select multiple items.'),
00370 '#default_value' => $this->options['expose']['multiple'],
00371 );
00372 }
00373 $form['expose']['remember'] = array(
00374 '#type' => 'checkbox',
00375 '#title' => t('Remember the last selection'),
00376 '#description' => t('Enable to remember the last selection made by the user.'),
00377 '#default_value' => $this->options['expose']['remember'],
00378 );
00379
00380 $form['expose']['identifier'] = array(
00381 '#type' => 'textfield',
00382 '#default_value' => $this->options['expose']['identifier'],
00383 '#title' => t('Filter identifier'),
00384 '#size' => 40,
00385 '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'),
00386 '#fieldset' => 'more',
00387 );
00388 }
00389
00393 function expose_validate($form, &$form_state) {
00394 if (empty($form_state['values']['options']['expose']['identifier'])) {
00395 form_error($form['expose']['identifier'], t('The identifier is required if the filter is exposed.'));
00396 }
00397
00398 if (!empty($form_state['values']['options']['expose']['identifier']) && $form_state['values']['options']['expose']['identifier'] == 'value') {
00399 form_error($form['expose']['identifier'], t('This identifier is not allowed.'));
00400 }
00401
00402 if (!$this->view->display_handler->is_identifier_unique($form_state['id'], $form_state['values']['options']['expose']['identifier'])) {
00403 form_error($form['expose']['identifier'], t('This identifier is used by another handler.'));
00404 }
00405 }
00406
00410 function expose_options() {
00411 $this->options['expose'] = array(
00412 'use_operator' => FALSE,
00413 'operator' => $this->options['id'] . '_op',
00414 'identifier' => $this->options['id'],
00415 'label' => $this->definition['title'],
00416 'remember' => FALSE,
00417 'multiple' => FALSE,
00418 'required' => FALSE,
00419 );
00420 }
00421
00427 function exposed_form(&$form, &$form_state) {
00428 if (empty($this->options['exposed'])) {
00429 return;
00430 }
00431
00432
00433 if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id'])) {
00434 $operator = $this->options['expose']['operator_id'];
00435 $this->operator_form($form, $form_state);
00436 $form[$operator] = $form['operator'];
00437
00438 if (isset($form[$operator]['#title'])) {
00439 unset($form[$operator]['#title']);
00440 }
00441
00442 $this->exposed_translate($form[$operator], 'operator');
00443
00444 unset($form['operator']);
00445 }
00446
00447
00448 if (!empty($this->options['expose']['identifier'])) {
00449 $value = $this->options['expose']['identifier'];
00450 $this->value_form($form, $form_state);
00451 $form[$value] = $form['value'];
00452
00453 if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') {
00454 unset($form[$value]['#title']);
00455 }
00456
00457 $this->exposed_translate($form[$value], 'value');
00458
00459 if (!empty($form['#type']) && ($form['#type'] == 'checkboxes' || ($form['#type'] == 'select' && !empty($form['#multiple'])))) {
00460 unset($form[$value]['#default_value']);
00461 }
00462
00463 if (!empty($form['#type']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
00464 $form[$value]['#default_value'] = 'All';
00465 }
00466
00467 if ($value != 'value') {
00468 unset($form['value']);
00469 }
00470 }
00471 }
00472
00477 function exposed_translate(&$form, $type) {
00478 if (!isset($form['#type'])) {
00479 return;
00480 }
00481
00482 if ($form['#type'] == 'radios') {
00483 $form['#type'] = 'select';
00484 }
00485
00486 if ($form['#type'] == 'checkboxes') {
00487 if (empty($form['#no_convert']) || empty($this->options['expose']['multiple'])) {
00488 $form['#type'] = 'select';
00489 }
00490 if (!empty($this->options['expose']['multiple'])) {
00491 $form['#multiple'] = TRUE;
00492 }
00493 }
00494 if (empty($this->options['expose']['multiple']) && isset($form['#multiple'])) {
00495 unset($form['#multiple']);
00496 $form['#size'] = NULL;
00497 }
00498
00499 if ($type == 'value' && empty($this->always_required) && empty($this->options['expose']['required']) && $form['#type'] == 'select' && empty($form['#multiple'])) {
00500 $any_label = variable_get('views_exposed_filter_any_label', 'new_any') == 'old_any' ? t('<Any>') : t('- Any -');
00501 $form['#options'] = array('All' => $any_label) + $form['#options'];
00502 $form['#default_value'] = 'All';
00503 }
00504
00505 if (!empty($this->options['expose']['required'])) {
00506 $form['#required'] = TRUE;
00507 }
00508 }
00509
00520 function exposed_info() {
00521 if (empty($this->options['exposed'])) {
00522 return;
00523 }
00524
00525 return array(
00526 'operator' => $this->options['expose']['operator_id'],
00527 'value' => $this->options['expose']['identifier'],
00528 'label' => $this->options['expose']['label'],
00529 );
00530 }
00531
00536 function accept_exposed_input($input) {
00537 if (empty($this->options['exposed'])) {
00538 return TRUE;
00539 }
00540
00541
00542 if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']) && isset($input[$this->options['expose']['operator_id']])) {
00543 $this->operator = $input[$this->options['expose']['operator_id']];
00544 }
00545
00546 if (!empty($this->options['expose']['identifier'])) {
00547 $value = $input[$this->options['expose']['identifier']];
00548
00549
00550 if (empty($this->options['expose']['required'])) {
00551 if (($this->operator == 'empty' || $this->operator == 'not empty') && $value === '') {
00552 $value = ' ';
00553 }
00554
00555 if ($this->operator != 'empty' && $this->operator != 'not empty') {
00556 if ($value == 'All' || $value === array()) {
00557 return FALSE;
00558 }
00559 }
00560
00561 if (!empty($this->always_multiple) && $value === '') {
00562 return FALSE;
00563 }
00564 }
00565
00566
00567 if (isset($value)) {
00568 $this->value = $value;
00569 if (empty($this->always_multiple) && empty($this->options['expose']['multiple'])) {
00570 $this->value = array($value);
00571 }
00572 }
00573 else {
00574 return FALSE;
00575 }
00576 }
00577
00578 return TRUE;
00579 }
00580
00581 function store_exposed_input($input, $status) {
00582 if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) {
00583 return TRUE;
00584 }
00585
00586 if (empty($this->options['expose']['remember'])) {
00587 return;
00588 }
00589
00590
00591
00592 $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display;
00593
00594
00595 $operator = !empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']);
00596
00597
00598
00599 if (!$status && isset($_SESSION['views'][$this->view->name][$display_id])) {
00600 $session = &$_SESSION['views'][$this->view->name][$display_id];
00601 if ($operator && isset($session[$this->options['expose']['operator_id']])) {
00602 unset($session[$this->options['expose']['operator_id']]);
00603 }
00604
00605 if (isset($session[$this->options['expose']['identifier']])) {
00606 unset($session[$this->options['expose']['identifier']]);
00607 }
00608 }
00609
00610 if ($status) {
00611 if (!isset($_SESSION['views'][$this->view->name][$display_id])) {
00612 $_SESSION['views'][$this->view->name][$display_id] = array();
00613 }
00614
00615 $session = &$_SESSION['views'][$this->view->name][$display_id];
00616
00617 if ($operator && isset($input[$this->options['expose']['operator_id']])) {
00618 $session[$this->options['expose']['operator_id']] = $input[$this->options['expose']['operator_id']];
00619 }
00620
00621 $session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']];
00622 }
00623 }
00624
00632 function query() {
00633 $this->ensure_my_table();
00634 $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $this->value, $this->operator);
00635 }
00636
00647 function can_group() {
00648 return TRUE;
00649 }
00650 }
00651
00652
00658 class views_handler_filter_broken extends views_handler_filter {
00659 function ui_name($short = FALSE) {
00660 return t('Broken/missing handler');
00661 }
00662
00663 function ensure_my_table() { }
00664 function query($group_by = FALSE) { }
00665 function options_form(&$form, &$form_state) {
00666 $form['markup'] = array(
00667 '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>',
00668 );
00669 }
00670
00674 function broken() { return TRUE; }
00675 }
00676
00677