Révision a45e4bc1
Ajouté par Assos Assos il y a environ 9 ans
drupal7/sites/all/modules/webform/components/date.inc | ||
---|---|---|
15 | 15 |
'pid' => 0, |
16 | 16 |
'weight' => 0, |
17 | 17 |
'value' => '', |
18 |
'mandatory' => 0,
|
|
18 |
'required' => 0,
|
|
19 | 19 |
'extra' => array( |
20 | 20 |
'timezone' => 'user', |
21 |
'exclude' => array(), |
|
21 | 22 |
'start_date' => '-2 years', |
22 | 23 |
'end_date' => '+2 years', |
23 | 24 |
'year_textfield' => 0, |
... | ... | |
25 | 26 |
'title_display' => 0, |
26 | 27 |
'description' => '', |
27 | 28 |
'private' => FALSE, |
29 |
'analysis' => FALSE, |
|
28 | 30 |
), |
29 | 31 |
); |
30 | 32 |
} |
... | ... | |
73 | 75 |
'#access' => variable_get('configurable_timezones', 1), |
74 | 76 |
); |
75 | 77 |
|
78 |
$form['extra']['exclude'] = array( |
|
79 |
'#type' => 'checkboxes', |
|
80 |
'#title' => t('Hide'), |
|
81 |
'#default_value' => $component['extra']['exclude'], |
|
82 |
'#options' => array( |
|
83 |
'day' => t('Day'), |
|
84 |
'month' => t('Month'), |
|
85 |
'year' => t('Year'), |
|
86 |
), |
|
87 |
'#description' => t('A hidden day or month will be set to 1. A hidden year will be set to the year of the default value.'), |
|
88 |
'#weight' => 3, |
|
89 |
); |
|
90 |
|
|
76 | 91 |
$form['display']['datepicker'] = array( |
77 | 92 |
'#type' => 'checkbox', |
78 | 93 |
'#title' => t('Enable popup calendar'), |
... | ... | |
110 | 125 |
'#parents' => array('extra', 'end_date'), |
111 | 126 |
); |
112 | 127 |
|
128 |
$form['#validate'] = array('_webform_edit_date_validate'); |
|
113 | 129 |
return $form; |
114 | 130 |
} |
115 | 131 |
|
132 |
/** |
|
133 |
* Implements hook_form_id_validate. |
|
134 |
* |
|
135 |
* Warns user about hiding all the date fields and not using the date picker. |
|
136 |
*/ |
|
137 |
function _webform_edit_date_validate($form, &$form_state) { |
|
138 |
// Reduce checkbox values to simple non-associative array of values. |
|
139 |
form_set_value($form['extra']['exclude'], array_filter(array_values($form_state['values']['extra']['exclude'])), $form_state); |
|
140 |
|
|
141 |
// Note that Drupal 7 doesn't support setting errors no checkboxes due to |
|
142 |
// browser issues. @see https://www.drupal.org/node/222380 |
|
143 |
if (count($form_state['values']['extra']['exclude']) == 3) { |
|
144 |
form_set_error('extra][exclude', 'The day, month and year can\'t all be hidden.'); |
|
145 |
} |
|
146 |
if ($form_state['values']['extra']['exclude'] == array('month')) { |
|
147 |
form_set_error('extra][exclude', 'You cannot hide just the month.'); |
|
148 |
} |
|
149 |
|
|
150 |
// Validate that the start and end dates are valid. Don't validate the default |
|
151 |
// date because with token substitution, it might not be valid at component |
|
152 |
// definition time. Also note that validation was introduced in 7.x-4.8 and |
|
153 |
// previously-defined webform may have invalid start and end dates. |
|
154 |
foreach (array('start_date', 'end_date') as $field) { |
|
155 |
if (trim($form_state['values']['extra'][$field]) && !($date[$field] = webform_strtodate('c', $form_state['values']['extra'][$field]))) { |
|
156 |
form_set_error("extra][$field", t('The @field could not be interpreted in <a href="http://www.gnu.org/software/tar/manual/html_chapter/Date-input-formats.html">GNU Date Input Format</a>.', |
|
157 |
array('@field' => $form['validation'][$field]['#title']))); |
|
158 |
} |
|
159 |
} |
|
160 |
if (!empty($date['start_date']) && !empty($date['end_date']) && $date['end_date'] < $date['start_date']) { |
|
161 |
form_set_error('extra][end_date', t('The End date must be on or after the Start date.')); |
|
162 |
} |
|
163 |
} |
|
164 |
|
|
116 | 165 |
/** |
117 | 166 |
* Implements _webform_render_component(). |
118 | 167 |
*/ |
119 |
function _webform_render_date($component, $value = NULL, $filter = TRUE) { |
|
168 |
function _webform_render_date($component, $value = NULL, $filter = TRUE, $submission = NULL) {
|
|
120 | 169 |
$node = isset($component['nid']) ? node_load($component['nid']) : NULL; |
121 | 170 |
|
122 | 171 |
$element = array( |
123 | 172 |
'#type' => 'date', |
124 |
'#title' => $filter ? _webform_filter_xss($component['name']) : $component['name'],
|
|
173 |
'#title' => $filter ? webform_filter_xss($component['name']) : $component['name'], |
|
125 | 174 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
126 | 175 |
'#weight' => $component['weight'], |
127 |
'#description' => $filter ? _webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'],
|
|
128 |
'#required' => $component['mandatory'],
|
|
176 |
'#description' => $filter ? webform_filter_descriptions($component['extra']['description'], $node) : $component['extra']['description'], |
|
177 |
'#required' => $component['required'],
|
|
129 | 178 |
'#start_date' => trim($component['extra']['start_date']), |
130 | 179 |
'#end_date' => trim($component['extra']['end_date']), |
180 |
'#reference_timestamp' => $submission && $submission->completed ? $submission->completed : NULL, |
|
131 | 181 |
'#year_textfield' => $component['extra']['year_textfield'], |
132 |
'#default_value' => $filter ? _webform_filter_values($component['value'], $node, NULL, NULL, FALSE) : $component['value'],
|
|
182 |
'#default_value' => $filter ? webform_replace_tokens($component['value'], $node) : $component['value'],
|
|
133 | 183 |
'#timezone' => $component['extra']['timezone'], |
184 |
'#exclude' => $component['extra']['exclude'], |
|
134 | 185 |
'#process' => array('webform_expand_date'), |
135 | 186 |
'#theme' => 'webform_date', |
136 | 187 |
'#theme_wrappers' => array('webform_element'), |
... | ... | |
160 | 211 |
* Form API #process function for Webform date fields. |
161 | 212 |
*/ |
162 | 213 |
function webform_expand_date($element) { |
214 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user'; |
|
215 |
|
|
163 | 216 |
// Accept a string or array value for #default_value. |
164 | 217 |
if (!empty($element['#default_value']) && is_string($element['#default_value'])) { |
165 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user'; |
|
166 | 218 |
$timestring = webform_strtodate('c', $element['#default_value'], $timezone); |
167 | 219 |
$element['#default_value'] = webform_date_array($timestring, 'date'); |
168 | 220 |
} |
... | ... | |
190 | 242 |
// Let Drupal do it's normal expansion. |
191 | 243 |
$element = form_process_date($element); |
192 | 244 |
|
245 |
// Convert relative dates to absolute and calculate the year, month and day. |
|
246 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user'; |
|
247 |
foreach (array('start', 'end') as $start_end) { |
|
248 |
$element_field = &$element["#{$start_end}_date"]; |
|
249 |
$element_field = $element_field ? webform_strtodate('Y-m-d', $element_field, $timezone, $element['#reference_timestamp']) : ''; |
|
250 |
if ($element_field) { |
|
251 |
$parts = explode('-', $element_field); |
|
252 |
} |
|
253 |
else { |
|
254 |
$parts = $start_end == 'start' ? array(webform_strtodate('Y', '-2 years'), 1, 1) : array(webform_strtodate('Y', '+2 years'), 12, 31); |
|
255 |
$element_field = ''; |
|
256 |
} |
|
257 |
unset($element_field); // Drop PHP reference. |
|
258 |
$parts[3] = $parts[0] . '-' . $parts[1] . '-' . $parts[2]; |
|
259 |
$range[$start_end] = array_combine(array('year', 'month', 'day', 'date'), $parts); |
|
260 |
} |
|
261 |
|
|
262 |
// The start date is not guaranteeed to be early than the end date for |
|
263 |
// historical reasons. |
|
264 |
if ($range['start']['date'] > $range['end']['date']) { |
|
265 |
$temp = $range['start']; |
|
266 |
$range['start'] = $range['end']; |
|
267 |
$range['end'] = $temp; |
|
268 |
} |
|
269 |
|
|
270 |
// Restrict the months and days when not all options are valid choices. |
|
271 |
if ($element['#start_date'] && $element['#end_date']) { |
|
272 |
$delta_months = ($range['end']['year'] * 12 + $range['end']['month']) - ($range['start']['year'] * 12 + $range['start']['month']); |
|
273 |
if ($delta_months < 11) { |
|
274 |
// There are 10 or fewer months between the start and end date. If there |
|
275 |
// were 11, then every month would be possible, and the menu select |
|
276 |
// should not be pruned. |
|
277 |
$month_options = &$element['month']['#options']; |
|
278 |
if ($range['start']['month'] <= $range['end']['month']) { |
|
279 |
$month_options = array_intersect_key($month_options, array_flip(range($range['start']['month'], $range['end']['month']))); |
|
280 |
} |
|
281 |
else { |
|
282 |
$month_options = array_intersect_key($month_options, array_flip(range($range['start']['month'], 12))) + |
|
283 |
array_intersect_key($month_options, array_flip(range(1, $range['end']['month']))); |
|
284 |
} |
|
285 |
unset($month_options); // Drop PHP reference. |
|
286 |
if ($delta_months <= 1) { |
|
287 |
// The start and end date are either on the same month or consequtive |
|
288 |
// months. See if the days should be pruned. |
|
289 |
$day_options = &$element['day']['#options']; |
|
290 |
if ($range['start']['month'] == $range['end']['month']) { |
|
291 |
// Range is within the same month. The days are a simple range from |
|
292 |
// start day to end day. |
|
293 |
$day_options = array_intersect_key($day_options, array_flip(range($range['start']['day'], $range['end']['day']))); |
|
294 |
} |
|
295 |
elseif ($range['start']['day'] > $range['end']['day'] + 1) { |
|
296 |
// Range spans two months and at least one day would be omitted. |
|
297 |
$days_in_month = date('t', mktime(0, 0, 0, $range['start']['month'], 1, $range['start']['year'])); |
|
298 |
$day_options = array_intersect_key($day_options, array_flip(range($range['start']['day'], $days_in_month))) + |
|
299 |
array_intersect_key($day_options, array_flip(range(1, $range['end']['day']))); |
|
300 |
} |
|
301 |
unset($day_options); // Drop PHP reference. |
|
302 |
} |
|
303 |
} |
|
304 |
} |
|
305 |
|
|
193 | 306 |
// Set default values. |
194 | 307 |
foreach ($default_values as $type => $value) { |
195 | 308 |
switch ($type) { |
196 | 309 |
case 'month': |
197 | 310 |
$none = t('Month'); |
311 |
$hidden_default = 1; |
|
198 | 312 |
break; |
199 | 313 |
case 'day': |
200 | 314 |
$none = t('Day'); |
315 |
$hidden_default = 1; |
|
201 | 316 |
break; |
202 | 317 |
case 'year': |
203 | 318 |
$none = t('Year'); |
319 |
$hidden_default = !empty($element['#default_value']['year']) ? $element['#default_value']['year'] : webform_strtodate('Y', 'today', $timezone); |
|
204 | 320 |
break; |
205 | 321 |
} |
206 | 322 |
unset($element[$type]['#value']); |
207 | 323 |
$element[$type]['#title'] = $none; |
208 | 324 |
$element[$type]['#title_display'] = 'invisible'; |
209 |
$element[$type]['#default_value'] = isset($default_values[$type]) ? $default_values[$type] : NULL;
|
|
325 |
$element[$type]['#default_value'] = $default_values[$type];
|
|
210 | 326 |
$element[$type]['#options'] = array('' => $none) + $element[$type]['#options']; |
211 |
}
|
|
212 |
|
|
213 |
// Convert relative dates to absolute ones.
|
|
214 |
foreach (array('start_date', 'end_date') as $start_end) {
|
|
215 |
$timezone = $element['#timezone'] != 'user' ? NULL : 'user';
|
|
216 |
$date = webform_strtodate('Y-m-d', $element['#' . $start_end], $timezone);
|
|
217 |
$element['#' . $start_end] = $date ? $date : '';
|
|
327 |
if (in_array($type, $element['#exclude'])) {
|
|
328 |
$element[$type] += array( |
|
329 |
'#prefix' => '<div class="webform-date-field-wrapper element-invisible">',
|
|
330 |
'#suffix' => '</div>',
|
|
331 |
);
|
|
332 |
$element[$type]['#default_value'] = $hidden_default;
|
|
333 |
}
|
|
218 | 334 |
} |
219 | 335 |
|
220 | 336 |
// Tweak the year field. |
... | ... | |
225 | 341 |
unset($element['year']['#options']); |
226 | 342 |
} |
227 | 343 |
elseif ($element['#start_date'] || $element['#end_date']) { |
228 |
$start_year = $element['#start_date'] ? webform_strtodate('Y', $element['#start_date']) : webform_strtodate('Y', '-2 years'); |
|
229 |
$end_year = $element['#end_date'] ? webform_strtodate('Y', $element['#end_date']) : webform_strtodate('Y', '+2 years'); |
|
230 |
$element['year']['#options'] = array('' => t('Year')) + drupal_map_assoc(range($start_year, $end_year)); |
|
344 |
$element['year']['#options'] = array('' => t('Year')) + drupal_map_assoc(range($range['start']['year'], $range['end']['year'])); |
|
231 | 345 |
} |
232 | 346 |
|
233 | 347 |
return $element; |
... | ... | |
250 | 364 |
$element['day']['#attributes']['class'][] = 'error'; |
251 | 365 |
} |
252 | 366 |
|
367 |
// Add HTML5 required attribute, if needed. |
|
368 |
if ($element['#required']) { |
|
369 |
$element['year']['#attributes']['required'] = 'required'; |
|
370 |
$element['month']['#attributes']['required'] = 'required'; |
|
371 |
$element['day']['#attributes']['required'] = 'required'; |
|
372 |
} |
|
373 |
|
|
253 | 374 |
$class = array('webform-container-inline'); |
254 | 375 |
|
255 | 376 |
// Add the JavaScript calendar if available (provided by Date module package). |
... | ... | |
280 | 401 |
* Element validation for Webform date fields. |
281 | 402 |
*/ |
282 | 403 |
function webform_validate_date($element, $form_state) { |
283 |
// Check if the user filled the required fields. |
|
284 |
foreach (array('day', 'month', 'year') as $field_type) { |
|
285 |
if (!is_numeric($element[$field_type]['#value']) && $element['#required']) { |
|
286 |
form_error($element, t('!name field is required.', array('!name' => $element['#title']))); |
|
404 |
if ($element['month']['#value'] !== '' || $element['day']['#value'] !== '' || $element['year']['#value'] !== '') { |
|
405 |
// Check that each part of the date has been filled in. |
|
406 |
foreach (array('day', 'month', 'year') as $field_type) { |
|
407 |
if (empty($element[$field_type]['#value'])) { |
|
408 |
form_error($element[$field_type], t('!part in !name is missing.', array('!name' => $element['#title'], '!part' => $element[$field_type]['#title']))); |
|
409 |
$missing_fields = TRUE; |
|
410 |
} |
|
411 |
} |
|
412 |
if (isset($missing_fields)) { |
|
287 | 413 |
return; |
288 | 414 |
} |
289 |
} |
|
290 | 415 |
|
291 |
if ($element['month']['#value'] !== '' || $element['day']['#value'] !== '' || $element['year']['#value'] !== '') { |
|
292 | 416 |
// Check for a valid date. |
293 |
if (!checkdate((int) $element['month']['#value'], (int) $element['day']['#value'], (int) $element['year']['#value'])) {
|
|
417 |
if (!checkdate($element['month']['#value'], $element['day']['#value'], $element['year']['#value'])) {
|
|
294 | 418 |
form_error($element, t('Entered !name is not a valid date.', array('!name' => $element['#title']))); |
295 | 419 |
return; |
296 | 420 |
} |
... | ... | |
299 | 423 |
$timestamp = strtotime($element['year']['#value'] . '-' . $element['month']['#value'] . '-' . $element['day']['#value']); |
300 | 424 |
$format = webform_date_format('short'); |
301 | 425 |
|
302 |
// Flip start and end if needed. |
|
426 |
// Flip start and end if needed. Prior to 7.x-4.8, it was possible to save |
|
427 |
// a date component with the end date earlier than the start date. |
|
303 | 428 |
$date1 = strtotime($element['#start_date']); |
304 | 429 |
$date2 = strtotime($element['#end_date']); |
305 | 430 |
if ($date1 !== FALSE && $date2 !== FALSE) { |
... | ... | |
312 | 437 |
} |
313 | 438 |
|
314 | 439 |
// Check that the date is after the start date. |
315 |
if ($start_date !== FALSE) { |
|
316 |
if ($timestamp < $start_date) { |
|
317 |
form_error($element, t('The entered date must be @start_date or later.', array('@start_date' => date($format, $start_date)))); |
|
318 |
} |
|
440 |
if ($start_date !== FALSE && $timestamp < $start_date) { |
|
441 |
form_error($element, t('The entered date must be @start_date or later.', array('@start_date' => date($format, $start_date)))); |
|
319 | 442 |
} |
320 | 443 |
|
321 | 444 |
// Check that the date is before the end date. |
322 |
if ($end_date !== FALSE) { |
|
323 |
if ($timestamp > $end_date) { |
|
324 |
form_error($element, t('The entered date must be @end_date or earlier.', array('@end_date' => date($format, $end_date)))); |
|
325 |
} |
|
445 |
if ($end_date !== FALSE && $timestamp > $end_date) { |
|
446 |
form_error($element, t('The entered date must be @end_date or earlier.', array('@end_date' => date($format, $end_date)))); |
|
326 | 447 |
} |
327 | 448 |
} |
449 |
elseif ($element['#required']) { |
|
450 |
form_error($element, t('!name field is required.', array('!name' => $element['#title']))); |
|
451 |
} |
|
328 | 452 |
} |
329 | 453 |
|
330 | 454 |
/** |
... | ... | |
338 | 462 |
/** |
339 | 463 |
* Implements _webform_display_component(). |
340 | 464 |
*/ |
341 |
function _webform_display_date($component, $value, $format = 'html') { |
|
465 |
function _webform_display_date($component, $value, $format = 'html', $submission = array()) {
|
|
342 | 466 |
$value = webform_date_array(isset($value[0]) ? $value[0] : '', 'date'); |
343 | 467 |
|
344 | 468 |
return array( |
345 | 469 |
'#title' => $component['name'], |
470 |
'#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before', |
|
346 | 471 |
'#weight' => $component['weight'], |
347 | 472 |
'#theme' => 'webform_display_date', |
348 | 473 |
'#theme_wrappers' => $format == 'html' ? array('webform_element') : array('webform_element_text'), |
349 | 474 |
'#format' => $format, |
475 |
'#exclude' => $component['extra']['exclude'], |
|
476 |
|
|
350 | 477 |
'#value' => $value, |
351 | 478 |
'#translatable' => array('title'), |
352 | 479 |
); |
... | ... | |
360 | 487 |
$output = ' '; |
361 | 488 |
if ($element['#value']['year'] && $element['#value']['month'] && $element['#value']['day']) { |
362 | 489 |
$timestamp = webform_strtotime($element['#value']['month'] . '/' . $element['#value']['day'] . '/' . $element['#value']['year']); |
363 |
$format = webform_date_format('medium');
|
|
490 |
$format = webform_date_format(NULL, $element['#exclude']);
|
|
364 | 491 |
$output = format_date($timestamp, 'custom', $format, 'UTC'); |
365 | 492 |
} |
366 | 493 |
|
... | ... | |
370 | 497 |
/** |
371 | 498 |
* Implements _webform_analysis_component(). |
372 | 499 |
*/ |
373 |
function _webform_analysis_date($component, $sids = array()) { |
|
500 |
function _webform_analysis_date($component, $sids = array(), $single = FALSE, $join = NULL) {
|
|
374 | 501 |
$query = db_select('webform_submitted_data', 'wsd', array('fetch' => PDO::FETCH_ASSOC)) |
375 | 502 |
->fields('wsd', array('no', 'data')) |
376 |
->condition('nid', $component['nid']) |
|
377 |
->condition('cid', $component['cid']) |
|
378 |
->orderBy('sid'); |
|
503 |
->condition('wsd.nid', $component['nid'])
|
|
504 |
->condition('wsd.cid', $component['cid'])
|
|
505 |
->orderBy('wsd.sid');
|
|
379 | 506 |
|
380 | 507 |
if (count($sids)) { |
381 |
$query->condition('sid', $sids, 'IN'); |
|
508 |
$query->condition('wsd.sid', $sids, 'IN'); |
|
509 |
} |
|
510 |
|
|
511 |
if ($join) { |
|
512 |
$query->innerJoin($join, 'ws2_', 'wsd.sid = ws2_.sid'); |
|
382 | 513 |
} |
383 | 514 |
|
384 | 515 |
$result = $query->execute(); |
... | ... | |
396 | 527 |
$nonblanks = count($dates); |
397 | 528 |
$rows[0] = array(t('Left Blank'), ($submissions - $nonblanks)); |
398 | 529 |
$rows[1] = array(t('User entered value'), $nonblanks); |
399 |
return $rows; |
|
530 |
|
|
531 |
return array( |
|
532 |
'table_rows' => $rows, |
|
533 |
); |
|
400 | 534 |
} |
401 | 535 |
|
402 | 536 |
/** |
... | ... | |
405 | 539 |
function _webform_table_date($component, $value) { |
406 | 540 |
if ($value[0]) { |
407 | 541 |
$timestamp = webform_strtotime($value[0]); |
408 |
$format = webform_date_format('short'); |
|
542 |
$format = webform_date_format('short', $component['extra']['exclude']);
|
|
409 | 543 |
return format_date($timestamp, 'custom', $format, 'UTC'); |
410 | 544 |
} |
411 | 545 |
else { |
... | ... | |
420 | 554 |
$header = array(); |
421 | 555 |
$header[0] = ''; |
422 | 556 |
$header[1] = ''; |
423 |
$header[2] = $component['name']; |
|
557 |
$header[2] = $export_options['header_keys'] ? $component['form_key'] : $component['name'];
|
|
424 | 558 |
return $header; |
425 | 559 |
} |
426 | 560 |
|
... | ... | |
430 | 564 |
function _webform_csv_data_date($component, $export_options, $value) { |
431 | 565 |
if ($value[0]) { |
432 | 566 |
$timestamp = webform_strtotime($value[0]); |
433 |
$format = webform_date_format('short'); |
|
567 |
if (!empty($export_options['iso8601_date'])) { |
|
568 |
$format = 'Y-m-d'; // ISO 8601 date: 2004-02-12 |
|
569 |
} |
|
570 |
else { |
|
571 |
$format = webform_date_format('short'); |
|
572 |
} |
|
434 | 573 |
return format_date($timestamp, 'custom', $format, 'UTC'); |
435 | 574 |
} |
436 | 575 |
else { |
Formats disponibles : Unified diff
Update webform to 4.10