source: sipes/modules_contrib/date/includes/date_api_argument_handler.inc @ c43ea01

stableversion-3.0
Last change on this file since c43ea01 was f3eebcf, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se actualizo el modulo

  • Propiedad mode establecida a 100755
File size: 15.8 KB
Línea 
1<?php
2/**
3 * @file
4 * Views argument handler.
5 */
6
7/**
8 * Date API argument handler.
9 */
10class date_api_argument_handler extends views_handler_argument_date {
11  var $offset = NULL;
12
13  function construct() {
14    parent::construct();
15    require_once('./'. drupal_get_path('module', 'date_api') .'/date_api_sql.inc');
16    $this->date_handler = new date_sql_handler();
17    $this->date_handler->construct();
18  }
19
20  /**
21   * Get granularity and use it to create the formula and a format
22   * for the results.
23   */
24  function init(&$view, $options) {
25    parent::init($view, $options);
26
27    // Identify the type of display we're using.
28    $this->display_handler = $view->display_handler->definition['handler'];
29
30    // Add a date handler to the display.
31    $date_handler = $this->date_handler;
32    $date_handler->granularity = $this->options['granularity'];
33    $this->format = $date_handler->views_formats($date_handler->granularity, 'display');
34    $this->sql_format = $date_handler->views_formats($date_handler->granularity, 'sql');
35
36    if (empty($this->view->date_info)) $this->view->date_info = new stdClass();
37
38    // Set the view range, do this only if not already set in case there are multiple date arguments.
39    if (empty($this->view->date_info->min_allowed_year)) {
40      $range = date_range_years($this->options['year_range']);
41      $this->view->date_info->min_allowed_year = !empty($range) && is_array($range) ? $range[0] : variable_get('min_allowed_year', 100);
42      $this->view->date_info->max_allowed_year = !empty($range) && is_array($range) ? $range[1] : variable_get('max_allowed_year', 4000);
43    }
44    if (empty($this->view->date_info->date_fields)) {
45      $this->view->date_info->date_fields = array();
46    }
47    $this->view->date_info->date_fields = array_merge($this->view->date_info->date_fields, $this->options['date_fields']);
48  }
49
50  /**
51   * Default value for the date_fields option.
52   */
53  function option_definition() {
54    $options = parent::option_definition();
55    $options['date_fields'] = array('default' => array());
56    $options['year_range'] = array('default' => '-3:+3', 'export' => 'export_plugin');
57    $options['date_method'] = array('default' => 'OR', 'export' => 'export_plugin');
58    $options['granularity'] = array('default' => 'month', 'export' => 'export_plugin');
59    $options['default_argument_type'] = array('default' => 'date', 'export' => 'export_plugin');
60    return $options;
61  }
62
63  /**
64   * Make sure our custom options get exported.
65   * Handle the options we know about, pass the rest to the parent plugin.
66   */
67  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
68    $output = '';
69    if (in_array($option, array('year_range', 'granularity', 'default_argument_type', 'date_method'))) {
70      $name = $this->options[$option];
71      $output .= $indent . $prefix . "['$option'] = '$name';\n";
72      return $output;
73    }
74    return parent::export_plugin($indent, $prefix, $storage, $option, $definition, $parents);
75  }
76
77  /**
78   * Add a form element to select date_fields for this argument.
79   */
80  function options_form(&$form, &$form_state) {
81    parent::options_form($form, $form_state);
82    $options = $this->date_handler->date_parts();
83    unset($options['second'], $options['minute']);
84    $options += array('week' => date_t('Week', 'datetime'));
85    $form['granularity'] = array(
86      '#title' => t('Granularity'),
87      '#type' => 'radios',
88      '#options' => $options,
89      '#default_value' => $this->options['granularity'],
90      '#multiple' => TRUE,
91      '#description' => t("Select the type of date value to be used in defaults, summaries, and navigation. For example, a granularity of 'month' will set the default date to the current month, summarize by month in summary views, and link to the next and previous month when using date navigation."),
92    );
93
94    $form['year_range'] = array(
95      '#title' => t('Date year range'),
96      '#type' => 'textfield',
97      '#default_value' => $this->options['year_range'],
98      '#description' => t("Set the allowable minimum and maximum year range for this argument, either a -X:+X offset from the current year, like '-3:+3' or an absolute minimum and maximum year, like '2005:2010'. When the argument is set to a date outside the range, the page will be returned as 'Page not found (404)'."),
99    );
100
101    $fields = date_api_fields($this->definition['base']);
102    $options = array();
103    foreach ($fields['name'] as $name => $field) {
104      $options[$name] = $field['label'];
105    }
106
107    // If this argument was added as a CCK field argument and no other date field
108    // has been chosen, update the default with the right date.
109    if (empty($this->options['date_fields']) && $this->field != 'date_argument') {
110      $this->options['date_fields'] = array($this->table .'.'. $this->field);
111    }
112
113    $form['date_fields'] = array(
114      '#title' => t('Date field(s)'),
115      '#type' => 'checkboxes',
116      '#options' => $options,
117      '#default_value' => $this->options['date_fields'],
118      '#multiple' => TRUE,
119      '#description' => t("Select one or more date fields to filter with this argument. Do not select both the 'From date' and 'To date' for CCK date fields, only one of them is needed."),
120    );
121    $form['date_method'] = array(
122      '#title' => t('Method'),
123      '#type' => 'radios',
124      '#options' => array('OR' => t('OR'), 'AND' => t('AND')),
125      '#default_value' => $this->options['date_method'],
126      '#description' => t('Method of handling multiple date fields in the same query. Return items that have any matching date field (date = field_1 OR field_2), or only those with matches in all selected date fields (date = field_1 AND field_2).'),
127      );
128
129  }
130
131  function options_validate($form, &$form_state) {
132    // It is very important to call the parent function here:
133    parent::options_validate($form, $form_state);
134
135    if ($form_state['values']['form_id'] == 'views_ui_config_item_form') {
136      $check_fields = array_filter($form_state['values']['options']['date_fields']);
137      if (empty($check_fields)) {
138        form_error($form['date_fields'], t('You must select at least one date field for this argument.'));
139      }
140      if (!preg_match('/^(?:\-[0-9]{1,4}|[0-9]{4}):(?:[\+|\-][0-9]{1,4}|[0-9]{4})$/', $form_state['values']['options']['year_range'])) {
141        form_error($form['year_range'], t('Date year range must be in the format -9:+9, 2005:2010, -9:2010, or 2005:+9'));
142      }
143    }
144  }
145
146  function options_submit($form, &$form_state) {
147    // It is very important to call the parent function here:
148    parent::options_submit($form, $form_state);
149
150    if ($form_state['values']['form_id'] == 'views_ui_config_item_form') {
151      $form_state['values']['options']['date_fields'] = array_filter($form_state['values']['options']['date_fields']);
152    }
153  }
154
155  // Update the summary values to show selected granularity.
156  function admin_summary() {
157    $fields = date_api_fields($this->definition['base']);
158    if (!empty($this->options['date_fields'])) {
159      $output = array();
160      foreach ($this->options['date_fields'] as $field) {
161        $output[] = $fields['name'][$field]['label'];
162      }
163      return implode('<br />'. $this->options['date_method'] .' ', $output);
164    }
165    else {
166      return parent::admin_summary();
167    }
168  }
169
170  /**
171   * Set the empty argument value to the current date,
172   * formatted appropriately for this argument.
173   */
174  function get_default_argument($raw = FALSE) {
175    $granularity = $this->options['granularity'];
176    if (!$raw && $this->options['default_argument_type'] == 'date') {
177      if ($granularity == 'week') {
178        $now = date_now();
179        $week = date_week(date_format($now, 'Y-m-d'));
180        return date_format($now, 'Y') .'-W'. $week;
181      }
182      else {
183        return date($this->format(), time());
184      }
185    }
186    else {
187      return parent::get_default_argument($raw);
188    }
189  }
190
191  function format() {
192    if (!empty($this->options['granularity'])) {
193      $date_handler = new date_sql_handler();
194      return $date_handler->views_formats($this->options['granularity']);
195    }
196    else {
197      return !empty($this->options[$this->option_name]) ? $this->options[$this->option_name] : 'Y-m';
198    }
199  }
200
201  /**
202   * Provide a link to the next level of the view from the summary.
203   */
204  function summary_name($data) {
205    $format = $this->date_handler->views_formats($this->options['granularity'], 'display');
206    $value = $data->{$this->name_alias};
207    $range = $this->date_handler->arg_range($value);
208    return date_format_date($range[0], 'custom', $format);
209  }
210
211  /**
212   * Provide the argument to use to link from the summary to the next level;
213   * this will be called once per row of a summary, and used as part of
214   * $view->get_url().
215   *
216   * @param $data
217   *   The query results for the row.
218   */
219  function summary_argument($data) {
220    $format = $this->date_handler->views_formats($this->options['granularity'], 'sql');
221    $value = $data->{$this->name_alias};
222    $range = $this->date_handler->arg_range($value);
223    return date_format_date($range[0], 'custom', $format);
224  }
225
226  /**
227   * Provide a link to the next level of the view from the argument.
228   */
229  function title() {
230    $format = $this->date_handler->views_formats($this->options['granularity'], 'display');
231    $range = $this->date_handler->arg_range($this->argument);
232    return date_format_date($range[0], 'custom', $format);
233  }
234
235  /**
236   * Create a summary query that matches the granularity.
237   *
238   * Needed or Views will do a groupby on the complete date instead
239   * of only the part of the date actually used in the argument.
240   */
241  function summary_query() {
242    $this->get_query_fields();
243
244    // No way to do summaries on more than one field at a time.
245    if (count($this->query_fields) > 1) {
246      return;
247    }
248
249    // Cause query->ensure_table to perform the correct join.
250    $this->table = $this->query_fields[0]['field']['table_name'];
251    $this->ensure_my_table();
252
253    $field = $this->query_fields[0]['field'];
254    $date_handler = $this->query_fields[0]['date_handler'];
255
256    // Get the SQL format for this granularity, like Y-m,
257    // and use that as the grouping value.
258    $format = $date_handler->views_formats($this->options['granularity'], 'sql');
259    $this->formula = $date_handler->sql_format($format, $date_handler->sql_field($field['fullname']));
260
261    // Add the computed field.
262    $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $this->formula, $field['query_name']);
263
264    return $this->summary_basics(FALSE);
265  }
266
267  function get_query_fields() {
268    $fields = date_api_fields($this->definition['base']);
269    $fields = $fields['name'];
270    $min_date = isset($this->min_date) ? $this->min_date : NULL;
271    $min_utc = isset($this->min_utc) ? $this->min_utc : NULL;
272    $max_date = isset($this->max_date) ? $this->max_date : NULL;
273    $max_utc = isset($this->max_utc) ? $this->max_utc : NULL;
274    $this->query_fields = array();
275    foreach ($this->options['date_fields'] as $delta => $name) {
276      if (array_key_exists($name, $fields) && $field = $fields[$name]) {
277        $date_handler = new date_sql_handler();
278        $date_handler->construct($field['sql_type'], date_default_timezone_name());
279        $date_handler->granularity = $this->options['granularity'];
280        date_views_set_timezone($date_handler, $this, $field);
281        $this->query_fields[] = array('field' => $field, 'date_handler' => $date_handler);
282      }
283    }
284  }
285
286  /**
287   * Make sure the date field is added to the query.
288   *
289   * Do this in pre_query() so it will get done even if the argument
290   * is the wildcard, since query() is skipped when the wildcard is used.
291   */
292  function pre_query() {
293    // Unset invalid date values before the query runs.
294    if (!empty($this->view->args) && count($this->view->args) > $this->position) {
295      $argument = $this->view->args[$this->position];
296      $parts = $this->date_handler->arg_parts($argument);
297      if (empty($parts[0]['date']) && empty($parts[0]['period'])) {
298        unset($this->view->args[$this->position]);
299      }
300    }
301  }
302
303  /**
304   * Set up the query for this argument.
305   *
306   * The argument sent may be found at $this->argument.
307   */
308  function query() {
309    $block_identifier = date_block_identifier($this->view);
310    if (!empty($this->view->block_identifier) || isset($_GET[$block_identifier])) {
311      // Retrieve the block arguments in a way that will work for
312      // urls like user/%/calendar/2009-04.
313      if (!empty($_GET[$block_identifier])) {
314        $path_args = explode('/', $this->view->get_path());
315        $mini_args = explode('/', $_GET[$block_identifier]);
316        foreach ($path_args as $pos => $key) {
317          if ($path_args[$pos] != '%') {
318            unset($mini_args[$pos]);
319          }
320        }
321        // Get rid of gaps in the array caused by embedded args.
322        $mini_args = array_values($mini_args);
323        $this->view->args = $mini_args;
324      }
325      $i = 0;
326      foreach ($this->view->argument as $argument) {
327        if ($argument->field == 'date_argument') {
328          $this->argument = $this->view->args[$argument->position];
329          break;
330        }
331        $i++;
332      }
333    }
334    $parts = $this->date_handler->arg_parts($this->argument);
335
336    foreach ($parts as $type) {
337      foreach ($type as $part) {
338        foreach ($part as $key => $value) {
339          if (!empty($value)) {
340            // The last part evaluated is the one that will 'stick'
341            // as the date type.
342            $this->granularity = $key;
343            $this->$key = $value;
344          }
345        }
346      }
347    }
348
349    $range = $this->date_handler->arg_range($this->argument);
350    $min_date = $range[0];
351    $max_date = $range[1];
352    $this->min_date = $min_date;
353    $this->max_date = $max_date;
354
355    // See if we're outside the allowed date range for our argument.
356    if (date_format($min_date, 'Y') < $this->view->date_info->min_allowed_year || date_format($max_date, 'Y') > $this->view->date_info->max_allowed_year) {
357      $this->forbid = TRUE;
358      $this->query->add_where('date', "0=1");
359      return;
360    }
361
362    // The second option seems to work better in the block view if
363    // set to something other than the original value.
364    // Need to keep an eye on this to be sure nothing else breaks.
365    //$format = $this->date_handler->views_formats($this->options['granularity'], 'sql');
366    $format = $this->date_handler->views_formats($this->granularity, 'sql');
367    $this->get_query_fields();
368    if (!empty($this->query_fields)) {
369      // Use set_where_group() with the selected date_method
370      // of 'AND' or 'OR' to create the where clause.
371      $this->query->set_where_group($this->options['date_method'], 'date');
372      foreach ($this->query_fields as $query_field) {
373        $field = $query_field['field'];
374        if ($field['table_name'] != $this->table || !empty($this->relationship)) {
375          $this->related_table_alias = $this->query->ensure_table($field['table_name'], $this->relationship);
376        }
377        $date_handler = $query_field['date_handler'];
378        $table_alias = !empty($this->related_table_alias) ? $this->related_table_alias : $field['table_name'];
379        $from_field = str_replace($field['table_name'] .'_', $table_alias .'.', $field['fromto'][0]);
380        $to_field = str_replace($field['table_name'] .'_', $table_alias .'.', $field['fromto'][1]);
381
382        if ($this->granularity != 'week') {
383          $from = $date_handler->sql_where_format($format, $from_field, '<=', date_format($max_date, $format));
384          $to   = $date_handler->sql_where_format($format, $to_field, '>=', date_format($min_date, $format));
385        }
386        else {
387          $format = DATE_FORMAT_DATETIME;
388          $from = $date_handler->sql_where_date('DATE', $from_field, '<=', date_format($max_date, $format));
389          $to   = $date_handler->sql_where_date('DATE', $to_field, '>=', date_format($min_date, $format));
390        }
391        $sql = str_replace('***table***', $field['table_name'], "($from AND $to)");
392        if ($sql) {
393          $this->query->add_where('date', $sql);
394        }
395      }
396    }
397  }
398}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.