PageRenderTime 51ms CodeModel.GetById 7ms RepoModel.GetById 1ms app.codeStats 0ms

/core/modules/views/src/Plugin/views/filter/NumericFilter.php

https://gitlab.com/guillaumev/alkarama
PHP | 342 lines | 271 code | 35 blank | 36 comment | 45 complexity | b9d2ae748f74bc9c38fd427cb5f4e8d0 MD5 | raw file
  1. <?php
  2. namespace Drupal\views\Plugin\views\filter;
  3. use Drupal\Core\Form\FormStateInterface;
  4. /**
  5. * Simple filter to handle greater than/less than filters
  6. *
  7. * @ingroup views_filter_handlers
  8. *
  9. * @ViewsFilter("numeric")
  10. */
  11. class NumericFilter extends FilterPluginBase {
  12. protected $alwaysMultiple = TRUE;
  13. protected function defineOptions() {
  14. $options = parent::defineOptions();
  15. $options['value'] = array(
  16. 'contains' => array(
  17. 'min' => array('default' => ''),
  18. 'max' => array('default' => ''),
  19. 'value' => array('default' => ''),
  20. ),
  21. );
  22. return $options;
  23. }
  24. function operators() {
  25. $operators = array(
  26. '<' => array(
  27. 'title' => $this->t('Is less than'),
  28. 'method' => 'opSimple',
  29. 'short' => $this->t('<'),
  30. 'values' => 1,
  31. ),
  32. '<=' => array(
  33. 'title' => $this->t('Is less than or equal to'),
  34. 'method' => 'opSimple',
  35. 'short' => $this->t('<='),
  36. 'values' => 1,
  37. ),
  38. '=' => array(
  39. 'title' => $this->t('Is equal to'),
  40. 'method' => 'opSimple',
  41. 'short' => $this->t('='),
  42. 'values' => 1,
  43. ),
  44. '!=' => array(
  45. 'title' => $this->t('Is not equal to'),
  46. 'method' => 'opSimple',
  47. 'short' => $this->t('!='),
  48. 'values' => 1,
  49. ),
  50. '>=' => array(
  51. 'title' => $this->t('Is greater than or equal to'),
  52. 'method' => 'opSimple',
  53. 'short' => $this->t('>='),
  54. 'values' => 1,
  55. ),
  56. '>' => array(
  57. 'title' => $this->t('Is greater than'),
  58. 'method' => 'opSimple',
  59. 'short' => $this->t('>'),
  60. 'values' => 1,
  61. ),
  62. 'between' => array(
  63. 'title' => $this->t('Is between'),
  64. 'method' => 'opBetween',
  65. 'short' => $this->t('between'),
  66. 'values' => 2,
  67. ),
  68. 'not between' => array(
  69. 'title' => $this->t('Is not between'),
  70. 'method' => 'opBetween',
  71. 'short' => $this->t('not between'),
  72. 'values' => 2,
  73. ),
  74. 'regular_expression' => array(
  75. 'title' => $this->t('Regular expression'),
  76. 'short' => $this->t('regex'),
  77. 'method' => 'op_regex',
  78. 'values' => 1,
  79. ),
  80. );
  81. // if the definition allows for the empty operator, add it.
  82. if (!empty($this->definition['allow empty'])) {
  83. $operators += array(
  84. 'empty' => array(
  85. 'title' => $this->t('Is empty (NULL)'),
  86. 'method' => 'opEmpty',
  87. 'short' => $this->t('empty'),
  88. 'values' => 0,
  89. ),
  90. 'not empty' => array(
  91. 'title' => $this->t('Is not empty (NOT NULL)'),
  92. 'method' => 'opEmpty',
  93. 'short' => $this->t('not empty'),
  94. 'values' => 0,
  95. ),
  96. );
  97. }
  98. return $operators;
  99. }
  100. /**
  101. * Provide a list of all the numeric operators
  102. */
  103. public function operatorOptions($which = 'title') {
  104. $options = array();
  105. foreach ($this->operators() as $id => $info) {
  106. $options[$id] = $info[$which];
  107. }
  108. return $options;
  109. }
  110. protected function operatorValues($values = 1) {
  111. $options = array();
  112. foreach ($this->operators() as $id => $info) {
  113. if ($info['values'] == $values) {
  114. $options[] = $id;
  115. }
  116. }
  117. return $options;
  118. }
  119. /**
  120. * Provide a simple textfield for equality
  121. */
  122. protected function valueForm(&$form, FormStateInterface $form_state) {
  123. $form['value']['#tree'] = TRUE;
  124. // We have to make some choices when creating this as an exposed
  125. // filter form. For example, if the operator is locked and thus
  126. // not rendered, we can't render dependencies; instead we only
  127. // render the form items we need.
  128. $which = 'all';
  129. if (!empty($form['operator'])) {
  130. $source = ':input[name="options[operator]"]';
  131. }
  132. if ($exposed = $form_state->get('exposed')) {
  133. $identifier = $this->options['expose']['identifier'];
  134. if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator_id'])) {
  135. // exposed and locked.
  136. $which = in_array($this->operator, $this->operatorValues(2)) ? 'minmax' : 'value';
  137. }
  138. else {
  139. $source = ':input[name="' . $this->options['expose']['operator_id'] . '"]';
  140. }
  141. }
  142. $user_input = $form_state->getUserInput();
  143. if ($which == 'all') {
  144. $form['value']['value'] = array(
  145. '#type' => 'textfield',
  146. '#title' => !$exposed ? $this->t('Value') : '',
  147. '#size' => 30,
  148. '#default_value' => $this->value['value'],
  149. );
  150. // Setup #states for all operators with one value.
  151. foreach ($this->operatorValues(1) as $operator) {
  152. $form['value']['value']['#states']['visible'][] = array(
  153. $source => array('value' => $operator),
  154. );
  155. }
  156. if ($exposed && !isset($user_input[$identifier]['value'])) {
  157. $user_input[$identifier]['value'] = $this->value['value'];
  158. $form_state->setUserInput($user_input);
  159. }
  160. }
  161. elseif ($which == 'value') {
  162. // When exposed we drop the value-value and just do value if
  163. // the operator is locked.
  164. $form['value'] = array(
  165. '#type' => 'textfield',
  166. '#title' => !$exposed ? $this->t('Value') : '',
  167. '#size' => 30,
  168. '#default_value' => $this->value['value'],
  169. );
  170. if ($exposed && !isset($user_input[$identifier])) {
  171. $user_input[$identifier] = $this->value['value'];
  172. $form_state->setUserInput($user_input);
  173. }
  174. }
  175. if ($which == 'all' || $which == 'minmax') {
  176. $form['value']['min'] = array(
  177. '#type' => 'textfield',
  178. '#title' => !$exposed ? $this->t('Min') : $this->exposedInfo()['label'],
  179. '#size' => 30,
  180. '#default_value' => $this->value['min'],
  181. '#description' => !$exposed ? '' : $this->exposedInfo()['description']
  182. );
  183. $form['value']['max'] = array(
  184. '#type' => 'textfield',
  185. '#title' => !$exposed ? $this->t('And max') : $this->t('And'),
  186. '#size' => 30,
  187. '#default_value' => $this->value['max'],
  188. );
  189. if ($which == 'all') {
  190. $states = array();
  191. // Setup #states for all operators with two values.
  192. foreach ($this->operatorValues(2) as $operator) {
  193. $states['#states']['visible'][] = array(
  194. $source => array('value' => $operator),
  195. );
  196. }
  197. $form['value']['min'] += $states;
  198. $form['value']['max'] += $states;
  199. }
  200. if ($exposed && !isset($user_input[$identifier]['min'])) {
  201. $user_input[$identifier]['min'] = $this->value['min'];
  202. }
  203. if ($exposed && !isset($user_input[$identifier]['max'])) {
  204. $user_input[$identifier]['max'] = $this->value['max'];
  205. }
  206. if (!isset($form['value'])) {
  207. // Ensure there is something in the 'value'.
  208. $form['value'] = array(
  209. '#type' => 'value',
  210. '#value' => NULL
  211. );
  212. }
  213. }
  214. }
  215. public function query() {
  216. $this->ensureMyTable();
  217. $field = "$this->tableAlias.$this->realField";
  218. $info = $this->operators();
  219. if (!empty($info[$this->operator]['method'])) {
  220. $this->{$info[$this->operator]['method']}($field);
  221. }
  222. }
  223. protected function opBetween($field) {
  224. if ($this->operator == 'between') {
  225. $this->query->addWhere($this->options['group'], $field, array($this->value['min'], $this->value['max']), 'BETWEEN');
  226. }
  227. else {
  228. $this->query->addWhere($this->options['group'], $field, array($this->value['min'], $this->value['max']), 'NOT BETWEEN');
  229. }
  230. }
  231. protected function opSimple($field) {
  232. $this->query->addWhere($this->options['group'], $field, $this->value['value'], $this->operator);
  233. }
  234. protected function opEmpty($field) {
  235. if ($this->operator == 'empty') {
  236. $operator = "IS NULL";
  237. }
  238. else {
  239. $operator = "IS NOT NULL";
  240. }
  241. $this->query->addWhere($this->options['group'], $field, NULL, $operator);
  242. }
  243. /**
  244. * Filters by a regular expression.
  245. *
  246. * @param string $field
  247. * The expression pointing to the queries field, for example "foo.bar".
  248. */
  249. protected function opRegex($field) {
  250. $this->query->addWhere($this->options['group'], $field, $this->value, 'REGEXP');
  251. }
  252. public function adminSummary() {
  253. if ($this->isAGroup()) {
  254. return $this->t('grouped');
  255. }
  256. if (!empty($this->options['exposed'])) {
  257. return $this->t('exposed');
  258. }
  259. $options = $this->operatorOptions('short');
  260. $output = $options[$this->operator];
  261. if (in_array($this->operator, $this->operatorValues(2))) {
  262. $output .= ' ' . $this->t('@min and @max', array('@min' => $this->value['min'], '@max' => $this->value['max']));
  263. }
  264. elseif (in_array($this->operator, $this->operatorValues(1))) {
  265. $output .= ' ' . $this->value['value'];
  266. }
  267. return $output;
  268. }
  269. /**
  270. * Do some minor translation of the exposed input
  271. */
  272. public function acceptExposedInput($input) {
  273. if (empty($this->options['exposed'])) {
  274. return TRUE;
  275. }
  276. // rewrite the input value so that it's in the correct format so that
  277. // the parent gets the right data.
  278. if (!empty($this->options['expose']['identifier'])) {
  279. $value = &$input[$this->options['expose']['identifier']];
  280. if (!is_array($value)) {
  281. $value = array(
  282. 'value' => $value,
  283. );
  284. }
  285. }
  286. $rc = parent::acceptExposedInput($input);
  287. if (empty($this->options['expose']['required'])) {
  288. // We have to do some of our own checking for non-required filters.
  289. $info = $this->operators();
  290. if (!empty($info[$this->operator]['values'])) {
  291. switch ($info[$this->operator]['values']) {
  292. case 1:
  293. if ($value['value'] === '') {
  294. return FALSE;
  295. }
  296. break;
  297. case 2:
  298. if ($value['min'] === '' && $value['max'] === '') {
  299. return FALSE;
  300. }
  301. break;
  302. }
  303. }
  304. }
  305. return $rc;
  306. }
  307. }