Index: handlers/views_handler_sort.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_sort.inc,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 views_handler_sort.inc --- handlers/views_handler_sort.inc 26 Jun 2009 00:23:37 -0000 1.1.2.1 +++ handlers/views_handler_sort.inc 2 Sep 2009 15:53:08 -0000 @@ -10,52 +10,264 @@ * Base sort handler that has no options and performs a simple sort */ class views_handler_sort extends views_handler { + + /** + * Determine if a sort can be exposed. + */ + function can_expose() { return TRUE; } + + /** + * Provide the basic form which calls through to subforms. + * If overridden, it is best to call through to the parent, + * or to at least make sure all of the functions in this form + * are called. + */ + function options_form(&$form, &$form_state) { + if ($this->can_expose()) { + $this->show_expose_button($form, $form_state); + } + $form['start'] = array('#value' => '
'); + $this->sort_form($form, $form_state); + $form['end'] = array('#value' => '
'); + if ($this->can_expose()) { + $this->show_expose_form($form, $form_state); + } + } + + /** + * Simple validate handler + */ + function options_validate(&$form, &$form_state) { + $this->sort_validate($form, $form_state); + if (!empty($this->options['exposed'])) { + $this->expose_validate($form, $form_state); + } + } + + /** + * Validate the sort form. + */ + function sort_validate($form, &$form_state) { } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function sort_submit($form, &$form_state) { } + + /** + * Simple submit handler + */ + function options_submit(&$form, &$form_state) { + unset($form_state['values']['expose_button']); // don't store this. + $this->sort_submit($form, $form_state); + if (!empty($this->options['exposed'])) { + $this->expose_submit($form, $form_state); + } + } + + /** + * Provide a form for setting the sort. + * + * This may be overridden by child classes, and it must + * define $form['sort']; + */ + function sort_form(&$form, &$form_state) { + $options = $this->sort_options(); + if (!empty($options)) { + $form['sort'] = array( + '#type' => 'radios', + '#options' => $options, + '#default_value' => $this->options['sort'], + ); + } + } + + /** + * Provide a list of options for the default sort form. + * Should be overridden by classes that don't override sort_form + */ + function sort_options() { return array( + '' => t('Unsorted'), + 'ASC' => t('Sort ascending'), + 'DESC' => t('Sort descending'), + ); + } + + function expose_form_left(&$form, &$form_state) { + $form['expose']['label'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['label'], + '#title' => t('Label'), + '#size' => 40, + ); + $form['expose']['identifier'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['identifier'], + '#title' => t('Sort identifier'), + '#size' => 40, + '#description' => t('This will appear in the URL after the ? to identify this sort. Cannot be blank.'), + ); + } + + /** + * Handle the 'left' side fo the exposed options form. + */ + function expose_form_right(&$form, &$form_state) { + + $form['expose']['sort'] = array( + '#type' => 'value', + '#value' => '', + ); + + $form['expose']['label'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['label'], + '#title' => t('Label'), + '#size' => 40, + ); + } + + /** + * Provide default options for exposed sorts. + */ + function expose_options() { + $this->options['expose'] = array( + 'sort' => $this->options['sort'], + 'label' => $this->ui_name(), + 'identifier' => $this->options['id'] .'_sort', + ); + } + + /** + * Validate the options form. + */ + function expose_validate($form, &$form_state) { + if (empty($this->options['expose']['identifier'])) { + if (empty($form_state['values']['options']['expose']['identifier'])) { + form_error($form['expose']['identifier'], t('The identifier is required if the sort is exposed.')); + } + } + + if (!empty($form_state['values']['options']['expose']['identifier']) && $form_state['values']['options']['expose']['identifier'] == 'value') { + form_error($form['expose']['identifier'], t('This identifier is not allowed.')); + } + } + + /** + * Render our chunk of the exposed sort form when selecting + * + * You can override this if it doesn't do what you expect. + */ + function exposed_form(&$form, &$form_state) { + if (empty($this->options['exposed'])) { + return; + } + + if (!empty($this->options['expose']['identifier'])) { + $value = $this->options['expose']['identifier']; + + $this->sort_form($form, $form_state); + $form[$value] = $form['sort']; + + $this->exposed_translate($form[$value], 'sort'); + + unset($form['sort']); + } + + } + + /** + * Make some translations to a form item to make it more suitable to + * exposing. + */ + function exposed_translate(&$form, $type) { + if (!isset($form['#type'])) { + return; + } + + if ($form['#type'] == 'radios') { + $form['#type'] = 'select'; + } + } + + /** + * Tell the renderer about our exposed form. This only needs to be + * overridden for particularly complex forms. And maybe not even then. + */ + function exposed_info() { + if (empty($this->options['exposed'])) { + return; + } + + return array( + 'sort' => $this->options['expose']['sort'], + 'label' => $this->options['expose']['label'], + 'value' => $this->options['expose']['identifier'], + ); + } + + /** + * Check to see if input from the exposed sorts should change + * the behavior of this sort. + */ + function accept_exposed_input($input) { + return TRUE; + } + + function store_exposed_input($input, $status) { + return TRUE; + } + /** * Called to add the sort to a query. */ function query() { - $this->ensure_my_table(); - // Add the field. - $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']); + + if (empty($this->options['exposed'])) { + return; + } + + $sort = drupal_strtolower($this->view->exposed_input[$this->options['expose']['identifier']]); + + // Ensure $this->sort is valid. + if (!empty($sort) && $sort == 'asc' || $sort == 'desc') { + $this->ensure_my_table(); + // Add the field. + $this->query->add_orderby($this->table_alias, $this->real_field, $sort); + } } function option_definition() { $options = parent::option_definition(); - $options['order'] = array('default' => 'ASC'); + $options['exposed'] = array('default' => FALSE); + $options['sort'] = array('default' => ''); + $options['identifier'] = array('default' => ''); return $options; } /** - * Display whether or not the sort order is ascending or descending + * Display whether or not the sort sort is ascending or descending */ function admin_summary() { - switch ($this->options['order']) { + switch ($this->options['sort']) { case 'ASC': case 'asc': - default: $type = t('asc'); break; case 'DESC'; case 'desc'; $type = t('desc'); break; + default: + $type == t('unsorted'); + break; } return '' . $type . ''; } - /** - * Basic options for all sort criteria - */ - function options_form(&$form, &$form_state) { - $form['order'] = array( - '#type' => 'radios', - '#title' => t('Sort order'), - '#options' => array('ASC' => t('Ascending'), 'DESC' => t('Descending')), - '#default_value' => $this->options['order'], - ); - } } /**