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 29 Oct 2009 20:31:01 -0000
@@ -10,52 +10,274 @@
* 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['order'];
+ */
+ function sort_form(&$form, &$form_state) {
+ $options = $this->sort_options();
+ if (!empty($options)) {
+ $form['order'] = array(
+ '#type' => 'radios',
+ '#options' => $options,
+ '#default_value' => $this->options['order'],
+ );
+ }
+ }
+
+ /**
+ * 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(
+ 'unsorted' => 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']['order'] = array(
+ '#type' => 'value',
+ '#value' => 'unsorted',
+ );
+
+ $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(
+ 'order' => $this->options['order'],
+ 'label' => t('Sort by: ') . $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['order'];
+
+ $this->exposed_translate($form[$value], 'order');
+
+ unset($form['order']);
+ }
+
+ }
+
+ /**
+ * 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.
+ *
+ * @return
+ * An array with the following keys:
+ * - operator: The $form key of the operator. Set to NULL if no operator.
+ * - value: The $form key of the value. Set to NULL if no value.
+ * - label: The label to use for this piece.
+ */
+ function exposed_info() {
+ if (empty($this->options['exposed'])) {
+ return;
+ }
+
+ return array(
+ 'order' => $this->options['expose']['order'],
+ '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']);
+
+ // When a exposed sort is by default ASC or DESC, we have to check if
+ // this value was modified. If not, we use the default value for this sort.
+ if (!empty($this->options['exposed']) && !empty($this->view->exposed_input[$this->options['expose']['identifier']])) {
+ $sort = drupal_strtolower($this->view->exposed_input[$this->options['expose']['identifier']]);
+ }
+ else {
+ $sort = drupal_strtolower($this->options['order']);
+ }
+
+ // Ensure sort is valid and add the field.
+ if (!empty($sort) && ($sort == 'asc' || $sort == 'desc')) {
+ $this->ensure_my_table();
+ $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['order'] = array('default' => 'unsorted');
+ $options['identifier'] = array('default' => 'unsorted');
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() {
+ if (!empty($this->options['exposed'])) {
+ return t('exposed');
+ }
switch ($this->options['order']) {
case 'ASC':
case 'asc':
- default:
- $type = t('asc');
+ return t('asc');
break;
case 'DESC';
case 'desc';
- $type = t('desc');
+ return t('desc');
+ break;
+ default:
+ return 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'],
- );
- }
}
/**
Index: handlers/views_handler_sort_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_sort_date.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_sort_date.inc
--- handlers/views_handler_sort_date.inc 3 Sep 2008 19:21:28 -0000 1.1
+++ handlers/views_handler_sort_date.inc 29 Oct 2009 20:31:01 -0000
@@ -41,12 +41,21 @@ class views_handler_sort_date extends vi
* Called to add the sort to a query.
*/
function query() {
+ // When a exposed sort is by default ASC or DESC, we have to check if
+ // this value was modified. If not, we use the default value for this sort.
+ if (!empty($this->options['exposed']) && !empty($this->view->exposed_input[$this->options['expose']['identifier']])) {
+ $sort = drupal_strtolower($this->view->exposed_input[$this->options['expose']['identifier']]);
+ }
+ else {
+ $sort = drupal_strtolower($this->options['order']);
+ }
+
$this->ensure_my_table();
switch ($this->options['granularity']) {
case 'second':
default:
- $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
- return;
+ $formula = NULL;
+ break;
case 'minute':
$formula = views_date_sql_format('YmdHi', "$this->table_alias.$this->real_field");
break;
@@ -63,8 +72,15 @@ class views_handler_sort_date extends vi
$formula = views_date_sql_format('Y', "$this->table_alias.$this->real_field");
break;
}
-
- // Add the field.
- $this->query->add_orderby(NULL, $formula, $this->options['order'], $this->table_alias . '_' . $this->field . '_' . $this->options['granularity']);
+
+ // Ensure sort is valid and add the field.
+ if (!empty($sort) && ($sort == 'asc' || $sort == 'desc')) {
+ if ($formula) {
+ $this->query->add_orderby(NULL, $formula, $sort, $this->table_alias . '_' . $this->field . '_' . $this->options['granularity']);
+ }
+ else {
+ $this->query->add_orderby($this->table_alias, $this->real_field, $sort);
+ }
+ }
}
}
Index: handlers/views_handler_sort_formula.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_sort_formula.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_sort_formula.inc
--- handlers/views_handler_sort_formula.inc 3 Sep 2008 19:21:28 -0000 1.1
+++ handlers/views_handler_sort_formula.inc 29 Oct 2009 20:31:01 -0000
@@ -41,8 +41,18 @@ class views_handler_sort_formula extends
else {
$formula = $this->formula;
}
- $this->ensure_my_table();
- // Add the field.
- $this->query->add_orderby(NULL, $formula, $this->options['order'], $this->table_alias . '_' . $this->field);
+
+ if (!empty($this->options['exposed']) && !empty($this->view->exposed_input[$this->options['expose']['identifier']])) {
+ $sort = drupal_strtolower($this->view->exposed_input[$this->options['expose']['identifier']]);
+ }
+ else {
+ $sort = drupal_strtolower($this->options['order']);
+ }
+
+ // Ensure $this->sort is valid and add the field.
+ if (!empty($sort) && ($sort == 'asc' || $sort == 'desc')) {
+ $this->ensure_my_table();
+ $this->query->add_orderby(NULL, $formula, $sort, $this->table_alias . '_' . $this->field);
+ }
}
}
Index: handlers/views_handler_sort_random.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_sort_random.inc,v
retrieving revision 1.1
diff -u -p -r1.1 views_handler_sort_random.inc
--- handlers/views_handler_sort_random.inc 3 Sep 2008 19:21:28 -0000 1.1
+++ handlers/views_handler_sort_random.inc 29 Oct 2009 20:31:01 -0000
@@ -5,6 +5,9 @@
* Handle a random sort.
*/
class views_handler_sort_random extends views_handler_sort {
+
+ function can_expose() {return FALSE;}
+
function query() {
global $db_type;
switch ($db_type) {
@@ -25,4 +28,8 @@ class views_handler_sort_random extends
parent::options_form($form, $form_state);
$form['order']['#access'] = FALSE;
}
+
+ function admin_summary() {
+ return '';
+ }
}
Index: help/sort.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/help/sort.html,v
retrieving revision 1.2
diff -u -p -r1.2 sort.html
--- help/sort.html 13 Jun 2008 00:56:19 -0000 1.2
+++ help/sort.html 29 Oct 2009 20:31:01 -0000
@@ -22,4 +22,7 @@ This is because these fields sort purely
Date fields
Date fields often can have a 'granularity', which is a way of making similar dates actually be the same date. Take two dates that are close to each other: May 1, 2007 5:30 am and May 1, 2007 9:45am. Without granularity, the two dates are compared and the first date comes before the second date. However, if the granularity is set to 'day' it only looks at the parts of the date up to the day: May 1, 2007 and May 1, 2007. At that point, they are the same, and the sort would move on to the next sort criterion.
+
+Exposed Sorts
+If you expose a sort, users can define how will be sorted the view through a form element. Not all kind of sorts can be exposed. When you expose sorts is important the order in Views UI. If an exposed sort is by default unordered, only will be applied if users selects Ascendant or Descendent.