Projet

Général

Profil

Paste
Télécharger (16 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / date / date_views / includes / date_views_argument_handler_simple.inc @ 599a39cd

1 85ad3d82 Assos Assos
<?php
2 599a39cd Assos Assos
3 85ad3d82 Assos Assos
/**
4
 * @file
5
 * Date API views argument handler.
6
 */
7
8
/**
9 599a39cd Assos Assos
 * Date API views argument handler.
10 85ad3d82 Assos Assos
 */
11
class date_views_argument_handler_simple extends views_handler_argument_date {
12
13
  /**
14 599a39cd Assos Assos
   * {@inheritdoc}
15 85ad3d82 Assos Assos
   */
16
  function init(&$view, &$options) {
17
    parent::init($view, $options);
18
19
    // Add a date handler.
20
    module_load_include('inc', 'date_api', 'date_api_sql');
21
    $this->date_handler = new date_sql_handler(DATE_UNIX);
22
    if (!empty($this->definition['field_name'])) {
23
      $field = field_info_field($this->definition['field_name']);
24
      if (!empty($field) && !empty($field['type'])) {
25
        $this->date_handler->date_type = $field['type'];
26
        $this->original_table = $this->definition['table'];
27
      }
28
      $this->date_handler->db_timezone = date_get_timezone_db($field['settings']['tz_handling']);
29
      $this->date_handler->local_timezone = date_get_timezone($field['settings']['tz_handling']);
30
    }
31
    $this->date_handler->granularity = $this->options['granularity'];
32 599a39cd Assos Assos
    // This value needs to be initialized so it exists even if the query
33
    // doesn't run.
34 85ad3d82 Assos Assos
    $this->date_handler->placeholders = array();
35
36
    $this->format = $this->date_handler->views_formats($this->date_handler->granularity, 'display');
37
    $this->sql_format = $this->date_handler->views_formats($this->date_handler->granularity, 'sql');
38 599a39cd Assos Assos
    // $this->arg_format is the format the parent date handler will use to
39
    // create a default argument.
40 85ad3d82 Assos Assos
    $this->arg_format = $this->format();
41
42 599a39cd Assos Assos
    // Identify the base table for this field. It will be used to call for the
43
    // right query field options.
44 85ad3d82 Assos Assos
    $this->base_table = $this->table;
45
  }
46
47 b720ea3e Assos Assos
  /**
48
   * {@inheritdoc}
49
   */
50 85ad3d82 Assos Assos
  function format() {
51
    if (!empty($this->options['granularity'])) {
52
      return $this->date_handler->views_formats($this->options['granularity']);
53
    }
54
    else {
55
      return !empty($this->options[$this->option_name]) ? $this->options[$this->option_name] : 'Y-m';
56
    }
57
  }
58
59
  /**
60 599a39cd Assos Assos
   * {@inheritdoc}
61 85ad3d82 Assos Assos
   */
62
  function get_default_argument($raw = FALSE) {
63
    $is_default = FALSE;
64
65
    if (!$raw && $this->options['default_argument_type'] == 'date') {
66
      $granularity = $this->options['granularity'];
67
      if ($granularity == 'week') {
68
        $now = date_now();
69
        $week = date_week(date_format($now, 'Y-m-d'));
70 db9ffd17 Assos Assos
        $value = date_format($now, 'o') . '-W' . date_pad($week);
71 85ad3d82 Assos Assos
      }
72
      else {
73
        $value = date($this->arg_format, REQUEST_TIME);
74
      }
75
      drupal_alter('date_default_argument', $this, $value);
76
77
      return $value;
78
    }
79
80
    // Let the parent argument handle options like node created date.
81
    return parent::get_default_argument($raw);
82
  }
83
84
  /**
85 599a39cd Assos Assos
   * {@inheritdoc}
86 85ad3d82 Assos Assos
   */
87
  function option_definition() {
88 599a39cd Assos Assos
    // Default value for the date_fields option.
89 85ad3d82 Assos Assos
    $options = parent::option_definition();
90
    $options['year_range'] = array('default' => '-3:+3');
91
    $options['granularity'] = array('default' => 'month');
92 b720ea3e Assos Assos
    $options['granularity_reset'] = array('default' => FALSE);
93 85ad3d82 Assos Assos
    $options['default_argument_type']['default'] = 'date';
94
    $options['add_delta'] = array('default' => '');
95
    $options['use_fromto'] = array('default' => '');
96
    $options['title_format'] = array('default' => '');
97
    $options['title_format_custom'] = array('default' => '');
98
    return $options;
99
  }
100
101
  /**
102 599a39cd Assos Assos
   * {@inheritdoc}
103 85ad3d82 Assos Assos
   */
104
  function options_form(&$form, &$form_state) {
105
    parent::options_form($form, $form_state);
106
107
    // Add an option to control the format of the summary.
108
    $options = array(
109
      '' => t('Default format'),
110
      'custom' => t('Custom format'),
111
    );
112
    $example_month = date_format_date(date_example_date(), 'custom', $this->date_handler->views_formats('month', 'display'));
113
    $example_day = date_format_date(date_example_date(), 'custom', $this->date_handler->views_formats('day', 'display'));
114
115
    $form['title_format'] = array(
116
      '#type' => 'select',
117
      '#title' => t('Date format options'),
118
      '#default_value' => $this->options['title_format'],
119
      '#options' => $options,
120
      '#description' => t('The date format used in titles and summary links for this argument. The default format is based on the granularity of the filter, i.e. month: @example_month, day: @example_day.', array('@example_month' => $example_month, '@example_day' => $example_day)),
121
      '#attributes' => array('class' => array('dependent-options')),
122
      '#states' => array(
123
        'visible' => array(
124 b720ea3e Assos Assos
          ':input[name="options[default_action]"]' => array(
125
            'value' => 'summary',
126
          ),
127 85ad3d82 Assos Assos
        ),
128
      ),
129
    );
130
131
    $form['title_format_custom'] = array(
132
      '#type' => 'textfield',
133
      '#title' => t('Custom summary date format'),
134
      '#default_value' => $this->options['title_format_custom'],
135
      '#description' => t("A custom format for the title and summary date format. Define a php date format string like 'm-d-Y H:i' (see <a href=\"@link\">http://php.net/date</a> for more details).", array('@link' => 'http://php.net/date')),
136
      '#attributes' => array('class' => array('dependent-options')),
137
      '#states' => array(
138
        'visible' => array(
139 b720ea3e Assos Assos
          ':input[name="options[title_format]"]' => array(
140
            'value' => 'custom',
141
          ),
142 85ad3d82 Assos Assos
        ),
143
      ),
144
    );
145
146 b720ea3e Assos Assos
    // Get default granularity options
147 85ad3d82 Assos Assos
    $options = $this->date_handler->date_parts();
148 599a39cd Assos Assos
149 b720ea3e Assos Assos
    // Add the 'week' option.
150
    $options += array(
151
      'week' => t('Week', array(), array(
152
        'context' => 'datetime',
153
      )),
154
    );
155
156 85ad3d82 Assos Assos
    $form['granularity'] = array(
157
      '#title' => t('Granularity'),
158
      '#type' => 'radios',
159
      '#options' => $options,
160
      '#default_value' => $this->options['granularity'],
161
      '#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."),
162
    );
163
164 b720ea3e Assos Assos
    $form['granularity_reset'] = array(
165
      '#title' => t('Use granularity from argument value'),
166
      '#type' => 'checkbox',
167
      '#default_value' => $this->options['granularity_reset'],
168
      '#description' => t("If the granularity of argument value is different from selected, use it from argument value."),
169
    );
170
171 85ad3d82 Assos Assos
    $form['year_range'] = array(
172
      '#title' => t('Date year range'),
173
      '#type' => 'textfield',
174
      '#default_value' => $this->options['year_range'],
175
      '#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)' ."),
176
    );
177
178
    $form['use_fromto'] = array(
179
      '#type' => 'radios',
180
      '#title' => t('Dates to compare'),
181
      '#default_value' => $this->options['use_fromto'],
182
      '#options' => array('' => t('Start/End date range'), 'no' => t('Only this field')),
183
      '#description' => t("If selected the view will check if any value starting with the 'Start' date and ending with the 'End' date matches the view criteria. Otherwise the view will be limited to the specifically selected fields. Comparing to the whole Start/End range is the recommended setting when using this filter in a Calendar. When using the Start/End option, it is not necessary to add both the Start and End fields to the filter, either one will do."),
184
    );
185
186
    $access = TRUE;
187
    if (!empty($this->definition['field_name'])) {
188
      $field = field_info_field($this->definition['field_name']);
189
      $access = $field['cardinality'] != 1;
190
    }
191
    $form['add_delta'] = array(
192
      '#type' => 'radios',
193
      '#title' => t('Add multiple value identifier'),
194
      '#default_value' => $this->options['add_delta'],
195
      '#options' => array('' => t('No'), 'yes' => t('Yes')),
196
      '#description' => t('Add an identifier to the view to show which multiple value date fields meet the filter criteria. Note: This option may introduce duplicate values into the view. Required when using multiple value fields in a Calendar or any time you want the node view of multiple value dates to display only the values that match the view filters.'),
197 b720ea3e Assos Assos
      // Only let mere mortals tweak this setting for multi-value fields.
198 85ad3d82 Assos Assos
      '#access' => $access,
199
    );
200
  }
201
202 b720ea3e Assos Assos
  /**
203
   * {@inheritdoc}
204
   */
205 85ad3d82 Assos Assos
  function options_validate(&$form, &$form_state) {
206
    // It is very important to call the parent function here:
207
    parent::options_validate($form, $form_state);
208 b720ea3e Assos Assos
    if (!preg_match('/^(?:\-[0-9]{1,4}|[0-9]{4}):(?:[\+\-][0-9]{1,4}|[0-9]{4})$/', $form_state['values']['options']['year_range'])) {
209 85ad3d82 Assos Assos
      form_error($form['year_range'], t('Date year range must be in the format -9:+9, 2005:2010, -9:2010, or 2005:+9'));
210
    }
211
  }
212
213
  /**
214 599a39cd Assos Assos
   * {@inheritdoc}
215 85ad3d82 Assos Assos
   */
216
  function summary_name($data) {
217
    $value = $data->{$this->name_alias};
218
    if (empty($value) && !empty($this->definition['empty field name'])) {
219
      return $this->definition['empty field name'];
220
    }
221
    elseif (empty($value)) {
222
      return $this->options['wildcard_substitution'];
223
    }
224
    $format = !empty($this->options['title_format_custom']) && !empty($this->options['title_format_custom']) ? $this->options['title_format_custom'] : $this->date_handler->views_formats($this->options['granularity'], 'display');
225
    $range = $this->date_handler->arg_range($value);
226
    return date_format_date($range[0], 'custom', $format);
227
  }
228
229
  /**
230 599a39cd Assos Assos
   * {@inheritdoc}
231 85ad3d82 Assos Assos
   */
232
  function title() {
233
    $format = !empty($this->options['title_format_custom']) && !empty($this->options['title_format_custom']) ? $this->options['title_format_custom'] : $this->date_handler->views_formats($this->options['granularity'], 'display');
234
    $range = $this->date_handler->arg_range($this->argument);
235
    return date_format_date($range[0], 'custom', $format);
236 b720ea3e Assos Assos
  }
237 85ad3d82 Assos Assos
238
  /**
239 599a39cd Assos Assos
   * {@inheritdoc}
240 85ad3d82 Assos Assos
   */
241
  function summary_argument($data) {
242
    $format = $this->date_handler->views_formats($this->options['granularity'], 'sql');
243
    $value = $data->{$this->name_alias};
244
    if (empty($value)) {
245
      return $this->options['exception']['value'];
246
    }
247
    $range = $this->date_handler->arg_range($value);
248
    return date_format_date($range[0], 'custom', $format);
249
  }
250
251
  /**
252 599a39cd Assos Assos
   * {@inheritdoc}
253 85ad3d82 Assos Assos
   */
254
  function summary_query() {
255 599a39cd Assos Assos
    // Inject a test for valid date range before the summary query.
256
    // @todo The summary values are computed by the database. Unless the
257
    // database has built-in timezone handling it will use a fixed offset,
258
    // which will not be right for all dates. The only way I can see to make
259
    // this work right is to store the offset for each date in the database so
260
    // it can be added to the base date value before the database formats the
261
    // result. Because this is a huge architectural change, it won't go in
262
    // until we start a new branch.
263 85ad3d82 Assos Assos
    $this->formula = $this->date_handler->sql_format($this->sql_format, $this->date_handler->sql_field("***table***.$this->real_field"));
264
    $this->ensure_my_table();
265 599a39cd Assos Assos
266 85ad3d82 Assos Assos
    // Now that our table is secure, get our formula.
267
    $formula = $this->get_formula();
268
269 599a39cd Assos Assos
    // Add the field, give it an alias that does NOT match the actual field
270
    // name or grouping won't work right.
271 85ad3d82 Assos Assos
    $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field . '_summary');
272
    $this->query->set_count_field(NULL, $formula, $this->field);
273
274
    return $this->summary_basics(FALSE);
275
  }
276
277
  /**
278 599a39cd Assos Assos
   * {@inheritdoc}
279 85ad3d82 Assos Assos
   */
280
  function query($group_by = FALSE) {
281 599a39cd Assos Assos
    // Inject a test for valid date range before the regular query. Override
282
    // the parent query to be able to control the $group.
283
    // @todo Not doing anything with $group_by yet, need to figure out what has
284
    // to be done.
285 85ad3d82 Assos Assos
    if ($this->date_forbid()) {
286
      return;
287
    }
288
289 599a39cd Assos Assos
    // See if we need to reset granularity based on an argument value. Make
290
    // sure we don't try to reset to some bogus value if someone has typed in
291
    // an unexpected argument.
292 b720ea3e Assos Assos
    if ($this->options['granularity_reset'] && $granularity = $this->date_handler->arg_granularity($this->argument)) {
293 85ad3d82 Assos Assos
      $this->date_handler->granularity = $granularity;
294
      $this->format = $this->date_handler->views_formats($this->date_handler->granularity, 'display');
295
      $this->sql_format = $this->date_handler->views_formats($this->date_handler->granularity, 'sql');
296
    }
297
    $this->granularity = $this->date_handler->granularity;
298
    $this->ensure_my_table();
299
    $group = !empty($this->options['date_group']) ? $this->options['date_group'] : 0;
300
301 599a39cd Assos Assos
    // If requested, add the delta field to the view so we can later find the
302
    // value that matched our query.
303 85ad3d82 Assos Assos
    if (!empty($this->options['add_delta']) && (substr($this->real_field, -6) == '_value' || substr($this->real_field, -7) == '_value2')) {
304
      $this->query->add_field($this->table_alias, 'delta');
305
      $real_field_name = str_replace(array('_value', '_value2'), '', $this->real_field);
306
      $this->query->add_field($this->table_alias, 'entity_id', 'date_id_' . $real_field_name);
307
      $this->query->add_field($this->table_alias, 'delta', 'date_delta_' . $real_field_name);
308
    }
309
310
    $format = $this->date_handler->granularity == 'week' ? DATE_FORMAT_DATETIME : $this->sql_format;
311
    $view_min = date_format($this->min_date, $format);
312
    $view_max = date_format($this->max_date, $format);
313
    $view_min_placeholder = $this->placeholder();
314
    $view_max_placeholder = $this->placeholder();
315
    $this->date_handler->placeholders = array($view_min_placeholder => $view_min, $view_max_placeholder => $view_max);
316
317 599a39cd Assos Assos
    // Are we comparing this field only or the Start/End date range to the view
318
    // criteria?
319 85ad3d82 Assos Assos
    if (!empty($this->options['use_fromto'])) {
320
      // The simple case, match the field to the view range.
321
      $field = $this->date_handler->sql_field($this->table_alias . '.' . $this->real_field, NULL, $this->min_date);
322
      $field = $this->date_handler->sql_format($format, $field);
323
      $this->query->add_where_expression($group, "$field >= $view_min_placeholder AND $field <= $view_max_placeholder", array($view_min_placeholder => $view_min, $view_max_placeholder => $view_max));
324
325
    }
326
    else {
327 599a39cd Assos Assos
      // Look for the intersection of the range of the date field with the
328
      // range of the view. Get the Start/End values for this field. Retrieve
329
      // using the original table name. Swap the current table name (adjusted
330
      // for relationships) into the query.
331
      // @todo We may be able to use Views substitutions here, investigate that
332
      // later.
333 85ad3d82 Assos Assos
      $fields = date_views_fields($this->base_table);
334
      $fields = $fields['name'];
335
      $fromto = $fields[$this->original_table . '.' . $this->real_field]['fromto'];
336
337
      $value_min = str_replace($this->original_table, $this->table_alias, $fromto[0]);
338
      $value_max = str_replace($this->original_table, $this->table_alias, $fromto[1]);
339
      $field_min = $this->date_handler->sql_field($value_min, NULL, $this->min_date);
340
      $field_min = $this->date_handler->sql_format($format, $field_min);
341
      $field_max = $this->date_handler->sql_field($value_max, NULL, $this->max_date);
342
      $field_max = $this->date_handler->sql_format($format, $field_max);
343
      $this->query->add_where_expression($group, "$field_max >= $view_min_placeholder AND $field_min <= $view_max_placeholder", array($view_min_placeholder => $view_min, $view_max_placeholder => $view_max));
344
    }
345
  }
346
347
  /**
348 b720ea3e Assos Assos
   * Add a callback.
349
   *
350 599a39cd Assos Assos
   * To determine if we have moved outside the valid date range for this
351
   * argument.
352 85ad3d82 Assos Assos
   */
353
  function date_forbid() {
354
    if (empty($this->argument)) {
355
      return TRUE;
356
    }
357
    $this->date_range = $this->date_handler->arg_range($this->argument);
358
    $this->min_date = $this->date_range[0];
359
    $this->max_date = $this->date_range[1];
360
    $this->limit = date_range_years($this->options['year_range']);
361
    $group = !empty($this->options['date_group']) ? $this->options['date_group'] : 0;
362
363
    // See if we're outside the allowed date range for our argument.
364
    if (date_format($this->min_date, 'Y') < $this->limit[0] || date_format($this->max_date, 'Y') > $this->limit[1]) {
365
      $this->forbid = TRUE;
366
      $this->view->build_info['fail'] = TRUE;
367
      return TRUE;
368
    }
369
    return FALSE;
370
  }
371
372
}