handler_argument_date.inc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php
  2. /**
  3. * @file
  4. * Contains the SearchApiViewsHandlerArgumentDate class.
  5. */
  6. /**
  7. * Defines a contextual filter searching for a date or date range.
  8. */
  9. class SearchApiViewsHandlerArgumentDate extends SearchApiViewsHandlerArgument {
  10. /**
  11. * {@inheritdoc}
  12. */
  13. public function query($group_by = FALSE) {
  14. if (empty($this->value)) {
  15. $this->fillValue();
  16. if ($this->value === FALSE) {
  17. $this->abort();
  18. return;
  19. }
  20. }
  21. $outer_conjunction = strtoupper($this->operator);
  22. if (empty($this->options['not'])) {
  23. $operator = '=';
  24. $inner_conjunction = 'OR';
  25. }
  26. else {
  27. $operator = '<>';
  28. $inner_conjunction = 'AND';
  29. }
  30. if (!empty($this->value)) {
  31. if (!empty($this->value)) {
  32. $outer_filter = $this->query->createFilter($outer_conjunction);
  33. foreach ($this->value as $value) {
  34. $value_filter = $this->query->createFilter($inner_conjunction);
  35. $values = explode(';', $value);
  36. $values = array_map(array($this, 'getTimestamp'), $values);
  37. if (in_array(FALSE, $values, TRUE)) {
  38. $this->abort();
  39. return;
  40. }
  41. $is_range = (count($values) > 1);
  42. $inner_filter = ($is_range ? $this->query->createFilter('AND') : $value_filter);
  43. $range_op = (empty($this->options['not']) ? '>=' : '<');
  44. $inner_filter->condition($this->real_field, $values[0], $is_range ? $range_op : $operator);
  45. if ($is_range) {
  46. $range_op = (empty($this->options['not']) ? '<=' : '>');
  47. $inner_filter->condition($this->real_field, $values[1], $range_op);
  48. $value_filter->filter($inner_filter);
  49. }
  50. $outer_filter->filter($value_filter);
  51. }
  52. $this->query->filter($outer_filter);
  53. }
  54. }
  55. }
  56. /**
  57. * Converts a value to a timestamp, if it isn't one already.
  58. *
  59. * @param string|int $value
  60. * The value to convert. Either a timestamp, or a date/time string as
  61. * recognized by strtotime().
  62. *
  63. * @return int|false
  64. * The parsed timestamp, or FALSE if an illegal string was passed.
  65. */
  66. public function getTimestamp($value) {
  67. if (is_numeric($value)) {
  68. return $value;
  69. }
  70. return strtotime($value);
  71. }
  72. /**
  73. * Fills $this->value with data from the argument.
  74. */
  75. protected function fillValue() {
  76. if (!empty($this->options['break_phrase'])) {
  77. // Set up defaults:
  78. if (!isset($this->value)) {
  79. $this->value = array();
  80. }
  81. if (!isset($this->operator)) {
  82. $this->operator = 'OR';
  83. }
  84. if (empty($this->argument)) {
  85. return;
  86. }
  87. if (preg_match('/^([-\d;:\s]+\+)*[-\d;:\s]+$/', $this->argument)) {
  88. // The '+' character in a query string may be parsed as ' '.
  89. $this->value = explode('+', $this->argument);
  90. }
  91. elseif (preg_match('/^([-\d;:\s]+,)*[-\d;:\s]+$/', $this->argument)) {
  92. $this->operator = 'AND';
  93. $this->value = explode(',', $this->argument);
  94. }
  95. // Keep an 'error' value if invalid strings were given.
  96. if (!empty($this->argument) && (empty($this->value) || !is_array($this->value))) {
  97. $this->value = FALSE;
  98. }
  99. }
  100. else {
  101. $this->value = array($this->argument);
  102. }
  103. }
  104. /**
  105. * Aborts the associated query due to an illegal argument.
  106. */
  107. protected function abort() {
  108. $variables['!field'] = $this->definition['group'] . ': ' . $this->definition['title'];
  109. $this->query->abort(t('Illegal argument passed to !field contextual filter.', $variables));
  110. }
  111. /**
  112. * Computes the title this argument will assign the view, given the argument.
  113. *
  114. * @return string
  115. * A title fitting for the passed argument.
  116. */
  117. public function title() {
  118. if (!empty($this->argument)) {
  119. if (empty($this->value)) {
  120. $this->fillValue();
  121. }
  122. $dates = array();
  123. foreach ($this->value as $date) {
  124. $date_parts = explode(';', $date);
  125. $ts = $this->getTimestamp($date_parts[0]);
  126. $datestr = format_date($ts, 'short');
  127. if (count($date_parts) > 1) {
  128. $ts = $this->getTimestamp($date_parts[1]);
  129. $datestr .= ' - ' . format_date($ts, 'short');
  130. }
  131. if ($datestr) {
  132. $dates[] = $datestr;
  133. }
  134. }
  135. return $dates ? implode(', ', $dates) : check_plain($this->argument);
  136. }
  137. return check_plain($this->argument);
  138. }
  139. }