Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
74.16% |
221 / 298 |
|
50.00% |
7 / 14 |
CRAP | |
0.00% |
0 / 1 |
NumberRange | |
74.16% |
221 / 298 |
|
50.00% |
7 / 14 |
318.74 | |
0.00% |
0 / 1 |
query | |
93.33% |
28 / 30 |
|
0.00% |
0 / 1 |
8.02 | |||
render | |
93.33% |
14 / 15 |
|
0.00% |
0 / 1 |
4.00 | |||
formatTimeRange | |
80.00% |
20 / 25 |
|
0.00% |
0 / 1 |
15.57 | |||
formatTimeRangeInUnit | |
0.00% |
0 / 33 |
|
0.00% |
0 / 1 |
342 | |||
formatSecondsInUnit | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
72 | |||
makePluralWith | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
makePlural | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
8 | |||
makeSingle | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
8 | |||
formatSeconds | |
100.00% |
37 / 37 |
|
100.00% |
1 / 1 |
18 | |||
getRangeLabel | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
parseTimeRange | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
90 | |||
convertToSeconds | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
56 | |||
defineOptions | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
buildOptionsForm | |
100.00% |
57 / 57 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace Drupal\visitors\Plugin\views\field; |
4 | |
5 | use Drupal\Core\Form\FormStateInterface; |
6 | use Drupal\views\Attribute\ViewsField; |
7 | use Drupal\views\Plugin\views\field\FieldPluginBase; |
8 | use Drupal\views\ResultRow; |
9 | |
10 | /** |
11 | * Field handler to display numeric values grouped into configured ranges. |
12 | */ |
13 | #[ViewsField("visitors_number_range")] |
14 | class NumberRange extends FieldPluginBase { |
15 | |
16 | /** |
17 | * {@inheritdoc} |
18 | */ |
19 | public function query() { |
20 | $this->ensureMyTable(); |
21 | $suffix = '__range'; |
22 | $field = "$this->tableAlias.$this->realField"; |
23 | |
24 | $ranges_text = $this->options['ranges']; |
25 | $ranges = preg_split('/\r\n|\r|\n/', $ranges_text); |
26 | $ranges = array_map('trim', $ranges); |
27 | $ranges = array_filter($ranges, function ($range) { |
28 | return trim($range) !== ''; |
29 | }); |
30 | |
31 | if (empty($ranges)) { |
32 | return parent::query(); |
33 | } |
34 | |
35 | $case_sql = []; |
36 | foreach ($ranges as $i => $range) { |
37 | |
38 | $value = $i; |
39 | $parsed_range = $this->parseTimeRange($range); |
40 | |
41 | // "X-Y" with or without time units. |
42 | if (preg_match('/^(\d+(?:\.\d+)?)\-(\d+(?:\.\d+)?)$/', $range, $m)) { |
43 | $start_seconds = $this->convertToSeconds($m[1], $parsed_range['start_unit']); |
44 | $end_seconds = $this->convertToSeconds($m[2], $parsed_range['end_unit']); |
45 | $case_sql[] = "WHEN $field BETWEEN $start_seconds AND $end_seconds THEN $value"; |
46 | } |
47 | // "-X" format (0 to X). |
48 | elseif (preg_match('/^\-(\d+(?:\.\d+)?)([mdwy]?)$/', $range, $m)) { |
49 | $end_seconds = $this->convertToSeconds($m[1], $m[2] ?: NULL); |
50 | $case_sql[] = "WHEN $field BETWEEN 0 AND $end_seconds THEN $value"; |
51 | } |
52 | // "X+" with or without time units. |
53 | elseif (preg_match('/^(\d+(?:\.\d+)?)\+$/', $range, $m)) { |
54 | $seconds = $this->convertToSeconds($m[1], $parsed_range['start_unit']); |
55 | $case_sql[] = "WHEN $field >= $seconds THEN $value"; |
56 | } |
57 | // Exact number with or without time units. |
58 | elseif (preg_match('/^(\d+(?:\.\d+)?)$/', $range, $m)) { |
59 | $seconds = $this->convertToSeconds($m[1], $parsed_range['start_unit']); |
60 | $case_sql[] = "WHEN $field = $seconds THEN $value"; |
61 | } |
62 | |
63 | } |
64 | $max_value = count($ranges) + 1; |
65 | $case_expression = "CASE " . implode(' ', $case_sql) . " ELSE $max_value END"; |
66 | |
67 | // Tell Views to use this CASE expression as the field value. |
68 | $this->field_alias = $this->query->addField(NULL, $case_expression, $this->tableAlias . '_' . $this->realField . $suffix); |
69 | } |
70 | |
71 | /** |
72 | * {@inheritdoc} |
73 | */ |
74 | public function render(ResultRow $values) { |
75 | $label = $this->getValue($values); |
76 | |
77 | // Get display name. |
78 | $display_name = $this->options; |
79 | |
80 | // Always replace the index value with the range label. |
81 | $label = $this->getRangeLabel($label); |
82 | |
83 | // If time format is enabled, convert the range to time format. |
84 | if ($this->options['time_format']) { |
85 | $time_unit = $this->options['time_unit'] ?? 'auto'; |
86 | if ($time_unit === 'auto') { |
87 | $label = $this->formatTimeRange($label); |
88 | } |
89 | else { |
90 | $label = $this->formatTimeRangeInUnit($label, $time_unit); |
91 | } |
92 | } |
93 | elseif ($this->options['pluralize']) { |
94 | // Example: pluralize with the word "item". |
95 | return $this->formatPlural( |
96 | $label, |
97 | $this->options['singular_label'], |
98 | $this->options['plural_label'], |
99 | ); |
100 | } |
101 | |
102 | return $label; |
103 | } |
104 | |
105 | /** |
106 | * Formats a range value as time when the range represents seconds. |
107 | * |
108 | * @param string $range |
109 | * The range value (e.g., "60", "3600", "86400"). |
110 | * |
111 | * @return string |
112 | * The formatted time range (e.g., "1m", "1h", "1d"). |
113 | */ |
114 | protected function formatTimeRange(string $range): string { |
115 | // Handle ranges like "60-120" or "3600+". |
116 | if (strpos($range, '-') !== FALSE) { |
117 | $parts = explode('-', $range); |
118 | $unit = NULL; |
119 | $start = $this->formatSeconds((int) $parts[0], $unit); |
120 | $end = $this->formatSeconds((int) $parts[1], $unit); |
121 | // If start and end are less than 1 unit apart, return the integer with |
122 | // the unit. Example: "1 day". |
123 | if (is_numeric($start) && is_numeric($end) |
124 | && abs($end - $start) < 1) { |
125 | $integer = is_int($end) ? $end : (is_int($start) ? $start : $end); |
126 | // Only return "0" without units if both start and end are exactly 0. |
127 | if ($integer == 0 && $start == 0 && $end == 0) { |
128 | return '0'; |
129 | } |
130 | return $this->makePluralWith($integer, $unit); |
131 | } |
132 | if ($start == 0 && $end == 1) { |
133 | return $this->makeSingle("$end", $unit); |
134 | } |
135 | elseif ($start == 0) { |
136 | return $this->makeSingle("$start-$end", $unit); |
137 | } |
138 | |
139 | return $this->makePlural(floor($start) . "-$end", $unit); |
140 | } |
141 | |
142 | if (strpos($range, '+') !== FALSE) { |
143 | $seconds = (int) rtrim($range, '+'); |
144 | $unit = NULL; |
145 | $time = $this->formatSeconds($seconds, $unit); |
146 | return $this->makePluralWith(floor($time), $unit ?? 'second', '+'); |
147 | } |
148 | |
149 | // Single value. |
150 | $seconds = (int) $range; |
151 | $unit = NULL; |
152 | $time = $this->formatSeconds($seconds, $unit); |
153 | return $this->makePluralWith($time, $unit ?? 'second'); |
154 | } |
155 | |
156 | /** |
157 | * Formats a range value as time using a specific unit. |
158 | * |
159 | * @param string $range |
160 | * The range value (e.g., "60", "3600", "86400"). |
161 | * @param string $unit |
162 | * The time unit to use (second, minute, hour, day, week, year). |
163 | * |
164 | * @return string |
165 | * The formatted time range in the specified unit. |
166 | */ |
167 | protected function formatTimeRangeInUnit(string $range, string $unit): string { |
168 | // Handle "-X" format (0 to X). |
169 | if (preg_match('/^\-(\d+)$/', $range, $m)) { |
170 | $end = $this->formatSecondsInUnit((int) $m[1], $unit); |
171 | if ($end == 0) { |
172 | return '0'; |
173 | } |
174 | return $this->makePluralWith($end, $unit); |
175 | } |
176 | |
177 | // Handle ranges like "60-120" or "3600+". |
178 | if (strpos($range, '-') !== FALSE) { |
179 | $parts = explode('-', $range); |
180 | $start = $this->formatSecondsInUnit((int) $parts[0], $unit); |
181 | $end = $this->formatSecondsInUnit((int) $parts[1], $unit); |
182 | |
183 | // If both start and end are 0, return just "0". |
184 | if ($start == 0 && $end == 0) { |
185 | return '0'; |
186 | } |
187 | |
188 | // If start and end are less than 1 unit apart, return the integer with |
189 | // the unit. Example: "1 day". |
190 | if (is_numeric($start) && is_numeric($end) |
191 | && abs($end - $start) < 1) { |
192 | $integer = floor($start); |
193 | // Only return "0" without units if both start and end are exactly 0. |
194 | if ($integer == 0 && $start == 0 && $end == 0) { |
195 | return '0'; |
196 | } |
197 | return $this->makePluralWith($integer, $unit); |
198 | } |
199 | if ($start == 0 && $end == 1) { |
200 | return $this->makeSingle("$end", $unit); |
201 | } |
202 | elseif ($start == 0) { |
203 | return $this->makePlural($end, $unit); |
204 | } |
205 | |
206 | return $this->makePlural(floor($start) . "-" . floor($end), $unit); |
207 | } |
208 | |
209 | if (strpos($range, '+') !== FALSE) { |
210 | $seconds = (int) rtrim($range, '+'); |
211 | $time = $this->formatSecondsInUnit($seconds, $unit); |
212 | if ($time == 0) { |
213 | return '0+'; |
214 | } |
215 | return $this->makePluralWith(floor($time), $unit, '+'); |
216 | } |
217 | |
218 | // Single value. |
219 | $seconds = (int) $range; |
220 | $time = $this->formatSecondsInUnit($seconds, $unit); |
221 | if ($time == 0) { |
222 | return '0'; |
223 | } |
224 | return $this->makePluralWith($time, $unit); |
225 | } |
226 | |
227 | /** |
228 | * Formats seconds into a specific time unit. |
229 | * |
230 | * @param int $seconds |
231 | * The number of seconds. |
232 | * @param string $unit |
233 | * The unit of time to format the seconds into. |
234 | * |
235 | * @return float |
236 | * The formatted time value as a float. |
237 | */ |
238 | protected function formatSecondsInUnit(int $seconds, string $unit): float { |
239 | switch ($unit) { |
240 | case 'second': |
241 | return (float) $seconds; |
242 | |
243 | case 'minute': |
244 | return $seconds / 60; |
245 | |
246 | case 'hour': |
247 | return $seconds / 3600; |
248 | |
249 | case 'day': |
250 | return $seconds / 86400; |
251 | |
252 | case 'week': |
253 | return $seconds / 604800; |
254 | |
255 | case 'year': |
256 | return $seconds / 31536000; |
257 | |
258 | default: |
259 | return (float) $seconds; |
260 | } |
261 | } |
262 | |
263 | /** |
264 | * Creates plural or singular form based on the time value. |
265 | * |
266 | * @param mixed $time |
267 | * The time value to format. |
268 | * @param string $unit |
269 | * The time unit (second, minute, hour, etc.). |
270 | * @param string $suffix |
271 | * Optional suffix to append to the time value. |
272 | * |
273 | * @return string |
274 | * The formatted time string with proper pluralization. |
275 | */ |
276 | protected function makePluralWith($time, string $unit, $suffix = ''): string { |
277 | if ($time == 1) { |
278 | return $this->makeSingle($time, $unit, $suffix); |
279 | } |
280 | return $this->makePlural($time, $unit, $suffix); |
281 | } |
282 | |
283 | /** |
284 | * Creates plural form of time units. |
285 | * |
286 | * @param mixed $time |
287 | * The time value to format. |
288 | * @param string $unit |
289 | * The time unit (second, minute, hour, etc.). |
290 | * @param string $suffix |
291 | * Optional suffix to append to the time value. |
292 | * |
293 | * @return string |
294 | * The formatted time string in plural form. |
295 | */ |
296 | protected function makePlural($time, string $unit, $suffix = ''): string { |
297 | $plural = $this->t('Unknown unit'); |
298 | switch ($unit) { |
299 | case 'second': |
300 | $plural = $this->t('@time seconds', ['@time' => $time . $suffix]); |
301 | break; |
302 | |
303 | case 'minute': |
304 | $plural = $this->t('@time minutes', ['@time' => $time . $suffix]); |
305 | break; |
306 | |
307 | case 'hour': |
308 | $plural = $this->t('@time hours', ['@time' => $time . $suffix]); |
309 | break; |
310 | |
311 | case 'day': |
312 | $plural = $this->t('@time days', ['@time' => $time . $suffix]); |
313 | break; |
314 | |
315 | case 'week': |
316 | $plural = $this->t('@time weeks', ['@time' => $time . $suffix]); |
317 | break; |
318 | |
319 | case 'month': |
320 | $plural = $this->t('@time months', ['@time' => $time . $suffix]); |
321 | break; |
322 | |
323 | case 'year': |
324 | $plural = $this->t('@time years', ['@time' => $time . $suffix]); |
325 | break; |
326 | } |
327 | |
328 | return $plural; |
329 | } |
330 | |
331 | /** |
332 | * Creates singular form of time units. |
333 | * |
334 | * @param mixed $time |
335 | * The time value to format. |
336 | * @param string $unit |
337 | * The time unit (second, minute, hour, etc.). |
338 | * @param string $suffix |
339 | * Optional suffix to append to the time value. |
340 | * |
341 | * @return string |
342 | * The formatted time string in singular form. |
343 | */ |
344 | protected function makeSingle($time, string $unit, $suffix = ''): string { |
345 | $single = $this->t('Unknown unit'); |
346 | switch ($unit) { |
347 | case 'second': |
348 | $single = $this->t('@time second', ['@time' => $time . $suffix]); |
349 | break; |
350 | |
351 | case 'minute': |
352 | $single = $this->t('@time minute', ['@time' => $time . $suffix]); |
353 | break; |
354 | |
355 | case 'hour': |
356 | $single = $this->t('@time hour', ['@time' => $time . $suffix]); |
357 | break; |
358 | |
359 | case 'day': |
360 | $single = $this->t('@time day', ['@time' => $time . $suffix]); |
361 | break; |
362 | |
363 | case 'week': |
364 | $single = $this->t('@time week', ['@time' => $time . $suffix]); |
365 | break; |
366 | |
367 | case 'month': |
368 | $single = $this->t('@time month', ['@time' => $time . $suffix]); |
369 | break; |
370 | |
371 | case 'year': |
372 | $single = $this->t('@time year', ['@time' => $time . $suffix]); |
373 | break; |
374 | } |
375 | return $single; |
376 | } |
377 | |
378 | /** |
379 | * Formats seconds into human-readable time units. |
380 | * |
381 | * @param int $seconds |
382 | * The number of seconds. |
383 | * @param string|null $unit |
384 | * The unit of time used to format the seconds. |
385 | * |
386 | * @return float |
387 | * The formatted time value as a float. |
388 | */ |
389 | protected function formatSeconds(int $seconds, &$unit = NULL): float { |
390 | if ($seconds === 0) { |
391 | return (float) $seconds; |
392 | } |
393 | |
394 | // If unit is already specified and not empty, format seconds as that unit. |
395 | if ($unit !== NULL && $unit !== '') { |
396 | switch ($unit) { |
397 | case 'second': |
398 | return (float) $seconds; |
399 | |
400 | case 'minute': |
401 | return $seconds / 60; |
402 | |
403 | case 'hour': |
404 | return $seconds / 3600; |
405 | |
406 | case 'day': |
407 | return $seconds / 86400; |
408 | |
409 | case 'week': |
410 | return $seconds / 604800; |
411 | |
412 | case 'month': |
413 | return $seconds / 2592000; |
414 | |
415 | case 'year': |
416 | return $seconds / 31536000; |
417 | |
418 | default: |
419 | // If unit is not recognized, fall through to automatic detection. |
420 | break; |
421 | } |
422 | } |
423 | |
424 | // Automatic unit detection (existing logic) |
425 | if ($seconds < 60) { |
426 | $unit = 'second'; |
427 | return (float) $seconds; |
428 | } |
429 | |
430 | if ($seconds < 3600) { |
431 | $unit = 'minute'; |
432 | return $seconds / 60; |
433 | } |
434 | |
435 | if ($seconds < 86400) { |
436 | $unit = 'hour'; |
437 | return $seconds / 3600; |
438 | } |
439 | |
440 | if ($seconds < 604800) { |
441 | $unit = 'day'; |
442 | return $seconds / 86400; |
443 | } |
444 | |
445 | if ($seconds < 2592000) { |
446 | $unit = 'week'; |
447 | return $seconds / 604800; |
448 | } |
449 | |
450 | if ($seconds < 31536000) { |
451 | $unit = 'month'; |
452 | return $seconds / 2592000; |
453 | } |
454 | |
455 | $unit = 'year'; |
456 | return $seconds / 31536000; |
457 | } |
458 | |
459 | /** |
460 | * Gets the range label for a given index value. |
461 | * |
462 | * @param string|int $index |
463 | * The index value (e.g., 1, 2, 3, 4, etc.). |
464 | * |
465 | * @return string |
466 | * The range label for the index. |
467 | */ |
468 | protected function getRangeLabel($index): string { |
469 | $ranges_text = $this->options['ranges']; |
470 | $ranges = preg_split('/\r\n|\r|\n/', $ranges_text); |
471 | |
472 | $i = 0; |
473 | foreach ($ranges as $range) { |
474 | $range = trim($range); |
475 | if ($range === '') { |
476 | continue; |
477 | } |
478 | |
479 | if ($i === (int) $index) { |
480 | return $range; |
481 | } |
482 | |
483 | $i += 1; |
484 | } |
485 | |
486 | // If no match found, return the original index value. |
487 | return (string) $index; |
488 | } |
489 | |
490 | /** |
491 | * Parses a time range string to extract time units. |
492 | * |
493 | * @param string $range |
494 | * The range string (e.g., "1m-2m", "5d+", "1w", "-60"). |
495 | * |
496 | * @return array |
497 | * An array with 'start_unit' and 'end_unit' keys containing the time units. |
498 | */ |
499 | protected function parseTimeRange(string $range): array { |
500 | $result = ['start_unit' => NULL, 'end_unit' => NULL]; |
501 | |
502 | // Handle range format "X-Y" with units. |
503 | if (preg_match('/^(\d+(?:\.\d+)?)([mdwy]?)\-(\d+(?:\.\d+)?)([mdwy]?)$/', $range, $m)) { |
504 | $result['start_unit'] = $m[2] ?: NULL; |
505 | $result['end_unit'] = $m[4] ?: NULL; |
506 | } |
507 | // Handle "-X" format (0 to X) with units. |
508 | elseif (preg_match('/^\-(\d+(?:\.\d+)?)([mdwy]?)$/', $range, $m)) { |
509 | $result['start_unit'] = NULL; |
510 | $result['end_unit'] = $m[2] ?: NULL; |
511 | } |
512 | // Handle single value or "X+" format with units. |
513 | elseif (preg_match('/^(\d+(?:\.\d+)?)([mdwy]?)(\+?)$/', $range, $m)) { |
514 | $result['start_unit'] = $m[2] ?: NULL; |
515 | $result['end_unit'] = $m[2] ?: NULL; |
516 | } |
517 | |
518 | return $result; |
519 | } |
520 | |
521 | /** |
522 | * Converts a number with time unit to seconds. |
523 | * |
524 | * @param string $value |
525 | * The numeric value. |
526 | * @param string|null $unit |
527 | * The time unit (m, d, w, y) or NULL for no unit. |
528 | * |
529 | * @return int |
530 | * The value converted to seconds. |
531 | */ |
532 | protected function convertToSeconds(string $value, ?string $unit): int { |
533 | $num_value = (float) $value; |
534 | |
535 | if ($unit === NULL) { |
536 | return (int) $num_value; |
537 | } |
538 | |
539 | switch ($unit) { |
540 | // Minutes. |
541 | case 'm': |
542 | return (int) ($num_value * 60); |
543 | |
544 | // Days. |
545 | case 'd': |
546 | return (int) ($num_value * 86400); |
547 | |
548 | // Weeks. |
549 | case 'w': |
550 | return (int) ($num_value * 604800); |
551 | |
552 | // Years. |
553 | case 'y': |
554 | return (int) ($num_value * 31536000); |
555 | |
556 | default: |
557 | return (int) $num_value; |
558 | } |
559 | } |
560 | |
561 | /** |
562 | * {@inheritdoc} |
563 | */ |
564 | protected function defineOptions() { |
565 | $options = parent::defineOptions(); |
566 | $options['pluralize'] = ['default' => FALSE]; |
567 | $options['singular_label'] = ['default' => '1 item']; |
568 | $options['plural_label'] = ['default' => '@count items']; |
569 | $options['ranges'] = ['default' => "0\n1\n2\n3\n4\n5\n6-7\n8-10\n11-14\n15-20\n21+"]; |
570 | $options['time_format'] = ['default' => FALSE]; |
571 | $options['time_unit'] = ['default' => 'auto']; |
572 | return $options; |
573 | } |
574 | |
575 | /** |
576 | * {@inheritdoc} |
577 | */ |
578 | public function buildOptionsForm(&$form, FormStateInterface $form_state) { |
579 | parent::buildOptionsForm($form, $form_state); |
580 | |
581 | $form['pluralize'] = [ |
582 | '#type' => 'checkbox', |
583 | '#title' => $this->t('Enable pluralization'), |
584 | '#default_value' => $this->options['pluralize'], |
585 | ]; |
586 | |
587 | $form['singular_label'] = [ |
588 | '#type' => 'textfield', |
589 | '#title' => $this->t('Singular label'), |
590 | '#default_value' => $this->options['singular_label'], |
591 | '#states' => [ |
592 | 'visible' => [ |
593 | ':input[name="options[pluralize]"]' => ['checked' => TRUE], |
594 | ], |
595 | ], |
596 | ]; |
597 | |
598 | $form['plural_label'] = [ |
599 | '#type' => 'textfield', |
600 | '#title' => $this->t('Plural label'), |
601 | '#default_value' => $this->options['plural_label'], |
602 | '#states' => [ |
603 | 'visible' => [ |
604 | ':input[name="options[pluralize]"]' => ['checked' => TRUE], |
605 | ], |
606 | ], |
607 | ]; |
608 | |
609 | $form['ranges'] = [ |
610 | '#type' => 'textarea', |
611 | '#title' => $this->t('Number ranges'), |
612 | '#description' => $this->t("Enter one range per line. Examples: <code>0</code>, <code>6-7</code>, <code>21+</code>."), |
613 | '#default_value' => $this->options['ranges'], |
614 | ]; |
615 | |
616 | $form['time_format'] = [ |
617 | '#type' => 'checkbox', |
618 | '#title' => $this->t('Format ranges as time (e.g., 60s, 1h, 1d)'), |
619 | '#default_value' => $this->options['time_format'], |
620 | ]; |
621 | |
622 | $form['time_unit'] = [ |
623 | '#type' => 'select', |
624 | '#title' => $this->t('Time unit'), |
625 | '#description' => $this->t('Choose the time unit for displaying all ranges. Auto will use the most appropriate unit for each range.'), |
626 | '#default_value' => $this->options['time_unit'] ?? 'auto', |
627 | '#options' => [ |
628 | 'auto' => $this->t('Auto'), |
629 | 'second' => $this->t('Seconds'), |
630 | 'minute' => $this->t('Minutes'), |
631 | 'hour' => $this->t('Hours'), |
632 | 'day' => $this->t('Days'), |
633 | 'week' => $this->t('Weeks'), |
634 | 'year' => $this->t('Years'), |
635 | ], |
636 | '#states' => [ |
637 | 'visible' => [ |
638 | ':input[name="options[time_format]"]' => ['checked' => TRUE], |
639 | ], |
640 | ], |
641 | ]; |
642 | } |
643 | |
644 | } |