views_handler_sort.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. /**
  3. * @file
  4. * @todo.
  5. */
  6. /**
  7. * @defgroup views_sort_handlers Views sort handlers
  8. * @{
  9. * Handlers to tell Views how to sort queries.
  10. */
  11. /**
  12. * Base sort handler that has no options and performs a simple sort.
  13. *
  14. * @ingroup views_sort_handlers
  15. */
  16. class views_handler_sort extends views_handler {
  17. /**
  18. * Determine if a sort can be exposed.
  19. */
  20. function can_expose() { return TRUE; }
  21. /**
  22. * Called to add the sort to a query.
  23. */
  24. function query() {
  25. $this->ensure_my_table();
  26. // Add the field.
  27. $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
  28. }
  29. function option_definition() {
  30. $options = parent::option_definition();
  31. $options['order'] = array('default' => 'ASC');
  32. $options['exposed'] = array('default' => FALSE, 'bool' => TRUE);
  33. $options['expose'] = array(
  34. 'contains' => array(
  35. 'label' => array('default' => '', 'translatable' => TRUE),
  36. ),
  37. );
  38. return $options;
  39. }
  40. /**
  41. * Display whether or not the sort order is ascending or descending
  42. */
  43. function admin_summary() {
  44. if (!empty($this->options['exposed'])) {
  45. return t('Exposed');
  46. }
  47. switch ($this->options['order']) {
  48. case 'ASC':
  49. case 'asc':
  50. default:
  51. return t('asc');
  52. break;
  53. case 'DESC';
  54. case 'desc';
  55. return t('desc');
  56. break;
  57. }
  58. }
  59. /**
  60. * Basic options for all sort criteria
  61. */
  62. function options_form(&$form, &$form_state) {
  63. parent::options_form($form, $form_state);
  64. if ($this->can_expose()) {
  65. $this->show_expose_button($form, $form_state);
  66. }
  67. $form['op_val_start'] = array('#value' => '<div class="clearfix">');
  68. $this->show_sort_form($form, $form_state);
  69. $form['op_val_end'] = array('#value' => '</div>');
  70. if ($this->can_expose()) {
  71. $this->show_expose_form($form, $form_state);
  72. }
  73. }
  74. /**
  75. * Shortcut to display the expose/hide button.
  76. */
  77. function show_expose_button(&$form, &$form_state) {
  78. $form['expose_button'] = array(
  79. '#prefix' => '<div class="views-expose clearfix">',
  80. '#suffix' => '</div>',
  81. // Should always come first
  82. '#weight' => -1000,
  83. );
  84. // Add a checkbox for JS users, which will have behavior attached to it
  85. // so it can replace the button.
  86. $form['expose_button']['checkbox'] = array(
  87. '#theme_wrappers' => array('container'),
  88. '#attributes' => array('class' => array('js-only')),
  89. );
  90. $form['expose_button']['checkbox']['checkbox'] = array(
  91. '#title' => t('Expose this sort to visitors, to allow them to change it'),
  92. '#type' => 'checkbox',
  93. );
  94. // Then add the button itself.
  95. if (empty($this->options['exposed'])) {
  96. $form['expose_button']['markup'] = array(
  97. '#markup' => '<div class="description exposed-description" style="float: left; margin-right:10px">' . t('This sort is not exposed. Expose it to allow the users to change it.') . '</div>',
  98. );
  99. $form['expose_button']['button'] = array(
  100. '#limit_validation_errors' => array(),
  101. '#type' => 'submit',
  102. '#value' => t('Expose sort'),
  103. '#submit' => array('views_ui_config_item_form_expose'),
  104. );
  105. $form['expose_button']['checkbox']['checkbox']['#default_value'] = 0;
  106. }
  107. else {
  108. $form['expose_button']['markup'] = array(
  109. '#markup' => '<div class="description exposed-description">' . t('This sort is exposed. If you hide it, users will not be able to change it.') . '</div>',
  110. );
  111. $form['expose_button']['button'] = array(
  112. '#limit_validation_errors' => array(),
  113. '#type' => 'submit',
  114. '#value' => t('Hide sort'),
  115. '#submit' => array('views_ui_config_item_form_expose'),
  116. );
  117. $form['expose_button']['checkbox']['checkbox']['#default_value'] = 1;
  118. }
  119. }
  120. /**
  121. * Simple validate handler
  122. */
  123. function options_validate(&$form, &$form_state) {
  124. $this->sort_validate($form, $form_state);
  125. if (!empty($this->options['exposed'])) {
  126. $this->expose_validate($form, $form_state);
  127. }
  128. }
  129. /**
  130. * Simple submit handler
  131. */
  132. function options_submit(&$form, &$form_state) {
  133. unset($form_state['values']['expose_button']); // don't store this.
  134. $this->sort_submit($form, $form_state);
  135. if (!empty($this->options['exposed'])) {
  136. $this->expose_submit($form, $form_state);
  137. }
  138. }
  139. /**
  140. * Shortcut to display the value form.
  141. */
  142. function show_sort_form(&$form, &$form_state) {
  143. $options = $this->sort_options();
  144. if (!empty($options)) {
  145. $form['order'] = array(
  146. '#type' => 'radios',
  147. '#options' => $options,
  148. '#default_value' => $this->options['order'],
  149. );
  150. }
  151. }
  152. function sort_validate(&$form, &$form_state) { }
  153. function sort_submit(&$form, &$form_state) { }
  154. /**
  155. * Provide a list of options for the default sort form.
  156. * Should be overridden by classes that don't override sort_form
  157. */
  158. function sort_options() {
  159. return array(
  160. 'ASC' => t('Sort ascending'),
  161. 'DESC' => t('Sort descending'),
  162. );
  163. }
  164. function expose_form(&$form, &$form_state) {
  165. // #flatten will move everything from $form['expose'][$key] to $form[$key]
  166. // prior to rendering. That's why the pre_render for it needs to run first,
  167. // so that when the next pre_render (the one for fieldsets) runs, it gets
  168. // the flattened data.
  169. array_unshift($form['#pre_render'], 'views_ui_pre_render_flatten_data');
  170. $form['expose']['#flatten'] = TRUE;
  171. $form['expose']['label'] = array(
  172. '#type' => 'textfield',
  173. '#default_value' => $this->options['expose']['label'],
  174. '#title' => t('Label'),
  175. '#required' => TRUE,
  176. '#size' => 40,
  177. '#weight' => -1,
  178. );
  179. }
  180. /**
  181. * Provide default options for exposed sorts.
  182. */
  183. function expose_options() {
  184. $this->options['expose'] = array(
  185. 'order' => $this->options['order'],
  186. 'label' => $this->definition['title'],
  187. );
  188. }
  189. }
  190. /**
  191. * A special handler to take the place of missing or broken handlers.
  192. *
  193. * @ingroup views_sort_handlers
  194. */
  195. class views_handler_sort_broken extends views_handler_sort {
  196. function ui_name($short = FALSE) {
  197. return t('Broken/missing handler');
  198. }
  199. function ensure_my_table() { /* No table to ensure! */ }
  200. function query($group_by = FALSE) { /* No query to run */ }
  201. function options_form(&$form, &$form_state) {
  202. $form['markup'] = array(
  203. '#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>',
  204. );
  205. }
  206. /**
  207. * Determine if the handler is considered 'broken'
  208. */
  209. function broken() { return TRUE; }
  210. }
  211. /**
  212. * @}
  213. */