Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Datetime;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Component\Datetime\DateTimePlus;
|
Chris@0
|
6 use Drupal\Core\StringTranslation\StringTranslationTrait;
|
Chris@0
|
7
|
Chris@0
|
8 /**
|
Chris@0
|
9 * Extends DateTimePlus().
|
Chris@0
|
10 *
|
Chris@0
|
11 * This class extends the basic component and adds in Drupal-specific
|
Chris@0
|
12 * handling, like translation of the format() method.
|
Chris@0
|
13 *
|
Chris@0
|
14 * Static methods in base class can also be used to create DrupalDateTime objects.
|
Chris@0
|
15 * For example:
|
Chris@0
|
16 *
|
Chris@0
|
17 * DrupalDateTime::createFromArray( array('year' => 2010, 'month' => 9, 'day' => 28) )
|
Chris@0
|
18 *
|
Chris@18
|
19 * @see \Drupal\Component\Datetime\DateTimePlus
|
Chris@0
|
20 */
|
Chris@0
|
21 class DrupalDateTime extends DateTimePlus {
|
Chris@0
|
22
|
Chris@0
|
23 use StringTranslationTrait;
|
Chris@0
|
24
|
Chris@0
|
25 /**
|
Chris@0
|
26 * Format string translation cache.
|
Chris@0
|
27 */
|
Chris@0
|
28 protected $formatTranslationCache;
|
Chris@0
|
29
|
Chris@0
|
30 /**
|
Chris@0
|
31 * Constructs a date object.
|
Chris@0
|
32 *
|
Chris@0
|
33 * @param string $time
|
Chris@0
|
34 * A date/input_time_adjusted string. Defaults to 'now'.
|
Chris@0
|
35 * @param mixed $timezone
|
Chris@0
|
36 * PHP DateTimeZone object, string or NULL allowed.
|
Chris@0
|
37 * Defaults to NULL. Note that the $timezone parameter and the current
|
Chris@0
|
38 * timezone are ignored when the $time parameter either is a UNIX timestamp
|
Chris@0
|
39 * (e.g. @946684800) or specifies a timezone
|
Chris@0
|
40 * (e.g. 2010-01-28T15:00:00+02:00).
|
Chris@14
|
41 * @see http://php.net/manual/datetime.construct.php
|
Chris@0
|
42 * @param array $settings
|
Chris@0
|
43 * - validate_format: (optional) Boolean choice to validate the
|
Chris@0
|
44 * created date using the input format. The format used in
|
Chris@0
|
45 * createFromFormat() allows slightly different values than format().
|
Chris@0
|
46 * Using an input format that works in both functions makes it
|
Chris@0
|
47 * possible to a validation step to confirm that the date created
|
Chris@0
|
48 * from a format string exactly matches the input. This option
|
Chris@0
|
49 * indicates the format can be used for validation. Defaults to TRUE.
|
Chris@0
|
50 * - langcode: (optional) Used to control the result of the format() method.
|
Chris@0
|
51 * Defaults to NULL.
|
Chris@0
|
52 * - debug: (optional) Boolean choice to leave debug values in the
|
Chris@0
|
53 * date object for debugging purposes. Defaults to FALSE.
|
Chris@0
|
54 */
|
Chris@0
|
55 public function __construct($time = 'now', $timezone = NULL, $settings = []) {
|
Chris@0
|
56 if (!isset($settings['langcode'])) {
|
Chris@0
|
57 $settings['langcode'] = \Drupal::languageManager()->getCurrentLanguage()->getId();
|
Chris@0
|
58 }
|
Chris@0
|
59
|
Chris@0
|
60 // Instantiate the parent class.
|
Chris@0
|
61 parent::__construct($time, $timezone, $settings);
|
Chris@0
|
62
|
Chris@0
|
63 }
|
Chris@0
|
64
|
Chris@0
|
65 /**
|
Chris@0
|
66 * Overrides prepareTimezone().
|
Chris@0
|
67 *
|
Chris@0
|
68 * Override basic component timezone handling to use Drupal's
|
Chris@0
|
69 * knowledge of the preferred user timezone.
|
Chris@0
|
70 */
|
Chris@0
|
71 protected function prepareTimezone($timezone) {
|
Chris@0
|
72 if (empty($timezone)) {
|
Chris@0
|
73 // Fallback to user or system default timezone.
|
Chris@0
|
74 $timezone = drupal_get_user_timezone();
|
Chris@0
|
75 }
|
Chris@0
|
76 return parent::prepareTimezone($timezone);
|
Chris@0
|
77 }
|
Chris@0
|
78
|
Chris@0
|
79 /**
|
Chris@0
|
80 * Overrides format().
|
Chris@0
|
81 *
|
Chris@0
|
82 * @param string $format
|
Chris@0
|
83 * A format string using either PHP's date().
|
Chris@0
|
84 * @param array $settings
|
Chris@0
|
85 * - timezone: (optional) String timezone name. Defaults to the timezone
|
Chris@0
|
86 * of the date object.
|
Chris@0
|
87 * - langcode: (optional) String two letter language code used to control
|
Chris@0
|
88 * the result of the format() method. Defaults to NULL.
|
Chris@0
|
89 *
|
Chris@0
|
90 * @return string
|
Chris@0
|
91 * The formatted value of the date. Since the format may contain user input,
|
Chris@0
|
92 * this value should be escaped when output.
|
Chris@0
|
93 */
|
Chris@0
|
94 public function format($format, $settings = []) {
|
Chris@0
|
95 $langcode = !empty($settings['langcode']) ? $settings['langcode'] : $this->langcode;
|
Chris@0
|
96 $value = '';
|
Chris@0
|
97 // Format the date and catch errors.
|
Chris@0
|
98 try {
|
Chris@0
|
99 // Encode markers that should be translated. 'A' becomes
|
Chris@0
|
100 // '\xEF\AA\xFF'. xEF and xFF are invalid UTF-8 sequences,
|
Chris@0
|
101 // and we assume they are not in the input string.
|
Chris@0
|
102 // Paired backslashes are isolated to prevent errors in
|
Chris@0
|
103 // read-ahead evaluation. The read-ahead expression ensures that
|
Chris@0
|
104 // A matches, but not \A.
|
Chris@0
|
105 $format = preg_replace(['/\\\\\\\\/', '/(?<!\\\\)([AaeDlMTF])/'], ["\xEF\\\\\\\\\xFF", "\xEF\\\\\$1\$1\xFF"], $format);
|
Chris@0
|
106
|
Chris@0
|
107 // Call date_format().
|
Chris@0
|
108 $format = parent::format($format, $settings);
|
Chris@0
|
109
|
Chris@0
|
110 // Translates a formatted date string.
|
Chris@0
|
111 $translation_callback = function ($matches) use ($langcode) {
|
Chris@0
|
112 $code = $matches[1];
|
Chris@0
|
113 $string = $matches[2];
|
Chris@0
|
114 if (!isset($this->formatTranslationCache[$langcode][$code][$string])) {
|
Chris@0
|
115 $options = ['langcode' => $langcode];
|
Chris@0
|
116 if ($code == 'F') {
|
Chris@0
|
117 $options['context'] = 'Long month name';
|
Chris@0
|
118 }
|
Chris@0
|
119
|
Chris@0
|
120 if ($code == '') {
|
Chris@0
|
121 $this->formatTranslationCache[$langcode][$code][$string] = $string;
|
Chris@0
|
122 }
|
Chris@0
|
123 else {
|
Chris@0
|
124 $this->formatTranslationCache[$langcode][$code][$string] = $this->t($string, [], $options);
|
Chris@0
|
125 }
|
Chris@0
|
126 }
|
Chris@0
|
127 return $this->formatTranslationCache[$langcode][$code][$string];
|
Chris@0
|
128 };
|
Chris@0
|
129
|
Chris@0
|
130 // Translate the marked sequences.
|
Chris@0
|
131 $value = preg_replace_callback('/\xEF([AaeDlMTF]?)(.*?)\xFF/', $translation_callback, $format);
|
Chris@0
|
132 }
|
Chris@0
|
133 catch (\Exception $e) {
|
Chris@0
|
134 $this->errors[] = $e->getMessage();
|
Chris@0
|
135 }
|
Chris@0
|
136 return $value;
|
Chris@0
|
137 }
|
Chris@0
|
138
|
Chris@0
|
139 }
|