PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Helpers / global / date.php

date.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 11.1.0, at back/Helpers/global/date.php

412 lines 13.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined('ABSPATH') || die('Restricted Access');
3
4 function acym_replaceDateTags(string $value): string
5 {
6 $replace = ['{year}', '{month}', '{weekday}', '{day}'];
7 $replaceBy = [gmdate('Y'), gmdate('m'), gmdate('N'), gmdate('d')];
8 $value = str_replace($replace, $replaceBy, $value);
9
10 $results = [];
11 if (preg_match_all('#{(year|month|weekday|day)\|(add|remove):([^}]*)}#Uis', $value, $results)) {
12 foreach ($results[0] as $i => $oneMatch) {
13 $format = str_replace(['year', 'month', 'weekday', 'day'], ['Y', 'm', 'N', 'd'], $results[1][$i]);
14 $delay = str_replace(['add', 'remove'], ['+', '-'], $results[2][$i]).intval($results[3][$i]).' '.str_replace('weekday', 'day', $results[1][$i]);
15 $value = str_replace($oneMatch, gmdate($format, strtotime($delay)), $value);
16 }
17 }
18
19 return $value;
20 }
21
22 function acym_dateField(string $name, $value = '', string $class = '', string $attributes = '', string $relativeDefault = '-'): string
23 {
24 // Open container
25 $result = '<div class="grid-x margin-y date_rs_selection_popup">';
26
27 // Choice of relative / specific date
28 $result .= '<div class="cell grid-x">';
29 $result .= acym_switchFilter(
30 [
31 'relative' => acym_translation('ACYM_RELATIVE_DATE'),
32 'specific' => acym_translation('ACYM_SPECIFIC_DATE'),
33 ],
34 'relative',
35 'switch_'.$name,
36 'date_rs_selection'
37 );
38 $result .= '</div>';
39
40 // Relative date options
41 $result .= '<div class="cell date_rs_selection_choice date_rs_selection_relative grid-x grid-margin-x align-center">
42 <div class="cell medium-4">
43 <input type="number" class="relativenumber" value="0">
44 </div>
45 <div class="cell medium-4">';
46 $result .= acym_select(
47 [
48 '60' => acym_translation('ACYM_MINUTES'),
49 '3600' => acym_translation('ACYM_HOUR'),
50 '86400' => acym_translation('ACYM_DAY'),
51 ],
52 'relative_'.$name,
53 null,
54 ['class' => 'acym__select relativetype']
55 );
56
57 $result .= '</div>
58 <div class="cell medium-4">';
59
60 $result .= acym_select(
61 [
62 '-' => acym_translation('ACYM_IN_PAST'),
63 '+' => acym_translation('ACYM_IN_FUTURE'),
64 ],
65 'relativewhen_'.$name,
66 $relativeDefault,
67 ['class' => 'acym__select relativewhen']
68 );
69 $result .= '</div>
70 </div>';
71
72 // Specific date option
73 $result .= '<div class="cell date_rs_selection_choice date_rs_selection_specific grid-x align-center acym_vcenter" style="display: none;">
74 <span class="cell shrink margin-right-1">'.acym_translation('ACYM_CHOOSE_DATE').'</span>
75 <div class="cell shrink">
76 <input type="datetime-local" name="specific_'.esc_attr($name).'" class="acy_date_picker">
77 </div>
78 </div>
79 <div class="cell grid-x grid-margin-x">
80 <div class="cell auto"></div>
81 <button type="button" class="cell medium-4 button button-secondary acym__button__clear__time" data-close>'.acym_translation('ACYM_CLEAR').'</button>
82 <button type="button" class="cell medium-4 button acym__button__set__time" data-close>'.acym_translation('ACYM_APPLY').'</button>
83 <div class="cell auto"></div>
84 </div>';
85
86 // Close container
87 $result .= '</div>';
88
89 // Input in which the value is
90 $id = 'acym_'.preg_replace('#[^a-z0-9_]#i', '', $name);
91 if (is_numeric($value)) {
92 $months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
93
94 $replaceValues = [];
95 foreach ($months as $oneMonth) {
96 $replaceValues[] = substr(acym_translation('ACYM_'.strtoupper($oneMonth)), 0, 3);
97 }
98
99 $shownValue = str_replace($months, $replaceValues, acym_date($value, 'd F Y H:i'));
100 } else {
101 $shownValue = $value;
102 }
103 $hiddenField = '<input data-rs="'.esc_attr($id).'" type="hidden" name="'.esc_attr($name).'" value="'.esc_attr($value).'">';
104 ob_start();
105 acym_modal(
106 '<input data-open="'.esc_attr($id).'" class="rs_date_field '.esc_attr($class).'" '.$attributes.' type="text" value="'.esc_attr($shownValue).'" readonly>',
107 $result,
108 $id,
109 [],
110 [],
111 false,
112 false
113 );
114 $result = $hiddenField.ob_get_clean();
115
116 return $result;
117 }
118
119 /**
120 * Function to display the time based on the database value as int
121 */
122 function acym_getDate($time = 0, string $format = '%d %B %Y %H:%M')
123 {
124 if (empty($time)) return '';
125
126 if (is_numeric($format)) {
127 $format = acym_translation('ACYM_DATE_FORMAT_LC'.$format);
128 }
129
130 $format = str_replace(
131 ['%A', '%d', '%B', '%m', '%Y', '%y', '%H', '%M', '%S', '%a', '%I', '%p', '%w'],
132 ['l', 'd', 'F', 'm', 'Y', 'y', 'H', 'i', 's', 'D', 'h', 'a', 'w'],
133 $format
134 );
135
136 //Not sure why but sometimes it fails... so lets try to catch the error...
137 try {
138 return acym_date($time, $format, false);
139 } catch (Exception $e) {
140 return gmdate($format, $time);
141 }
142 }
143
144 function acym_replaceDate(string $mydate, bool $display = false): string
145 {
146 if (strpos($mydate, '[time]') === false) {
147 if (is_numeric($mydate) && $display) {
148 return acym_date($mydate, 'Y-m-d H:i:s');
149 }
150
151 return $mydate;
152 }
153
154 if ($mydate === '[time]' && $display) {
155 return acym_translation('ACYM_NOW');
156 }
157
158 $mydate = str_replace('[time]', time(), $mydate);
159 $operators = ['+', '-'];
160 foreach ($operators as $oneOperator) {
161 if (strpos($mydate, $oneOperator) === false) continue;
162
163 $dateArray = explode($oneOperator, $mydate);
164 if ($oneOperator == '+') {
165 if ($display) {
166 $mydate = acym_translationSprintf('ACYM_AFTER_DATE', acym_secondsToTime(intval($dateArray[1])));
167 } else {
168 $mydate = intval($dateArray[0]) + intval($dateArray[1]);
169 }
170 } elseif ($oneOperator == '-') {
171 if ($display) {
172 $mydate = acym_translationSprintf('ACYM_BEFORE_DATE', acym_secondsToTime(intval($dateArray[1])));
173 } else {
174 $mydate = intval($dateArray[0]) - intval($dateArray[1]);
175 }
176 }
177 }
178
179 return $mydate;
180 }
181
182 function acym_secondsToTime(int $seconds): string
183 {
184 $dtF = new \DateTime('@0');
185 $dtT = new \DateTime("@$seconds");
186
187 return $dtF->diff($dtT)->format('%a day(s) %h h, %i min');
188 }
189
190 function acym_displayDateFormat(string $format, string $name = 'date', string $default = '', array $attributes = [], bool $returnHtml = true): string
191 {
192 if (empty($attributes)) {
193 $attributes = [
194 'class' => 'acym__custom__fields__select__form acym__select',
195 ];
196 }
197
198 $return = [];
199 if ($returnHtml) {
200 $return[] = '<div class="cell grid-x grid-margin-x">';
201 }
202
203 $days = [
204 '' => acym_translation('ACYM_DAY'),
205 ];
206 for ($i = 1; $i <= 31; $i++) {
207 $days[$i < 10 ? '0'.$i : $i] = $i < 10 ? '0'.$i : $i;
208 }
209
210 $month = [
211 '' => acym_translation('ACYM_MONTH'),
212 '01' => acym_translation('ACYM_JANUARY'),
213 '02' => acym_translation('ACYM_FEBRUARY'),
214 '03' => acym_translation('ACYM_MARCH'),
215 '04' => acym_translation('ACYM_APRIL'),
216 '05' => acym_translation('ACYM_MAY'),
217 '06' => acym_translation('ACYM_JUNE'),
218 '07' => acym_translation('ACYM_JULY'),
219 '08' => acym_translation('ACYM_AUGUST'),
220 '09' => acym_translation('ACYM_SEPTEMBER'),
221 '10' => acym_translation('ACYM_OCTOBER'),
222 '11' => acym_translation('ACYM_NOVEMBER'),
223 '12' => acym_translation('ACYM_DECEMBER'),
224 ];
225
226 $year = [
227 '' => acym_translation('ACYM_YEAR'),
228 ];
229 $currentYear = (int)acym_date('now', 'Y');
230 for ($i = 1900; $i <= $currentYear + 10; $i++) {
231 $year[$i] = $i;
232 }
233
234 $formatToDisplay = explode('%', $format);
235 $defaultDate = empty($default) ? [] : explode('-', $default);
236
237 unset($formatToDisplay[0]);
238 foreach ($formatToDisplay as $one) {
239 if ($one === 'd') {
240 if ($returnHtml) {
241 $return[] = '<div class="medium-3 margin-left-0 margin-right-0 cell">'.acym_select(
242 $days,
243 $name,
244 empty($defaultDate[2]) || $defaultDate[2] === '00' ? '' : $defaultDate[2],
245 array_merge($attributes, ['aria-label' => acym_translation('ACYM_DAY')]),
246 'value',
247 'text',
248 $name.'-'.$one
249 ).'</div>';
250 } elseif (!empty($defaultDate[2]) && $defaultDate[2] !== '00') {
251 $return[] = $defaultDate[2];
252 }
253 }
254
255 if ($one === 'm') {
256 if ($returnHtml) {
257 $return[] = '<div class="medium-5 cell">'.acym_select(
258 $month,
259 $name,
260 empty($defaultDate[1]) || $defaultDate[1] === '00' ? '' : $defaultDate[1],
261 array_merge($attributes, ['aria-label' => acym_translation('ACYM_MONTH')]),
262 'value',
263 'text',
264 $name.'-'.$one
265 ).'</div>';
266 } elseif (!empty($defaultDate[1]) && $defaultDate[1] !== '00') {
267 $return[] = $month[$defaultDate[1]];
268 }
269 }
270
271 if ($one === 'y') {
272 if ($returnHtml) {
273 $return[] = '<div class="medium-4 margin-right-0 cell">'.acym_select(
274 $year,
275 $name,
276 empty($defaultDate[0]) || $defaultDate[0] === '0000' ? '' : $defaultDate[0],
277 array_merge($attributes, ['aria-label' => acym_translation('ACYM_YEAR')]),
278 'value',
279 'text',
280 $name.'-'.$one
281 ).'</div>';
282 } elseif (!empty($defaultDate[0]) && $defaultDate[0] !== '0000') {
283 $return[] = $defaultDate[0];
284 }
285 }
286 }
287
288 if ($returnHtml) {
289 $return[] = '</div>';
290
291 return implode('', $return);
292 } else {
293 return implode(' ', $return);
294 }
295 }
296
297 function acym_getTimeFromUTCDate(?string $date): int
298 {
299 // Accept null/empty inputs gracefully and return 0 when no valid date is provided to avoid error.
300 if (empty($date)) {
301 return 0;
302 }
303
304 // Stored dates are UTC: parse them as UTC so the resulting timestamp is independent of the server timezone
305 $timestamp = strtotime($date.' UTC');
306 if ($timestamp === false) {
307 $timestamp = strtotime($date);
308 }
309 if ($timestamp === false) {
310 return 0;
311 }
312
313 return $timestamp;
314 }
315
316 function acym_getTimeFromCMSDate($date)
317 {
318 return acym_getTimeFromUTCDate($date) - acym_getTimeOffsetCMS();
319 }
320
321 function acym_getTime($date)
322 {
323 return acym_getTimeFromCMSDate($date);
324 }
325
326 function acym_date($date = 'now', $format = null, bool $useTz = true, bool $translate = true): string
327 {
328 if ($date === 'now') {
329 $date = time();
330 }
331
332 if (is_numeric($date)) {
333 $date = acym_dateTimeCMS($date);
334 }
335
336 if (!$format || (strpos($format, 'ACYM_DATE_FORMAT') !== false && acym_translation($format) == $format)) {
337 $format = 'ACYM_DATE_FORMAT_LC1';
338 }
339 if (strpos($format, 'ACYM_DATE') !== false) {
340 $format = acym_translation($format);
341 }
342
343 //Don't use timezone
344 if ($useTz === false) {
345 $date = new DateTime($date);
346
347 if ($translate) {
348 return acym_translateDate($date->format($format));
349 } else {
350 return $date->format($format);
351 }
352 } else {
353 //We replace the . with : WordPress give format like UTC+5.45, but we want something like UTC+5:45
354 $cmsOffset = str_replace('.', ':', acym_getCMSConfig('offset'));
355
356 $timezone = new DateTimeZone($cmsOffset);
357
358 if (!is_numeric($cmsOffset)) {
359 $cmsOffset = $timezone->getOffset(new DateTime());
360 }
361
362 // $date is a UTC date string: apply the CMS timezone offset then format in UTC so the server timezone never shifts the displayed result
363 if ($translate) {
364 return acym_translateDate(gmdate($format, strtotime($date.' UTC') + $cmsOffset));
365 } else {
366 return gmdate($format, strtotime($date.' UTC') + $cmsOffset);
367 }
368 }
369 }
370
371 function acym_translateDate(string $date): string
372 {
373 $map = [
374 'January' => 'ACYM_JANUARY',
375 'February' => 'ACYM_FEBRUARY',
376 'March' => 'ACYM_MARCH',
377 'April' => 'ACYM_APRIL',
378 'May' => 'ACYM_MAY',
379 'June' => 'ACYM_JUNE',
380 'July' => 'ACYM_JULY',
381 'August' => 'ACYM_AUGUST',
382 'September' => 'ACYM_SEPTEMBER',
383 'October' => 'ACYM_OCTOBER',
384 'November' => 'ACYM_NOVEMBER',
385 'December' => 'ACYM_DECEMBER',
386 'Monday' => 'ACYM_MONDAY',
387 'Tuesday' => 'ACYM_TUESDAY',
388 'Wednesday' => 'ACYM_WEDNESDAY',
389 'Thursday' => 'ACYM_THURSDAY',
390 'Friday' => 'ACYM_FRIDAY',
391 'Saturday' => 'ACYM_SATURDAY',
392 'Sunday' => 'ACYM_SUNDAY',
393 ];
394
395 foreach ($map as $english => $translationKey) {
396 $translation = acym_translation($translationKey);
397 if ($translation === $translationKey) {
398 continue;
399 }
400
401 $date = preg_replace('#'.preg_quote($english).'#i', $translation, $date);
402 $date = preg_replace('#'.preg_quote(substr($english, 0, 3)).'#i', mb_substr($translation, 0, 3), $date);
403 }
404
405 return $date;
406 }
407
408 function acym_isDateValid($date): bool
409 {
410 return $date !== '0000-00-00 00:00:00' && !empty($date);
411 }
412