PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
← All changes | inc/class-lp-datetime.php +272 -237 4.1.6.9.44.4.8 View file →
@@ -2,102 +2,58 @@
2 2
3 3 /**
4 4 * Class LP_Datetime
5 5 */
6 -class LP_Datetime extends DateTime {
6 +class LP_Datetime {
7 7 /**
8 - * @var string
8 + * @var string $format .
9 9 */
10 10 public static $format = 'Y-m-d H:i:s';
11 -
12 11 /**
13 - * @var object
12 + * Format date by config WP.
14 13 */
15 - protected static $gmt;
16 -
14 + const I18N_FORMAT = 'i18n';
17 15 /**
18 - * @var object
16 + * Format date time by config WP.
19 17 */
20 - protected static $stz;
21 -
18 + const I18N_FORMAT_HAS_TIME = 'i18n_has_time';
22 19 /**
23 - * @var DateTimeZone
20 + * Format date time Human.
24 21 */
25 - protected $tz;
26 -
22 + const HUMAN_FORMAT = 'human';
23 + /**
24 + * String date time.
25 + *
26 + * @var string $raw_date .
27 + */
27 28 protected $raw_date = null;
28 29
29 - protected static $def_timezone = null;
30 -
31 30 /**
32 31 * Constructor.
33 32 *
34 - * @param string $date
35 - * @param mixed $tz
33 + * @param string|int $date
34 + * @param mixed $tz
36 35 *
37 36 * @throws
38 37 */
39 38 public function __construct( $date = '', $tz = null ) {
40 - if ( empty( self::$gmt ) || empty( self::$stz ) ) {
41 - self::$gmt = new DateTimeZone( 'GMT' );
42 - self::$stz = new DateTimeZone( @date_default_timezone_get() ); // phpcs:ignore
43 - }
44 -
45 39 if ( $date instanceof LP_Datetime ) {
46 40 $this->raw_date = $date->get_raw_date();
47 41 } else {
48 - $this->raw_date = is_numeric( $date ) ? gmdate( 'Y-m-d H:i:s', $date ) : $date;
42 + $this->raw_date = is_numeric( $date ) ? gmdate( self::$format, $date ) : $date;
49 43 }
50 44
51 - if ( empty( $date ) ) {
52 - $date = current_time( 'mysql' );
45 + if ( empty( $this->raw_date ) ) {
46 + $this->raw_date = current_time( 'mysql', 1 );
53 47 }
54 -
55 - if ( ! ( $tz instanceof DateTimeZone ) ) {
56 - $tz = self::get_default_timezone( $tz );
57 - }
58 -
59 - if ( ! $tz ) {
60 - $tz = null;
61 - }
62 -
63 - date_default_timezone_set( 'UTC' );
64 -
65 - parent::__construct( $this->raw_date, $tz );
66 -
67 - date_default_timezone_set( self::$stz->getName() ); // phpcs:ignore
68 -
69 - $this->tz = $tz;
70 48 }
71 49
72 50 /**
73 - * Get default timezone from param and wp settings
51 + * Check date is null
74 52 *
75 - * @param mixed $tz
76 - *
77 - * @return DateTimeZone|null|string
53 + * @return bool
78 54 */
79 - public static function get_default_timezone( $tz ) {
80 - if ( empty( self::$def_timezone ) ) {
81 - if ( $tz === null ) {
82 - $tz = wp_timezone();
83 - } elseif ( is_string( $tz ) && $tz ) {
84 - $tz = new DateTimeZone( $tz );
85 - }
86 - self::$def_timezone = $tz;
87 - }
88 -
89 - return self::$def_timezone;
90 - }
91 -
92 - /**
93 - * Check if time is exceeded with current time
94 - */
95 - public function is_exceeded( $interval = 0 ) {
96 - return $this->getTimestamp() >= current_time( 'timestamp' ) + $interval; // phpcs:ignore
97 - }
98 -
99 - public function is_null() {
55 + public function is_null(): bool {
100 56 return ! $this->raw_date || $this->raw_date === '0000-00-00 00:00:00';
101 57 }
102 58
103 59 public function get_raw_date() {
@@ -104,258 +60,337 @@
104 60 return $this->raw_date;
105 61 }
106 62
107 63 /**
108 - * @param string $name The name of the property.
109 - *
110 - * @return mixed
111 - */
112 - public function __get( $name ) {
113 - $value = null;
114 -
115 - switch ( $name ) {
116 - case 'daysinmonth':
117 - $value = $this->format( 't', true );
118 - break;
119 -
120 - case 'dayofweek':
121 - $value = $this->format( 'N', true );
122 - break;
123 -
124 - case 'dayofyear':
125 - $value = $this->format( 'z', true );
126 - break;
127 -
128 - case 'isleapyear':
129 - $value = (bool) $this->format( 'L', true );
130 - break;
131 -
132 - case 'day':
133 - $value = $this->format( 'd', true );
134 - break;
135 -
136 - case 'hour':
137 - $value = $this->format( 'H', true );
138 - break;
139 -
140 - case 'minute':
141 - $value = $this->format( 'i', true );
142 - break;
143 -
144 - case 'second':
145 - $value = $this->format( 's', true );
146 - break;
147 -
148 - case 'month':
149 - $value = $this->format( 'm', true );
150 - break;
151 -
152 - case 'ordinal':
153 - $value = $this->format( 'S', true );
154 - break;
155 -
156 - case 'week':
157 - $value = $this->format( 'W', true );
158 - break;
159 -
160 - case 'year':
161 - $value = $this->format( 'Y', true );
162 - break;
163 -
164 - default:
165 - }
166 -
167 - return $value;
168 - }
169 -
170 - /**
171 64 * @return string The date as a formatted string.
172 65 */
173 66 public function __toString() {
174 - return (string) $this->format( self::$format, true );
67 + return $this->format( self::$format );
175 68 }
176 69
177 70 /**
178 71 * Gets the date as a formatted string.
179 72 *
180 - * @param string $format The date format specification string (see {@link PHP_MANUAL#date})
181 - * @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
73 + * @param string $format Set i18n to return date in local time.
182 74 *
183 - * @return string The date string in the specified format format.
75 + * @return string.
76 + * @version 4.0.2
77 + * @since 3.0.0
184 78 */
185 - public function format( $format = '', $local = true ) {
186 - if ( '0000-00-00 00:00:00' === $this->raw_date ) {
187 - return '';
79 + public function format( string $format = '' ): string {
80 + $date_str = '';
81 +
82 + if ( '0000-00-00 00:00:00' === $this->get_raw_date() ) {
83 + return $date_str;
188 84 }
189 85
190 86 if ( empty( $format ) ) {
191 - $format = 'mysql';
87 + $format = get_option( 'date_format', 'Y-m-d' );
192 88 }
193 89
194 - $return = false;
195 -
196 90 switch ( $format ) {
197 - case 'i18n':
198 - $return = learn_press_date_i18n( $this->getTimestamp( $local ) );
91 + case 'i18n': // Display format Date by Timezone of WP.
92 + $time_stamp = $this->getTimestamp(); // UTC+0 (GMT)
93 + $time_stamp_by_time_zone = $time_stamp + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
94 + $date_format = get_option( 'date_format' );
95 + $date_str = date_i18n( $date_format, $time_stamp_by_time_zone );
199 96 break;
200 - case 'timestamp':
201 - $return = $this->getTimestamp( $local );
97 + case 'i18n_has_time': // Display format Date Time by Timezone of WP.
98 + $date_time_format_wp = apply_filters(
99 + 'learn-press/datetime/format/i18n_has_time',
100 + get_option( 'date_format' ) . ' ' . get_option( 'time_format' )
101 + );
102 + $time_stamp = $this->getTimestamp(); // UTC+0 (GMT)
103 + $time_stamp_by_time_zone = $time_stamp + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
104 + $date_str = apply_filters(
105 + 'learn-press/datetime/date/i18n_has_time',
106 + sprintf(
107 + '%s',
108 + date_i18n( $date_time_format_wp, $time_stamp_by_time_zone )
109 + ),
110 + $time_stamp,
111 + $time_stamp_by_time_zone
112 + );
202 113 break;
203 114 case 'human':
204 - $time = $this->getTimestamp( true );// mysql2date( 'G', $date->format('Y-m-d H:i:s') );
205 - $time1 = $this->getTimestamp( false );// mysql2date( 'G', $date->format('Y-m-d H:i:s') );
206 - $time_diff = ( time() ) - $time1;
115 + $time = $this->getTimestamp();
116 + $time_diff = time() - $time;
207 117
208 118 if ( $time_diff > 0 ) {
209 - $return = sprintf( __( '%s ago', 'learnpress' ), human_time_diff( $time1, time() ) );
119 + $date_str = sprintf( __( '%s ago', 'learnpress' ), human_time_diff( $time, time() ) );
210 120 }
211 121 break;
212 122 case 'mysql':
213 - $return = $this->format( 'Y-m-d H:i:s', $local );
123 + $date_str = gmdate( 'Y-m-d H:i:s', $this->getTimestamp() );
214 124 break;
215 125 default:
216 - if ( ! $local && ! empty( self::$gmt ) ) {
217 - parent::setTimezone( self::$gmt );
218 - }
126 + $date_str = gmdate( $format, $this->getTimestamp() );
127 + }
219 128
220 - $return = parent::format( $format );
221 -
222 - if ( ! $local && ! empty( $this->tz ) ) {
223 - parent::setTimezone( $this->tz );
224 - }
129 + if ( ! is_string( $date_str ) ) {
130 + $date_str = '';
225 131 }
226 132
227 - return $return;
133 + return $date_str;
228 134 }
229 135
230 136 /**
231 - * @param boolean $hours True to return the value in hours.
137 + * Display date human time diff.
138 + * 1. Show number days, hours if >= 1 days
139 + * 2. Show number hours, seconds if >= 1 hours
140 + * 3. Show number seconds if < 1 hours
232 141 *
233 - * @return float
142 + * @param DateTime $date_start
143 + * @param DateTime $date_end
144 + *
145 + * @return string
146 + * @since 4.0.3
147 + * @version 1.0.5
234 148 */
235 - public function getOffset( $hours = false ) {
236 - return $this->tz ? (float) $hours ? ( $this->tz->getOffset( $this ) / 3600 ) : $this->tz->getOffset( $this ) : 0;
237 - }
149 + public static function format_human_time_diff( DateTime $date_start, DateTime $date_end ): string {
150 + $diff = $date_end->diff( $date_start );
151 + $week = floor( $diff->d / 7 );
238 152
239 - /**
240 - * @param DateTimeZone $tz The new DateTimeZone object.
241 - *
242 - * @return void
243 - */
244 - public function setTimezone( $tz ) {
245 - $this->tz = $tz;
153 + $i18n_year = self::get_string_plural_duration( $diff->y, 'year' );
154 + $i18n_month = self::get_string_plural_duration( $diff->m, 'month' );
155 + $i18n_week = self::get_string_plural_duration( $week, 'week' );
156 + $i18n_day = self::get_string_plural_duration( $diff->d, 'day' );
157 + $i18n_hour = self::get_string_plural_duration( $diff->h, 'hour' );
158 + $i18n_minute = self::get_string_plural_duration( $diff->i, 'minute' );
159 + $i18n_second = self::get_string_plural_duration( $diff->s, 'second' );
246 160
247 - parent::setTimezone( $tz );
161 + $format_date = '';
162 + $string = array(
163 + 'y' => '%y years',
164 + 'm' => '%m months',
165 + 'w' => '', // object don't have week, only add to custom week format
166 + 'd' => '%d days, %h hours',
167 + 'h' => '%h hours, %i minutes',
168 + 'i' => '%i minutes, %s seconds',
169 + 's' => $i18n_second,
170 + );
171 +
172 + foreach ( $string as $k => $v ) {
173 + if ( isset( $diff->{$k} ) && $diff->{$k} > 0 ) {
174 + switch ( $k ) {
175 + case 'y':
176 + $format_date = sprintf(
177 + '%1$s%2$s',
178 + $i18n_year,
179 + $diff->m > 0 ? ', ' . $i18n_month : ''
180 + );
181 + break;
182 + case 'm':
183 + $format_date = sprintf(
184 + '%1$s%2$s',
185 + $i18n_month,
186 + $diff->d > 0 ? ', ' . $i18n_day : ''
187 + );
188 + break;
189 + case 'd':
190 + $format_date = sprintf(
191 + '%1$s%2$s',
192 + $i18n_day,
193 + $diff->h > 0 ? ', ' . $i18n_hour : ''
194 + );
195 + break;
196 + case 'h':
197 + $format_date = sprintf(
198 + '%1$s%2$s',
199 + $i18n_hour,
200 + $diff->i > 0 ? ', ' . $i18n_minute : ''
201 + );
202 + break;
203 + case 'i':
204 + $format_date = sprintf(
205 + '%1$s%2$s',
206 + $i18n_minute,
207 + $diff->s > 0 ? ', ' . $i18n_second : ''
208 + );
209 + break;
210 + default:
211 + $format_date = $v;
212 + break;
213 + }
214 + break;
215 + } elseif ( 'w' === $k && $week > 0 ) {
216 + $day_remain = $diff->d - $week * 7;
217 + $format_date = sprintf(
218 + '%1$s%2$s',
219 + $i18n_week,
220 + $day_remain > 0 ? ', ' . self::get_string_plural_duration( $day_remain, 'day' ) : ''
221 + );
222 + break;
223 + }
224 + }
225 +
226 + return apply_filters(
227 + 'learn-press/datetime/format_human_time_diff',
228 + $format_date,
229 + $diff,
230 + $date_start,
231 + $date_end
232 + );
248 233 }
249 234
250 235 /**
236 + * Get the date as an SQL datetime string.
237 + *
251 238 * @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
252 239 *
253 240 * @return string
241 + * @version 4.0.1
242 + * @since 3.0.0
254 243 */
255 - public function toISO8601( $local = true ) {
256 - return $this->format( DateTime::RFC3339, $local );
244 + public function toSql( bool $local = false ): string {
245 + if ( $local ) {
246 + return $this->toSqlLocal();
247 + }
248 +
249 + return $this->format( 'mysql' );
257 250 }
258 251
259 252 /**
260 - * Gets the date as an SQL datetime string.
253 + * Convert to format sql local time.
261 254 *
262 - * @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
263 - *
264 - * @return string
255 + * @return string
256 + * @since 4.2.1
265 257 */
266 - public function toSql( $local = true ) {
267 - return $this->format( 'Y-m-d H:i:s', $local );
258 + private function toSqlLocal(): string {
259 + $time = $this->getTimestamp() + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
260 +
261 + return gmdate( LP_Datetime::$format, $time );
268 262 }
269 263
270 264 /**
271 - * Consider the date is in GMT and convert to local time with
272 - * gmt_offset option of WP Core.
265 + * Convert local time to gmt+0 time.
273 266 *
267 + * @param LP_Datetime $date_time_local
274 268 * @param string $format
275 269 *
276 - * @return int|string
277 - * @since 4.0.0
270 + * @return string
271 + * @since 4.3.6
272 + * @version 1.0.0
278 273 */
279 - public function toLocal( $format = 'Y-m-d H:i:s' ) {
280 - $time = $this->getTimestamp() + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
281 -
282 - if ( $format ) {
283 - return date( $format, $time ); // phpcs:ignore
284 - }
285 -
286 - return $time;
274 + public function to_gmt_string( LP_Datetime $date_time_local, string $format = 'Y-m-d H:i:s' ): string {
275 + $time_stamp = $date_time_local->getTimestamp() - $this->get_wp_option_gmt_offset() * HOUR_IN_SECONDS;
276 + $time = new LP_Datetime( $time_stamp );
277 + return $time->format( $format );
287 278 }
288 279
289 280 /**
290 - * Gets the date as an RFC 822 string. IETF RFC 2822 supercedes RFC 822 and its definition
291 - * can be found at the IETF Web site.
281 + * Get gmt offset from wp option.
292 282 *
293 - * @param boolean $local True to return the date string in the local time zone, false to return it in GMT.
294 - *
295 - * @return string
283 + * @return false|mixed|null
296 284 */
297 - public function toRFC822( $local = true ) {
298 - return $this->format( DateTime::RFC2822, $local );
285 + public function get_wp_option_gmt_offset() {
286 + return get_option( 'gmt_offset' );
299 287 }
300 288
301 289 /**
302 - * Gets the date as UNIX time stamp.
290 + * Get timestamp of Date.
303 291 *
304 - * @return integer The date as a UNIX timestamp.
292 + * @return int
305 293 */
306 - public function toUnix() {
307 - return (int) parent::format( 'U' );
308 - }
309 -
310 - public function getTimestamp( $local = true ) {
311 - $this->setGMT( $local );
312 - $timestamp = parent::getTimestamp();
313 - $this->setGMT( $local, false );
314 -
315 - if ( $local ) {
316 - $timestamp += $this->getOffset();
294 + public function getTimestamp(): int {
295 + try {
296 + $date = new DateTime( $this->get_raw_date() );
297 + } catch ( Throwable $e ) {
298 + error_log( __METHOD__ . ': ' . $e->getMessage() );
299 + $date = new DateTime();
317 300 }
318 301
319 - return $timestamp;
302 + return $date->getTimestamp();
320 303 }
321 304
322 - protected function setGMT( $local = false, $gmt = true ) {
323 - if ( $gmt ) {
324 - if ( $local == false && ! empty( self::$gmt ) ) {
325 - parent::setTimezone( self::$gmt );
326 - }
327 - } else {
328 - if ( $local == false && ! empty( $this->tz ) ) {
329 - parent::setTimezone( $this->tz );
330 - }
331 - }
305 + /**
306 + * Get timestamp of Date in local time.
307 + * Note: timestamp before handle must timezone is GMT+0
308 + *
309 + * @return int
310 + * @since 4.2.7.3
311 + */
312 + public function getTimestampLocal(): int {
313 + return $this->getTimestamp() + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
332 314 }
333 315
334 - public static function getSqlNullDate() {
335 - return '0000-00-00 00:00:00';
336 - }
337 -
338 316 /**
339 - * Add X seconds into datetime of this object.
317 + * Get string plural duration.
340 318 *
341 - * @param int $seconds
319 + * @param int $duration_number
320 + * @param string $duration_type
342 321 *
343 - * @throws
344 - *
345 - * @since 3.3.0
322 + * @return string
323 + * @version 1.0.5
324 + * @since 4.2.3.5
346 325 */
347 - public function addDuration( $seconds ) {
348 - $timestamp = $this->getTimestamp();
349 - parent::__construct( date( 'Y-m-d H:i:s', $timestamp + $seconds ), $this->tz ); // phpcs:ignore
326 + public static function get_string_plural_duration( int $duration_number, string $duration_type = '' ): string {
327 + switch ( strtolower( $duration_type ) ) {
328 + case 'second':
329 + $duration_str = sprintf(
330 + _n( '%s Second', '%s Seconds', $duration_number, 'learnpress' ),
331 + $duration_number
332 + );
333 + break;
334 + case 'minute':
335 + $duration_str = sprintf(
336 + _n( '%s Minute', '%s Minutes', $duration_number, 'learnpress' ),
337 + $duration_number
338 + );
339 + break;
340 + case 'hour':
341 + $duration_str = sprintf(
342 + _n( '%s Hour', '%s Hours', $duration_number, 'learnpress' ),
343 + $duration_number
344 + );
345 + break;
346 + case 'day':
347 + $duration_str = sprintf(
348 + _n( '%s Day', '%s Days', $duration_number, 'learnpress' ),
349 + $duration_number
350 + );
351 + break;
352 + case 'week':
353 + $duration_str = sprintf(
354 + _n( '%s Week', '%s Weeks', $duration_number, 'learnpress' ),
355 + $duration_number
356 + );
357 + break;
358 + case 'month':
359 + $duration_str = sprintf(
360 + _n( '%s Month', '%s Months', $duration_number, 'learnpress' ),
361 + $duration_number
362 + );
363 + break;
364 + case 'year':
365 + $duration_str = sprintf(
366 + _n( '%s Year', '%s Years', $duration_number, 'learnpress' ),
367 + $duration_number
368 + );
369 + break;
370 + default:
371 + $duration_str = $duration_number . ' ' . $duration_type;
372 + }
373 +
374 + return apply_filters( 'learn-press/i18n/plural_duration', $duration_str, $duration_number, $duration_type );
350 375 }
351 376
352 - public function getPeriod( $seconds, $local = true ) {
353 - $timestamp = $this->getTimestamp( $local );
377 + /**
378 + * Get timezone string
379 + *
380 + * @return string
381 + * @since 4.2.7.2
382 + * @version 1.0.0
383 + */
384 + public static function get_timezone_string(): string {
385 + $wp_timezone = wp_timezone_string();
386 + $is_utc = (int) $wp_timezone !== 0;
354 387
355 - if ( ! is_numeric( $seconds ) ) {
356 - $seconds = strtotime( $seconds ) - time();
388 + if ( $is_utc ) {
389 + $wp_timezone = sprintf( '%s %s', __( 'Timezone: UTC', 'learnpress' ), $wp_timezone );
390 + } else {
391 + $wp_timezone = sprintf( '%s %s', __( 'Timezone:', 'learnpress' ), $wp_timezone );
357 392 }
358 393
359 - return date( 'Y-m-d H:i:s', $timestamp + $seconds ); // phpcs:ignore
394 + return $wp_timezone;
360 395 }
361 396 }