The SEO Framework - Version 4.0.4

Version Description

WordPress 5.3 has a bug where the timezone set in PHP is taken into account when creating permalinks. Since this bug can cause canonical URLs with dates to point to a nonexistent page, we're sending out this patch where TSF sets the timezone to flat UTC for its front-end generation.

The proper fix in WordPress 5.3.1 is due in about three weeks from now, after which we'll consider reverting these changes.

Download this release

Release Info

Developer Cybr
Plugin Icon 128x128 The SEO Framework
Version 4.0.4
Comparing to
See all releases

Code changes from version 4.0.3 to 4.0.4

autodescription.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: The SEO Framework
4
  * Plugin URI: https://theseoframework.com/
5
  * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
6
- * Version: 4.0.3
7
  * Author: The SEO Framework Team
8
  * Author URI: https://theseoframework.com/
9
  * License: GPLv3
@@ -64,7 +64,7 @@ defined( 'ABSPATH' ) or die;
64
  *
65
  * @since 2.3.5
66
  */
67
- define( 'THE_SEO_FRAMEWORK_VERSION', '4.0.3' );
68
 
69
  /**
70
  * The plugin Database version.
3
  * Plugin Name: The SEO Framework
4
  * Plugin URI: https://theseoframework.com/
5
  * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
6
+ * Version: 4.0.4
7
  * Author: The SEO Framework Team
8
  * Author URI: https://theseoframework.com/
9
  * License: GPLv3
64
  *
65
  * @since 2.3.5
66
  */
67
+ define( 'THE_SEO_FRAMEWORK_VERSION', '4.0.4' );
68
 
69
  /**
70
  * The plugin Database version.
inc/classes/builders/sitemap.class.php CHANGED
@@ -63,13 +63,14 @@ abstract class Sitemap {
63
  * Prepares sitemap generation by raising the memory limit and fixing the timezone.
64
  *
65
  * @since 4.0.0
 
66
  */
67
  final public function prepare_generation() {
68
 
69
  \wp_raise_memory_limit( 'sitemap' );
70
 
71
  // Set timezone according to settings.
72
- static::$tsf->set_timezone();
73
  }
74
 
75
  /**
63
  * Prepares sitemap generation by raising the memory limit and fixing the timezone.
64
  *
65
  * @since 4.0.0
66
+ * @since 4.0.4 Now sets timezone to UTC to fix WP 5.3 bug <https://core.trac.wordpress.org/ticket/48623>
67
  */
68
  final public function prepare_generation() {
69
 
70
  \wp_raise_memory_limit( 'sitemap' );
71
 
72
  // Set timezone according to settings.
73
+ static::$tsf->set_timezone( 'UTC' );
74
  }
75
 
76
  /**
inc/classes/core.class.php CHANGED
@@ -438,8 +438,8 @@ class Core {
438
  *
439
  * @since 2.6.0
440
  *
441
- * @param bool $guess : If true, the timezone will be guessed from the
442
- * WordPress core gmt_offset option.
443
  * @return string PHP Timezone String. May be empty (thus invalid).
444
  */
445
  public function get_timezone_string( $guess = false ) {
@@ -476,14 +476,20 @@ class Core {
476
  /**
477
  * Sets and resets the timezone.
478
  *
 
 
479
  * This exists because WordPress' current_time() adds discrepancies between UTC and GMT.
480
  * This is also far more accurate than WordPress' tiny time table.
481
  *
 
 
 
482
  * @since 2.6.0
483
  * @since 3.0.6 Now uses the old timezone string when a new one can't be generated.
 
 
484
  *
485
  * @param string $tzstring Optional. The PHP Timezone string. Best to leave empty to always get a correct one.
486
- * @link http://php.net/manual/en/timezones.php
487
  * @param bool $reset Whether to reset to default. Ignoring first parameter.
488
  * @return bool True on success. False on failure.
489
  */
@@ -491,25 +497,20 @@ class Core {
491
 
492
  static $old_tz = null;
493
 
494
- if ( is_null( $old_tz ) ) {
495
- // See method docs.
496
- // phpcs:ignore
497
- $old_tz = date_default_timezone_get();
498
- if ( empty( $old_tz ) )
499
- $old_tz = 'UTC';
500
- }
501
 
502
  if ( $reset ) {
503
- // See method docs.
504
- // phpcs:ignore
505
- return date_default_timezone_set( $old_tz );
 
506
  }
507
 
508
  if ( empty( $tzstring ) )
509
  $tzstring = $this->get_timezone_string( true ) ?: $old_tz;
510
 
511
- // See method docs.
512
- // phpcs:ignore
513
  return date_default_timezone_set( $tzstring );
514
  }
515
 
@@ -528,6 +529,9 @@ class Core {
528
  * Converts time from GMT input to given format.
529
  *
530
  * @since 2.7.0
 
 
 
531
  *
532
  * @param string $format The datetime format.
533
  * @param string $time The GMT time. Expects timezone to be omitted.
@@ -536,7 +540,7 @@ class Core {
536
  public function gmt2date( $format = 'Y-m-d', $time = '' ) {
537
 
538
  if ( $time )
539
- return date( $format, strtotime( $time . ' GMT' ) );
540
 
541
  return '';
542
  }
438
  *
439
  * @since 2.6.0
440
  *
441
+ * @param bool $guess If true, the timezone will be guessed from the
442
+ * WordPress core gmt_offset option.
443
  * @return string PHP Timezone String. May be empty (thus invalid).
444
  */
445
  public function get_timezone_string( $guess = false ) {
476
  /**
477
  * Sets and resets the timezone.
478
  *
479
+ * NOTE: Always call reset_timezone() ASAP. Don't let changes linger, as they can be destructive.
480
+ *
481
  * This exists because WordPress' current_time() adds discrepancies between UTC and GMT.
482
  * This is also far more accurate than WordPress' tiny time table.
483
  *
484
+ * @TODO Note that WordPress 5.3 no longer requires this, and that we should rely on wp_date() instead.
485
+ * So, we should remove this dependency ASAP.
486
+ *
487
  * @since 2.6.0
488
  * @since 3.0.6 Now uses the old timezone string when a new one can't be generated.
489
+ * @since 4.0.4 Now also unsets the stored timezone string on reset.
490
+ * @link http://php.net/manual/en/timezones.php
491
  *
492
  * @param string $tzstring Optional. The PHP Timezone string. Best to leave empty to always get a correct one.
 
493
  * @param bool $reset Whether to reset to default. Ignoring first parameter.
494
  * @return bool True on success. False on failure.
495
  */
497
 
498
  static $old_tz = null;
499
 
500
+ // phpcs:ignore, WordPress.WP.TimezoneChange
501
+ $old_tz = $old_tz ?: date_default_timezone_get() ?: 'UTC';
 
 
 
 
 
502
 
503
  if ( $reset ) {
504
+ $_revert_tz = $old_tz;
505
+ $old_tz = null;
506
+ // phpcs:ignore, WordPress.WP.TimezoneChange
507
+ return date_default_timezone_set( $_revert_tz );
508
  }
509
 
510
  if ( empty( $tzstring ) )
511
  $tzstring = $this->get_timezone_string( true ) ?: $old_tz;
512
 
513
+ // phpcs:ignore, WordPress.WP.TimezoneChange
 
514
  return date_default_timezone_set( $tzstring );
515
  }
516
 
529
  * Converts time from GMT input to given format.
530
  *
531
  * @since 2.7.0
532
+ * @since 4.0.4 Now uses `gmdate()` instead of `date()`.
533
+ * @see `$this->set_timezone()`
534
+ * @see `$this->reset_timezone()`
535
  *
536
  * @param string $format The datetime format.
537
  * @param string $time The GMT time. Expects timezone to be omitted.
540
  public function gmt2date( $format = 'Y-m-d', $time = '' ) {
541
 
542
  if ( $time )
543
+ return gmdate( $format, strtotime( $time . ' GMT' ) );
544
 
545
  return '';
546
  }
inc/classes/detect.class.php CHANGED
@@ -533,6 +533,7 @@ class Detect extends Render {
533
  *
534
  * @since 4.0.0
535
  * @staticvar bool $detected
 
536
  *
537
  * @return bool
538
  */
533
  *
534
  * @since 4.0.0
535
  * @staticvar bool $detected
536
+ * @TODO add filter?
537
  *
538
  * @return bool
539
  */
inc/classes/init.class.php CHANGED
@@ -341,6 +341,8 @@ class Init extends Query {
341
  * @since 3.1.0 1. Now no longer outputs anything on preview.
342
  * 2. Now no longer outputs anything on blocked post types.
343
  * @since 4.0.0 Now no longer outputs anything on Customizer.
 
 
344
  * @access private
345
  */
346
  public function html_output() {
@@ -380,6 +382,9 @@ class Init extends Query {
380
 
381
  $before_legacy = $this->get_legacy_header_filters_output( 'before' );
382
 
 
 
 
383
  //* Limit processing and redundant tags on 404 and search.
384
  if ( $this->is_search() ) :
385
  $output = $this->og_locale()
@@ -400,8 +405,9 @@ class Init extends Query {
400
  . $this->yandex_site_output()
401
  . $this->pint_site_output();
402
  else :
403
- $set_timezone = $this->uses_time_in_timestamp_format() && ( $this->output_published_time() || $this->output_modified_time() );
404
- $set_timezone and $this->set_timezone();
 
405
 
406
  $output = $this->the_description()
407
  . $this->og_image()
@@ -431,9 +437,13 @@ class Init extends Query {
431
  . $this->yandex_site_output()
432
  . $this->pint_site_output();
433
 
434
- $set_timezone and $this->reset_timezone();
 
435
  endif;
436
 
 
 
 
437
  $after_legacy = $this->get_legacy_header_filters_output( 'after' );
438
 
439
  /**
341
  * @since 3.1.0 1. Now no longer outputs anything on preview.
342
  * 2. Now no longer outputs anything on blocked post types.
343
  * @since 4.0.0 Now no longer outputs anything on Customizer.
344
+ * @since 4.0.4 1. Now sets timezone to UTC to fix WP 5.3 bug <https://core.trac.wordpress.org/ticket/48623>
345
+ * 2. Now always sets timezone regardless of settings, because, again, bug.
346
  * @access private
347
  */
348
  public function html_output() {
382
 
383
  $before_legacy = $this->get_legacy_header_filters_output( 'before' );
384
 
385
+ /** @since 4.0.4 : WP 5.3 patch, added. TEMP */
386
+ $this->set_timezone( 'UTC' );
387
+
388
  //* Limit processing and redundant tags on 404 and search.
389
  if ( $this->is_search() ) :
390
  $output = $this->og_locale()
405
  . $this->yandex_site_output()
406
  . $this->pint_site_output();
407
  else :
408
+ /** @since 4.0.4 : WP 5.3 patch, commented. TEMP */
409
+ // $set_timezone = $this->uses_time_in_timestamp_format() && ( $this->output_published_time() || $this->output_modified_time() );
410
+ // $set_timezone and $this->set_timezone();
411
 
412
  $output = $this->the_description()
413
  . $this->og_image()
437
  . $this->yandex_site_output()
438
  . $this->pint_site_output();
439
 
440
+ /** @since 4.0.4 : WP 5.3 patch, commented. TEMP */
441
+ // $set_timezone and $this->reset_timezone();
442
  endif;
443
 
444
+ /** @since 4.0.4 : WP 5.3 patch, added. TEMP */
445
+ $this->reset_timezone();
446
+
447
  $after_legacy = $this->get_legacy_header_filters_output( 'after' );
448
 
449
  /**
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: seo, xml sitemap, google search, open graph, schema.org, twitter card, per
4
  Requires at least: 4.9.0
5
  Tested up to: 5.3
6
  Requires PHP: 5.6.0
7
- Stable tag: 4.0.3
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -227,6 +227,12 @@ If you wish to display breadcrumbs, then your theme should provide this. Alterna
227
 
228
  == Changelog ==
229
 
 
 
 
 
 
 
230
  = 4.0.3 =
231
 
232
  Google Search has a new bug in their parser, which causes pages to be deindexed unintentionally when a specific combination of robots-settings are used. To work around this bug, we changed how the recently introduced copyright directive settings work.
4
  Requires at least: 4.9.0
5
  Tested up to: 5.3
6
  Requires PHP: 5.6.0
7
+ Stable tag: 4.0.4
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
227
 
228
  == Changelog ==
229
 
230
+ = 4.0.4 =
231
+
232
+ WordPress 5.3 has a [bug](https://core.trac.wordpress.org/ticket/48623) where the timezone set in PHP is taken into account when creating permalinks. Since this bug can cause canonical URLs with dates to point to a nonexistent page, we're sending out this patch where TSF sets the timezone to flat UTC for its front-end generation.
233
+
234
+ The proper fix in WordPress 5.3.1 is due in about three weeks from now, after which we'll consider reverting [these changes](https://theseoframework.com/?p=3390#detailed).
235
+
236
  = 4.0.3 =
237
 
238
  Google Search has a new bug in their parser, which causes pages to be deindexed unintentionally when a specific combination of robots-settings are used. To work around this bug, we changed how the recently introduced copyright directive settings work.