The SEO Framework - Version 3.2.2

Version Description

This minor update brings major bug fixes. Most notoriously, the home page settings now predict the metadata perfectly in the admin screens. Bloggers will love this update, too, because Facebook and Twitter metadata for the home blog page is now always correct.

For developers, please note that the upcoming major release (3.3.0) will introduce new taxonomical settings. Because the image-rendering integration isn't suited for this, it'll be overhauled. For more information, see this issue.

Also, for developers, note that some API changes better suited for a major release were also brought into this minor release; these were required to fix some bugs.

Download this release

Release Info

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

Code changes from version 3.1.4 to 3.2.2

Files changed (70) hide show
  1. autodescription.php +4 -4
  2. bootstrap/activation.php +2 -2
  3. bootstrap/deactivation.php +2 -1
  4. bootstrap/define.php +1 -1
  5. bootstrap/envtest.php +5 -3
  6. bootstrap/load.php +7 -7
  7. bootstrap/upgrade.php +6 -4
  8. inc/classes/admin-init.class.php +178 -87
  9. inc/classes/admin-pages.class.php +3 -3
  10. inc/classes/builders/scripts.class.php +174 -62
  11. inc/classes/cache.class.php +28 -27
  12. inc/classes/compat.class.php +1 -1
  13. inc/classes/core.class.php +38 -49
  14. inc/classes/debug.class.php +55 -41
  15. inc/classes/deprecated.class.php +1 -2
  16. inc/classes/detect.class.php +37 -25
  17. inc/classes/doing-it-right.class.php +3 -2
  18. inc/classes/feed.class.php +1 -1
  19. inc/classes/generate-description.class.php +103 -204
  20. inc/classes/generate-image.class.php +16 -26
  21. inc/classes/generate-ldjson.class.php +13 -11
  22. inc/classes/generate-title.class.php +185 -70
  23. inc/classes/generate-url.class.php +29 -24
  24. inc/classes/generate.class.php +3 -4
  25. inc/classes/init.class.php +3 -3
  26. inc/classes/inpost.class.php +7 -4
  27. inc/classes/load.class.php +4 -4
  28. inc/classes/metaboxes.class.php +8 -29
  29. inc/classes/post-data.class.php +17 -17
  30. inc/classes/profile.class.php +6 -7
  31. inc/classes/query.class.php +76 -92
  32. inc/classes/render.class.php +3 -3
  33. inc/classes/sanitize.class.php +32 -76
  34. inc/classes/silencer.class.php +1 -1
  35. inc/classes/site-options.class.php +3 -4
  36. inc/classes/sitemaps.class.php +7 -2
  37. inc/classes/term-data.class.php +8 -8
  38. inc/classes/user-data.class.php +13 -4
  39. inc/functions/api.php +1 -1
  40. inc/functions/deprecated.php +2 -2
  41. inc/functions/tsfem-suggestion.php +10 -108
  42. inc/interfaces/debug.interface.php +4 -4
  43. inc/views/inpost/seo-settings-singular-gutenberg-data.php +12 -0
  44. inc/views/inpost/seo-settings-singular.php +14 -6
  45. inc/views/metaboxes/description-metabox.php +3 -146
  46. inc/views/metaboxes/feed-metabox.php +1 -1
  47. inc/views/metaboxes/general-metabox.php +9 -9
  48. inc/views/metaboxes/homepage-metabox.php +6 -6
  49. inc/views/metaboxes/robots-metabox.php +3 -3
  50. inc/views/metaboxes/schema-metabox.php +4 -4
  51. inc/views/metaboxes/social-metabox.php +7 -7
  52. inc/views/metaboxes/title-metabox.php +4 -4
  53. inc/views/metaboxes/webmaster-metabox.php +1 -1
  54. language/autodescription.pot +120 -193
  55. lib/css/pt.css +7 -0
  56. lib/css/pt.min.css +1 -1
  57. lib/js/gutenberg.js +1 -1
  58. lib/js/installer/tsfinstaller.js +0 -285
  59. lib/js/installer/tsfinstaller.min.js +0 -1
  60. lib/js/media.js +1 -1
  61. lib/js/pt-gb.js +339 -0
  62. lib/js/pt-gb.min.js +1 -0
  63. lib/js/pt.js +1 -1
  64. lib/js/tsf-gbc.js +253 -0
  65. lib/js/tsf-gbc.min.js +1 -0
  66. lib/js/tsf.js +107 -141
  67. lib/js/tsf.min.js +1 -1
  68. lib/js/tt.js +6 -3
  69. lib/js/tt.min.js +1 -1
  70. readme.txt +97 -120
autodescription.php CHANGED
@@ -2,8 +2,8 @@
2
  /**
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 any WordPress website.
6
- * Version: 3.1.4
7
  * Author: Sybre Waaijer
8
  * Author URI: https://theseoframework.com/
9
  * License: GPLv3
@@ -15,7 +15,7 @@ defined( 'ABSPATH' ) or die;
15
 
16
  /**
17
  * The SEO Framework plugin
18
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
19
  *
20
  * This program is free software: you can redistribute it and/or modify
21
  * it under the terms of the GNU General Public License version 3 as published
@@ -53,7 +53,7 @@ defined( 'ABSPATH' ) or die;
53
  *
54
  * @since 2.3.5
55
  */
56
- define( 'THE_SEO_FRAMEWORK_VERSION', '3.1.4' );
57
 
58
  /**
59
  * The plugin Database version.
2
  /**
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: 3.2.2
7
  * Author: Sybre Waaijer
8
  * Author URI: https://theseoframework.com/
9
  * License: GPLv3
15
 
16
  /**
17
  * The SEO Framework plugin
18
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
19
  *
20
  * This program is free software: you can redistribute it and/or modify
21
  * it under the terms of the GNU General Public License version 3 as published
53
  *
54
  * @since 2.3.5
55
  */
56
+ define( 'THE_SEO_FRAMEWORK_VERSION', '3.2.2' );
57
 
58
  /**
59
  * The plugin Database version.
bootstrap/activation.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -84,8 +84,8 @@ function _activation_set_options_autoload() {
84
  \remove_all_actions( "update_option_{$setting}" );
85
  \remove_all_filters( "sanitize_option_{$setting}" );
86
 
87
- //? Write a small difference, so the change will be forwarded to the database.
88
  $temp_options = $options;
 
89
  if ( is_array( $temp_options ) )
90
  $temp_options['update_buster'] = (int) time();
91
 
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
84
  \remove_all_actions( "update_option_{$setting}" );
85
  \remove_all_filters( "sanitize_option_{$setting}" );
86
 
 
87
  $temp_options = $options;
88
+ //? Write a small difference, so the change will be forwarded to the database.
89
  if ( is_array( $temp_options ) )
90
  $temp_options['update_buster'] = (int) time();
91
 
bootstrap/deactivation.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -65,6 +65,7 @@ function _deactivation_unset_options_autoload() {
65
  \remove_all_filters( "sanitize_option_{$setting}" );
66
 
67
  $temp_options = $options;
 
68
  if ( is_array( $temp_options ) )
69
  $temp_options['update_buster'] = (int) time();
70
 
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
65
  \remove_all_filters( "sanitize_option_{$setting}" );
66
 
67
  $temp_options = $options;
68
+ //? Write a small difference, so the change will be forwarded to the database.
69
  if ( is_array( $temp_options ) )
70
  $temp_options['update_buster'] = (int) time();
71
 
bootstrap/define.php CHANGED
@@ -7,7 +7,7 @@ defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
7
 
8
  /**
9
  * The SEO Framework plugin
10
- * Copyright (C) 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
7
 
8
  /**
9
  * The SEO Framework plugin
10
+ * Copyright (C) 2018 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
bootstrap/envtest.php CHANGED
@@ -7,7 +7,7 @@ defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
7
 
8
  /**
9
  * The SEO Framework plugin
10
- * Copyright (C) 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
@@ -72,9 +72,11 @@ function the_seo_framework_pre_boot_test() {
72
  'wp' => '37965',
73
  );
74
 
75
- ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $requirements['php'] and $test = 1
 
76
  or $GLOBALS['wp_db_version'] < $requirements['wp'] and $test = 2
77
  or $test = true;
 
78
 
79
  //* All good.
80
  if ( true === $test ) {
@@ -83,7 +85,7 @@ function the_seo_framework_pre_boot_test() {
83
  }
84
 
85
  if ( $ms ) {
86
- $_plugins = get_site_option( 'active_sitewide_plugins' );
87
  $network_mode = isset( $_plugins[ plugin_basename( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) ] );
88
  } else {
89
  $network_mode = false;
7
 
8
  /**
9
  * The SEO Framework plugin
10
+ * Copyright (C) 2018 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
72
  'wp' => '37965',
73
  );
74
 
75
+ // phpcs:disable Generic.Formatting.MultipleStatementAlignment.NotSameWarning
76
+ ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $requirements['php'] and $test = 1 // precision alignment ok.
77
  or $GLOBALS['wp_db_version'] < $requirements['wp'] and $test = 2
78
  or $test = true;
79
+ // phpcs:enable Generic.Formatting.MultipleStatementAlignment.NotSameWarning
80
 
81
  //* All good.
82
  if ( true === $test ) {
85
  }
86
 
87
  if ( $ms ) {
88
+ $_plugins = get_site_option( 'active_sitewide_plugins' );
89
  $network_mode = isset( $_plugins[ plugin_basename( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) ] );
90
  } else {
91
  $network_mode = false;
bootstrap/load.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -70,7 +70,7 @@ function _init_tsf() {
70
  if ( \The_SEO_Framework\_can_load() ) {
71
  if ( \is_admin() ) {
72
  //! TODO: admin-only loader.
73
- $tsf = new \The_SEO_Framework\Load();
74
  $tsf->loaded = true;
75
 
76
  /**
@@ -79,7 +79,7 @@ function _init_tsf() {
79
  */
80
  \do_action( 'the_seo_framework_admin_loaded' );
81
  } else {
82
- $tsf = new \The_SEO_Framework\Load();
83
  $tsf->loaded = true;
84
  }
85
 
@@ -89,7 +89,7 @@ function _init_tsf() {
89
  */
90
  \do_action( 'the_seo_framework_loaded' );
91
  } else {
92
- $tsf = new \The_SEO_Framework\Silencer();
93
  $tsf->loaded = false;
94
  }
95
 
@@ -125,11 +125,11 @@ function _autoload_classes( $class ) {
125
  $strip = 'The_SEO_Framework\\';
126
 
127
  if ( strpos( $class, '_Interface' ) ) {
128
- $path = THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE;
129
  $extension = '.interface.php';
130
- $class = str_replace( '_Interface', '', $class );
131
  } else {
132
- $path = THE_SEO_FRAMEWORK_DIR_PATH_CLASS;
133
  $extension = '.class.php';
134
 
135
  //: substr_count( $class, '\\', 2 ) >= 2 // strrpos... str_split...
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2018 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
70
  if ( \The_SEO_Framework\_can_load() ) {
71
  if ( \is_admin() ) {
72
  //! TODO: admin-only loader.
73
+ $tsf = new \The_SEO_Framework\Load();
74
  $tsf->loaded = true;
75
 
76
  /**
79
  */
80
  \do_action( 'the_seo_framework_admin_loaded' );
81
  } else {
82
+ $tsf = new \The_SEO_Framework\Load();
83
  $tsf->loaded = true;
84
  }
85
 
89
  */
90
  \do_action( 'the_seo_framework_loaded' );
91
  } else {
92
+ $tsf = new \The_SEO_Framework\Silencer();
93
  $tsf->loaded = false;
94
  }
95
 
125
  $strip = 'The_SEO_Framework\\';
126
 
127
  if ( strpos( $class, '_Interface' ) ) {
128
+ $path = THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE;
129
  $extension = '.interface.php';
130
+ $class = str_replace( '_Interface', '', $class );
131
  } else {
132
+ $path = THE_SEO_FRAMEWORK_DIR_PATH_CLASS;
133
  $extension = '.class.php';
134
 
135
  //: substr_count( $class, '\\', 2 ) >= 2 // strrpos... str_split...
bootstrap/upgrade.php CHANGED
@@ -3,9 +3,11 @@
3
  * @package The_SEO_Framework/Bootstrap
4
  */
5
 
 
 
6
  /**
7
  * The SEO Framework plugin
8
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
9
  *
10
  * This program is free software: you can redistribute it and/or modify
11
  * it under the terms of the GNU General Public License version 3 as published
@@ -20,8 +22,6 @@
20
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
  */
22
 
23
- defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
24
-
25
  /**
26
  * This file holds functions for upgrading the plugin.
27
  * This file will only be called ONCE if the required version option is lower
@@ -87,7 +87,7 @@ function the_seo_framework_do_upgrade() {
87
  if ( ! the_seo_framework()->loaded ) return;
88
 
89
  if ( the_seo_framework()->is_seo_settings_page( false ) ) {
90
- wp_redirect( self_admin_url() );
91
  exit;
92
  }
93
 
@@ -194,6 +194,7 @@ add_action( 'the_seo_framework_upgraded', 'the_seo_framework_prepare_extension_m
194
  * Enqueues and outputs an Extension Manager suggestion.
195
  *
196
  * @since 3.1.0
 
197
  * @staticvar bool $run
198
  *
199
  * @return void Early when already enqueued
@@ -204,6 +205,7 @@ function the_seo_framework_prepare_extension_manager_suggestion() {
204
 
205
  if ( is_admin() ) {
206
  add_action( 'admin_init', function() {
 
207
  require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'tsfem-suggestion.php';
208
  the_seo_framework_load_extension_manager_suggestion();
209
  }, 20 );
3
  * @package The_SEO_Framework/Bootstrap
4
  */
5
 
6
+ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
7
+
8
  /**
9
  * The SEO Framework plugin
10
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
22
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
  */
24
 
 
 
25
  /**
26
  * This file holds functions for upgrading the plugin.
27
  * This file will only be called ONCE if the required version option is lower
87
  if ( ! the_seo_framework()->loaded ) return;
88
 
89
  if ( the_seo_framework()->is_seo_settings_page( false ) ) {
90
+ wp_redirect( self_admin_url() ); // phpcs:ignore -- self_admin_url() is safe.
91
  exit;
92
  }
93
 
194
  * Enqueues and outputs an Extension Manager suggestion.
195
  *
196
  * @since 3.1.0
197
+ * @since 3.2.2. No longer suggests when the user is new.
198
  * @staticvar bool $run
199
  *
200
  * @return void Early when already enqueued
205
 
206
  if ( is_admin() ) {
207
  add_action( 'admin_init', function() {
208
+ if ( ! the_seo_framework_previous_db_version() ) return;
209
  require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'tsfem-suggestion.php';
210
  the_seo_framework_load_extension_manager_suggestion();
211
  }, 20 );
inc/classes/admin-init.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -99,16 +99,38 @@ class Admin_Init extends Init {
99
 
100
  if ( _has_run( __METHOD__ ) ) return;
101
 
102
- $rtl = \is_rtl();
103
-
104
- //! PHP 5.4 compat: put in var. Also, we call it twice here...
105
  $scripts = $this->Scripts();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  /**
107
  * @since 3.1.0
108
  * @param array $scripts The default CSS and JS loader settings.
109
  * @param string $scripts The \The_SEO_Framework\Builders\Scripts builder class name.
110
  */
111
- $scripts::register( (array) \apply_filters_ref_array( 'the_seo_framework_scripts', [
112
  [
113
  [
114
  'id' => 'tsf',
@@ -162,7 +184,7 @@ class Admin_Init extends Init {
162
  'border-bottom-color:{{$bg_accent}}',
163
  ],
164
  '.tsf-tooltip-text' => [
165
- $rtl ? 'direction:rtl;' : '',
166
  ],
167
  ],
168
  ],
@@ -176,24 +198,42 @@ class Admin_Init extends Init {
176
  'ver' => THE_SEO_FRAMEWORK_VERSION,
177
  ],
178
  ],
179
- $scripts,
180
- ] ) );
 
181
 
182
- if ( $this->is_post_edit() ) {
183
- $this->enqueue_media_scripts();
184
- $this->enqueue_primaryterm_scripts();
185
- } elseif ( $this->is_seo_settings_page() ) {
186
- $this->enqueue_media_scripts();
187
- \wp_enqueue_style( 'wp-color-picker' );
188
- \wp_enqueue_script( 'wp-color-picker' );
189
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  }
191
 
192
  /**
193
  * Enqueues Media Upload and Cropping scripts.
194
  *
195
  * @since 3.1.0
196
- * @staticvar bool|null $registered Prevents duplicate calls.
197
  */
198
  public function enqueue_media_scripts() {
199
 
@@ -254,27 +294,36 @@ class Admin_Init extends Init {
254
 
255
  if ( _has_run( __METHOD__ ) ) return;
256
 
257
- $id = $this->get_the_real_admin_ID();
258
- $rtl = \is_rtl();
259
 
260
  $post_type = \get_post_type( $id );
261
  $_taxonomies = $post_type ? $this->get_hierarchical_taxonomies_as( 'objects', $post_type ) : [];
 
262
 
263
- $taxonomies = [];
264
 
265
  foreach ( $_taxonomies as $_t ) {
266
- $_i18n_name = strtolower( $_t->labels->singular_name );
 
267
  $taxonomies[ $_t->name ] = [
268
  'name' => $_t->name,
269
- 'i18n' => [
270
- /* translators: %s = term name */
271
- 'makePrimary' => sprintf( \esc_html__( 'Make primary %s', 'autodescription' ), $_i18n_name ),
272
- /* translators: %s = term name */
273
- 'primary' => sprintf( \esc_html__( 'Primary %s', 'autodescription' ), $_i18n_name ),
274
- 'name' => $_i18n_name,
275
- ],
276
  'primary' => $this->get_primary_term_id( $id, $_t->name ) ?: 0,
277
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  }
279
 
280
  $inline_css = [];
@@ -290,15 +339,29 @@ class Admin_Init extends Init {
290
  ];
291
  }
292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  //! PHP 5.4 compat: put in var.
294
  $scripts = $this->Scripts();
295
  $scripts::register( [
296
  [
297
- 'id' => 'tsf-pt',
298
  'type' => 'js',
299
- 'deps' => [ 'jquery', 'tsf', 'tsf-tt' ],
300
  'autoload' => true,
301
- 'name' => 'pt',
302
  'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/js/',
303
  'ver' => THE_SEO_FRAMEWORK_VERSION,
304
  'l10n' => [
@@ -339,66 +402,69 @@ class Admin_Init extends Init {
339
  * 4 : Added dynamic output control.
340
  * @since 2.9.0 Added boolean $returnValue['states']['isSettingsPage']
341
  * @since 3.0.4 `descPixelGuideline` has been increased from "920 and 820" to "1820 and 1720" respectively.
 
342
  *
343
  * @return array $strings The l10n strings.
344
  */
345
  protected function get_javascript_l10n() {
346
 
347
  $id = $this->get_the_real_ID();
348
- $default_title = '';
 
349
  $title_additions = '';
350
 
351
  $use_title_additions = $this->use_title_branding();
352
- $home_tagline = $this->get_option( 'homepage_title_tagline' );
353
- $title_location = $this->get_option( 'title_location' );
 
354
 
355
- $title_separator = esc_html( $this->get_separator( 'title' ) );
356
- $description_separator = esc_html( $this->get_separator( 'description' ) );
357
-
358
- $ishome = false;
359
  $is_settings_page = $this->is_seo_settings_page();
360
- $is_post_edit = $this->is_post_edit();
361
- $is_term_edit = $this->is_term_edit();
362
- $has_input = $is_settings_page || $is_post_edit || $is_term_edit;
 
363
 
364
- $page_on_front = $this->has_page_on_front();
365
 
366
  if ( $is_settings_page ) {
367
  // We're on our SEO settings pages.
368
  if ( $page_on_front ) {
369
  // Home is a page.
370
- $id = \get_option( 'page_on_front' );
371
  $inpost_title = $this->get_custom_field( '_genesis_title', $id );
372
  } else {
373
  // Home is a blog.
374
  $inpost_title = '';
375
  }
376
- $default_title = $inpost_title ?: $this->get_blogname();
377
  $title_additions = $this->get_home_page_tagline();
378
 
379
  $use_title_additions = (bool) $this->get_option( 'homepage_tagline' );
380
  } else {
381
  // We're somewhere within default WordPress pages.
382
- if ( $this->is_static_frontpage( $id ) ) {
383
- $default_title = $this->get_option( 'homepage_title' ) ?: $this->get_blogname();
 
 
 
 
 
 
 
384
  $title_location = $this->get_option( 'home_title_location' );
385
- $ishome = true;
 
386
 
387
  $use_title_additions = (bool) $this->get_option( 'homepage_tagline' );
388
- $title_additions = $this->get_home_page_tagline();
389
  } elseif ( $is_post_edit ) {
390
- $default_title = $this->get_raw_generated_title( [ 'id' => $id ] );
391
  $title_additions = $this->get_blogname();
392
- } elseif ( $is_term_edit ) {
393
- //* Category or Tag.
394
- if ( $this->get_current_taxonomy() && $id ) {
395
- $default_title = $this->get_generated_single_term_title( $this->fetch_the_term( $id ) );
396
- $title_additions = $this->get_blogname();
397
- }
398
  } else {
399
  //* We're in a special place.
400
  // Can't fetch title.
401
- $default_title = '';
402
  $title_additions = $this->get_blogname();
403
  }
404
  }
@@ -408,15 +474,15 @@ class Admin_Init extends Init {
408
  * Use $this->get_settings_capability() ?... might conflict with other nonces.
409
  * @augments tsfMedia 'upload_files'
410
  */
411
- // 'manage_options' => \current_user_can( 'manage_options' ) ? \wp_create_nonce( 'tsf-ajax-manage_options' ) : false,
412
- 'upload_files' => \current_user_can( 'upload_files' ) ? \wp_create_nonce( 'tsf-ajax-upload_files' ) : false,
413
- 'edit_posts' => \current_user_can( 'edit_posts' ) ? \wp_create_nonce( 'tsf-ajax-edit_posts' ) : false,
414
  ] );
415
 
416
- $term_name = '';
417
  $use_term_prefix = false;
418
  if ( $is_term_edit ) {
419
- $term_name = $this->get_tax_type_label( $this->get_current_taxonomy(), true );
420
  $use_term_prefix = $this->use_generated_archive_prefix();
421
  }
422
 
@@ -431,7 +497,7 @@ class Admin_Init extends Init {
431
  'twTitlePHLock' => (bool) $this->get_custom_field( '_twitter_title', $id ),
432
  'twDescriptionPHLock' => (bool) $this->get_custom_field( '_twitter_description', $id ),
433
  ];
434
- } elseif ( $ishome ) {
435
  $social_settings_locks = [
436
  'refTitleLock' => (bool) $this->get_option( 'homepage_title' ),
437
  'refDescriptionLock' => (bool) $this->get_option( 'homepage_description' ),
@@ -444,17 +510,38 @@ class Admin_Init extends Init {
444
  }
445
 
446
  $social_settings_placeholders = [];
 
447
  if ( $is_post_edit || $is_settings_page ) {
448
- $social_settings_placeholders = [
449
- 'ogDesc' => $this->get_generated_open_graph_description( [ 'id' => $id ] ),
450
- 'twDesc' => $this->get_generated_twitter_description( [ 'id' => $id ] ),
451
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452
  foreach ( $social_settings_placeholders as &$v ) {
453
- $v = html_entity_decode( $v, ENT_COMPAT, 'UTF-8' );
454
  }
455
  }
456
 
457
- $input_guidelines = [];
458
  $input_guidelines_i18n = [];
459
  if ( $has_input ) {
460
  $input_guidelines = $this->get_input_guidelines();
@@ -465,7 +552,7 @@ class Admin_Init extends Init {
465
  'nonces' => $this->get_js_nonces(),
466
  'states' => [
467
  'isRTL' => (bool) \is_rtl(),
468
- 'isHome' => $ishome,
469
  'hasInput' => $has_input,
470
  'counterType' => \absint( $this->get_user_option( 0, 'counter_type', 3 ) ),
471
  'useTagline' => $use_title_additions,
@@ -485,32 +572,32 @@ class Admin_Init extends Init {
485
  'i18n' => [
486
  'saveAlert' => \__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
487
  'confirmReset' => \__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
 
488
  'privateTitle' => $has_input && $id ? trim( str_replace( '%s', '', \__( 'Private: %s', 'default' ) ) ) : '',
 
489
  'protectedTitle' => $has_input && $id ? trim( str_replace( '%s', '', \__( 'Protected: %s', 'default' ) ) ) : '',
490
  /* translators: Pixel counter. 1: width, 2: guideline */
491
  'pixelsUsed' => $has_input ? \__( '%1$d out of %2$d pixels are used.', 'autodescription' ) : '',
492
  'inputGuidelines' => $input_guidelines_i18n,
493
  ],
494
  'params' => [
495
- 'objectTitle' => $default_title,
496
- 'defaultTitle' => $default_title,
497
- 'titleAdditions' => $title_additions,
498
- 'blogDescription' => $this->s_title_raw( $this->get_blogdescription() ),
499
- 'termName' => $term_name,
500
- 'untitledTitle' => $this->get_static_untitled_title(),
501
- 'titleSeparator' => $title_separator,
502
- 'descriptionSeparator' => $description_separator,
503
- 'titleLocation' => $title_location,
504
- 'inputGuidelines' => $input_guidelines,
505
- 'socialPlaceholders' => $social_settings_placeholders,
506
  ],
507
  ];
508
 
509
- $flags = ENT_COMPAT;
510
  foreach ( [ 'i18n', 'params' ] as $key ) {
511
  foreach ( $l10n[ $key ] as &$v ) {
512
  if ( is_scalar( $v ) )
513
- $v = html_entity_decode( $v, $flags, 'UTF-8' );
514
  }
515
  }
516
 
@@ -741,7 +828,7 @@ class Admin_Init extends Init {
741
  * @since 2.9.3 : 1. Query arguments work again (regression 2.9.2).
742
  * 2. Now only accepts http and https protocols.
743
  *
744
- * @param string $page Menu slug.
745
  * @param array $query_args Optional. Associative array of query string arguments
746
  * (key => value). Default is an empty array.
747
  * @return null Return early if first argument is false.
@@ -876,8 +963,12 @@ class Admin_Init extends Init {
876
  public function _wp_ajax_crop_image() {
877
 
878
  $this->_check_tsf_ajax_referer( 'upload_files' );
879
- if ( ! \current_user_can( 'upload_files' ) || ! isset( $_POST['id'], $_POST['context'], $_POST['cropDetails'] ) )
 
 
 
880
  \wp_send_json_error();
 
881
 
882
  $attachment_id = \absint( $_POST['id'] ); // input var ok.
883
 
@@ -909,7 +1000,7 @@ class Admin_Init extends Init {
909
  $parent_url = \wp_get_attachment_url( $attachment_id );
910
  $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
911
 
912
- $size = @getimagesize( $cropped );
913
  $image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
914
 
915
  $object = [
@@ -921,7 +1012,7 @@ class Admin_Init extends Init {
921
  ];
922
 
923
  $attachment_id = \wp_insert_attachment( $object, $cropped );
924
- $metadata = \wp_generate_attachment_metadata( $attachment_id, $cropped );
925
 
926
  /**
927
  * Filters the cropped image attachment metadata.
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
99
 
100
  if ( _has_run( __METHOD__ ) ) return;
101
 
102
+ //! PHP 5.4 compat: put in var.
 
 
103
  $scripts = $this->Scripts();
104
+ $scripts::register( $this->get_default_scripts() );
105
+
106
+ if ( $this->is_post_edit() ) {
107
+ $this->enqueue_media_scripts();
108
+ $this->enqueue_primaryterm_scripts();
109
+
110
+ if ( $this->is_gutenberg_page() ) {
111
+ $this->enqueue_gutenberg_compat_scripts();
112
+ }
113
+ } elseif ( $this->is_seo_settings_page() ) {
114
+ $this->enqueue_media_scripts();
115
+ \wp_enqueue_style( 'wp-color-picker' );
116
+ \wp_enqueue_script( 'wp-color-picker' );
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Returns a filterable sequential array of default scripts.
122
+ *
123
+ * @since 3.2.2
124
+ *
125
+ * @return array
126
+ */
127
+ public function get_default_scripts() {
128
  /**
129
  * @since 3.1.0
130
  * @param array $scripts The default CSS and JS loader settings.
131
  * @param string $scripts The \The_SEO_Framework\Builders\Scripts builder class name.
132
  */
133
+ return (array) \apply_filters_ref_array( 'the_seo_framework_scripts', [
134
  [
135
  [
136
  'id' => 'tsf',
184
  'border-bottom-color:{{$bg_accent}}',
185
  ],
186
  '.tsf-tooltip-text' => [
187
+ \is_rtl() ? 'direction:rtl' : '',
188
  ],
189
  ],
190
  ],
198
  'ver' => THE_SEO_FRAMEWORK_VERSION,
199
  ],
200
  ],
201
+ $this->Scripts(),
202
+ ] );
203
+ }
204
 
205
+ /**
206
+ * Enqueues Media Upload and Cropping scripts.
207
+ *
208
+ * @since 3.2.0
209
+ * @staticvar bool|null $registered Prevents duplicate calls.
210
+ */
211
+ public function enqueue_gutenberg_compat_scripts() {
212
+
213
+ if ( _has_run( __METHOD__ ) ) return;
214
+
215
+ $scripts = $this->Scripts();
216
+ $scripts::register( [
217
+ [
218
+ 'id' => 'tsf-gbc',
219
+ 'type' => 'js',
220
+ 'deps' => [ 'jquery', 'tsf', 'wp-editor', 'wp-data', 'lodash', 'react' ],
221
+ 'autoload' => true,
222
+ 'name' => 'tsf-gbc',
223
+ 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/js/',
224
+ 'ver' => THE_SEO_FRAMEWORK_VERSION,
225
+ 'l10n' => [
226
+ 'name' => 'tsfGBCL10n',
227
+ 'data' => [],
228
+ ],
229
+ ],
230
+ ] );
231
  }
232
 
233
  /**
234
  * Enqueues Media Upload and Cropping scripts.
235
  *
236
  * @since 3.1.0
 
237
  */
238
  public function enqueue_media_scripts() {
239
 
294
 
295
  if ( _has_run( __METHOD__ ) ) return;
296
 
297
+ $id = $this->get_the_real_admin_ID();
 
298
 
299
  $post_type = \get_post_type( $id );
300
  $_taxonomies = $post_type ? $this->get_hierarchical_taxonomies_as( 'objects', $post_type ) : [];
301
+ $taxonomies = [];
302
 
303
+ $gutenberg = $this->is_gutenberg_page();
304
 
305
  foreach ( $_taxonomies as $_t ) {
306
+ $singular_name = $this->get_tax_type_label( $_t->name );
307
+
308
  $taxonomies[ $_t->name ] = [
309
  'name' => $_t->name,
 
 
 
 
 
 
 
310
  'primary' => $this->get_primary_term_id( $id, $_t->name ) ?: 0,
311
+ ] + (
312
+ $gutenberg ? [
313
+ 'i18n' => [
314
+ /* translators: %s = term name */
315
+ 'selectPrimary' => sprintf( \esc_html__( 'Select Primary %s', 'autodescription' ), $singular_name ),
316
+ ],
317
+ ] : [
318
+ 'i18n' => [
319
+ /* translators: %s = term name */
320
+ 'makePrimary' => sprintf( \esc_html__( 'Make primary %s', 'autodescription' ), strtolower( $singular_name ) ),
321
+ /* translators: %s = term name */
322
+ 'primary' => sprintf( \esc_html__( 'Primary %s', 'autodescription' ), strtolower( $singular_name ) ),
323
+ 'name' => strtolower( $singular_name ),
324
+ ],
325
+ ]
326
+ );
327
  }
328
 
329
  $inline_css = [];
339
  ];
340
  }
341
 
342
+ if ( $gutenberg ) {
343
+ $vars = [
344
+ 'id' => 'tsf-pt-gb',
345
+ 'name' => 'pt-gb',
346
+ ];
347
+ $deps = [ 'jquery', 'tsf', 'wp-hooks', 'wp-element', 'wp-components', 'wp-url', 'wp-api-fetch', 'lodash', 'react' ];
348
+ } else {
349
+ $vars = [
350
+ 'id' => 'tsf-pt',
351
+ 'name' => 'pt',
352
+ ];
353
+ $deps = [ 'jquery', 'tsf', 'tsf-tt' ];
354
+ }
355
+
356
  //! PHP 5.4 compat: put in var.
357
  $scripts = $this->Scripts();
358
  $scripts::register( [
359
  [
360
+ 'id' => $vars['id'],
361
  'type' => 'js',
362
+ 'deps' => $deps,
363
  'autoload' => true,
364
+ 'name' => $vars['name'],
365
  'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/js/',
366
  'ver' => THE_SEO_FRAMEWORK_VERSION,
367
  'l10n' => [
402
  * 4 : Added dynamic output control.
403
  * @since 2.9.0 Added boolean $returnValue['states']['isSettingsPage']
404
  * @since 3.0.4 `descPixelGuideline` has been increased from "920 and 820" to "1820 and 1720" respectively.
405
+ * @since 3.2.2 Added string $returnValue['nonces']['manage_options']
406
  *
407
  * @return array $strings The l10n strings.
408
  */
409
  protected function get_javascript_l10n() {
410
 
411
  $id = $this->get_the_real_ID();
412
+
413
+ $default_title = '';
414
  $title_additions = '';
415
 
416
  $use_title_additions = $this->use_title_branding();
417
+ $home_tagline = $this->get_option( 'homepage_title_tagline' );
418
+ $title_location = $this->get_option( 'title_location' );
419
+ $title_separator = \esc_html( $this->get_separator( 'title' ) );
420
 
421
+ $is_home = false;
 
 
 
422
  $is_settings_page = $this->is_seo_settings_page();
423
+ $page_on_front = $this->has_page_on_front();
424
+ $is_post_edit = $this->is_post_edit();
425
+ $is_term_edit = $this->is_term_edit();
426
+ $has_input = $is_settings_page || $is_post_edit || $is_term_edit;
427
 
428
+ $_decode_flags = ENT_QUOTES | ENT_COMPAT;
429
 
430
  if ( $is_settings_page ) {
431
  // We're on our SEO settings pages.
432
  if ( $page_on_front ) {
433
  // Home is a page.
434
+ $id = (int) \get_option( 'page_on_front' );
435
  $inpost_title = $this->get_custom_field( '_genesis_title', $id );
436
  } else {
437
  // Home is a blog.
438
  $inpost_title = '';
439
  }
440
+ $default_title = $inpost_title ?: $this->get_blogname();
441
  $title_additions = $this->get_home_page_tagline();
442
 
443
  $use_title_additions = (bool) $this->get_option( 'homepage_tagline' );
444
  } else {
445
  // We're somewhere within default WordPress pages.
446
+ if ( $is_term_edit ) {
447
+ //* Category or Tag.
448
+ if ( $this->get_current_taxonomy() && $id ) {
449
+ // DEBUG: Use get_generated_archive_title() instead...? use_generated_archive_prefix() is in the way.
450
+ $default_title = $this->get_generated_single_term_title( $this->fetch_the_term( $id ) );
451
+ $title_additions = $this->get_blogname();
452
+ }
453
+ } elseif ( $this->is_static_frontpage( $id ) ) { // implies $is_post_edit or $is_settings_page
454
+ $default_title = $this->get_option( 'homepage_title' ) ?: $this->get_blogname();
455
  $title_location = $this->get_option( 'home_title_location' );
456
+
457
+ $is_home = true;
458
 
459
  $use_title_additions = (bool) $this->get_option( 'homepage_tagline' );
460
+ $title_additions = $this->get_home_page_tagline();
461
  } elseif ( $is_post_edit ) {
462
+ $default_title = $this->get_raw_generated_title( [ 'id' => $id ] );
463
  $title_additions = $this->get_blogname();
 
 
 
 
 
 
464
  } else {
465
  //* We're in a special place.
466
  // Can't fetch title.
467
+ $default_title = '';
468
  $title_additions = $this->get_blogname();
469
  }
470
  }
474
  * Use $this->get_settings_capability() ?... might conflict with other nonces.
475
  * @augments tsfMedia 'upload_files'
476
  */
477
+ 'manage_options' => \current_user_can( 'manage_options' ) ? \wp_create_nonce( 'tsf-ajax-manage_options' ) : false,
478
+ 'upload_files' => \current_user_can( 'upload_files' ) ? \wp_create_nonce( 'tsf-ajax-upload_files' ) : false,
479
+ 'edit_posts' => \current_user_can( 'edit_posts' ) ? \wp_create_nonce( 'tsf-ajax-edit_posts' ) : false,
480
  ] );
481
 
482
+ $term_name = '';
483
  $use_term_prefix = false;
484
  if ( $is_term_edit ) {
485
+ $term_name = $this->get_tax_type_label( $this->get_current_taxonomy(), true );
486
  $use_term_prefix = $this->use_generated_archive_prefix();
487
  }
488
 
497
  'twTitlePHLock' => (bool) $this->get_custom_field( '_twitter_title', $id ),
498
  'twDescriptionPHLock' => (bool) $this->get_custom_field( '_twitter_description', $id ),
499
  ];
500
+ } elseif ( $is_home ) {
501
  $social_settings_locks = [
502
  'refTitleLock' => (bool) $this->get_option( 'homepage_title' ),
503
  'refDescriptionLock' => (bool) $this->get_option( 'homepage_description' ),
510
  }
511
 
512
  $social_settings_placeholders = [];
513
+
514
  if ( $is_post_edit || $is_settings_page ) {
515
+ if ( $is_settings_page ) {
516
+ if ( $page_on_front ) {
517
+ $social_settings_placeholders = [
518
+ 'ogDesc' => $this->get_custom_field( '_genesis_description', $id ) ?: $this->get_generated_open_graph_description( [ 'id' => $id ] ),
519
+ 'twDesc' => $this->get_custom_field( '_genesis_description', $id ) ?: $this->get_generated_twitter_description( [ 'id' => $id ] ),
520
+ ];
521
+ } else {
522
+ $social_settings_placeholders = [
523
+ 'ogDesc' => $this->get_generated_open_graph_description( [ 'id' => $id ] ),
524
+ 'twDesc' => $this->get_generated_twitter_description( [ 'id' => $id ] ),
525
+ ];
526
+ }
527
+ } elseif ( $is_home ) {
528
+ $social_settings_placeholders = [
529
+ 'ogDesc' => $this->get_option( 'homepage_description' ) ?: $this->get_generated_open_graph_description( [ 'id' => $id ] ),
530
+ 'twDesc' => $this->get_option( 'homepage_description' ) ?: $this->get_generated_twitter_description( [ 'id' => $id ] ),
531
+ ];
532
+ } else {
533
+ $social_settings_placeholders = [
534
+ 'ogDesc' => $this->get_generated_open_graph_description( [ 'id' => $id ] ),
535
+ 'twDesc' => $this->get_generated_twitter_description( [ 'id' => $id ] ),
536
+ ];
537
+ }
538
+
539
  foreach ( $social_settings_placeholders as &$v ) {
540
+ $v = html_entity_decode( $v, $_decode_flags, 'UTF-8' );
541
  }
542
  }
543
 
544
+ $input_guidelines = [];
545
  $input_guidelines_i18n = [];
546
  if ( $has_input ) {
547
  $input_guidelines = $this->get_input_guidelines();
552
  'nonces' => $this->get_js_nonces(),
553
  'states' => [
554
  'isRTL' => (bool) \is_rtl(),
555
+ 'isHome' => $is_home,
556
  'hasInput' => $has_input,
557
  'counterType' => \absint( $this->get_user_option( 0, 'counter_type', 3 ) ),
558
  'useTagline' => $use_title_additions,
572
  'i18n' => [
573
  'saveAlert' => \__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
574
  'confirmReset' => \__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
575
+ // phpcs:ignore -- WordPress doesn't have a comment, either.
576
  'privateTitle' => $has_input && $id ? trim( str_replace( '%s', '', \__( 'Private: %s', 'default' ) ) ) : '',
577
+ // phpcs:ignore -- WordPress doesn't have a comment, either.
578
  'protectedTitle' => $has_input && $id ? trim( str_replace( '%s', '', \__( 'Protected: %s', 'default' ) ) ) : '',
579
  /* translators: Pixel counter. 1: width, 2: guideline */
580
  'pixelsUsed' => $has_input ? \__( '%1$d out of %2$d pixels are used.', 'autodescription' ) : '',
581
  'inputGuidelines' => $input_guidelines_i18n,
582
  ],
583
  'params' => [
584
+ 'objectTitle' => $this->s_title_raw( $default_title ),
585
+ 'defaultTitle' => $this->s_title_raw( $default_title ),
586
+ 'titleAdditions' => $this->s_title_raw( $title_additions ),
587
+ 'blogDescription' => $this->s_title_raw( $this->get_blogdescription() ),
588
+ 'termName' => $this->s_title_raw( $term_name ),
589
+ 'untitledTitle' => $this->s_title_raw( $this->get_static_untitled_title() ),
590
+ 'titleSeparator' => $title_separator,
591
+ 'titleLocation' => $title_location,
592
+ 'inputGuidelines' => $input_guidelines,
593
+ 'socialPlaceholders' => $social_settings_placeholders,
 
594
  ],
595
  ];
596
 
 
597
  foreach ( [ 'i18n', 'params' ] as $key ) {
598
  foreach ( $l10n[ $key ] as &$v ) {
599
  if ( is_scalar( $v ) )
600
+ $v = html_entity_decode( $v, $_decode_flags, 'UTF-8' );
601
  }
602
  }
603
 
828
  * @since 2.9.3 : 1. Query arguments work again (regression 2.9.2).
829
  * 2. Now only accepts http and https protocols.
830
  *
831
+ * @param string $page Menu slug. This slug must exist, or the redirect will loop back to the current page.
832
  * @param array $query_args Optional. Associative array of query string arguments
833
  * (key => value). Default is an empty array.
834
  * @return null Return early if first argument is false.
963
  public function _wp_ajax_crop_image() {
964
 
965
  $this->_check_tsf_ajax_referer( 'upload_files' );
966
+ if (
967
+ ! \current_user_can( 'upload_files' ) // precision alignment ok.
968
+ || ! isset( $_POST['id'], $_POST['context'], $_POST['cropDetails'] ) // input var ok.
969
+ ) {
970
  \wp_send_json_error();
971
+ }
972
 
973
  $attachment_id = \absint( $_POST['id'] ); // input var ok.
974
 
1000
  $parent_url = \wp_get_attachment_url( $attachment_id );
1001
  $url = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
1002
 
1003
+ $size = @getimagesize( $cropped ); // phpcs:ignore -- Feature might not be enabled.
1004
  $image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
1005
 
1006
  $object = [
1012
  ];
1013
 
1014
  $attachment_id = \wp_insert_attachment( $object, $cropped );
1015
+ $metadata = \wp_generate_attachment_metadata( $attachment_id, $cropped );
1016
 
1017
  /**
1018
  * Filters the cropped image attachment metadata.
inc/classes/admin-pages.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -335,7 +335,7 @@ class Admin_Pages extends Inpost {
335
  if ( $this->get_static_cache( 'check_seo_plugin_conflicts' ) && \current_user_can( 'activate_plugins' ) ) {
336
  $this->detect_seo_plugins()
337
  and $this->do_dismissible_notice(
338
- __( 'Multiple SEO tools have been detected. You should only use one.', 'autodescription' ),
339
  'warning'
340
  );
341
  $this->update_static_cache( 'check_seo_plugin_conflicts', 0 );
@@ -356,7 +356,7 @@ class Admin_Pages extends Inpost {
356
  */
357
  protected function do_settings_page_notices() {
358
 
359
- $get = empty( $_GET ) ? null : $_GET;
360
 
361
  if ( null === $get )
362
  return;
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
335
  if ( $this->get_static_cache( 'check_seo_plugin_conflicts' ) && \current_user_can( 'activate_plugins' ) ) {
336
  $this->detect_seo_plugins()
337
  and $this->do_dismissible_notice(
338
+ \__( 'Multiple SEO tools have been detected. You should only use one.', 'autodescription' ),
339
  'warning'
340
  );
341
  $this->update_static_cache( 'check_seo_plugin_conflicts', 0 );
356
  */
357
  protected function do_settings_page_notices() {
358
 
359
+ $get = empty( $_GET ) ? null : $_GET; // CSRF, input var OK.
360
 
361
  if ( null === $get )
362
  return;
inc/classes/builders/scripts.class.php CHANGED
@@ -7,7 +7,7 @@ namespace The_SEO_Framework\Builders;
7
 
8
  /**
9
  * The SEO Framework plugin
10
- * Copyright (C) 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
@@ -82,9 +82,11 @@ final class Scripts {
82
 
83
  /**
84
  * @since 3.1.0
 
 
85
  * @param string|null $include_secret The inclusion secret generated on tab load.
86
  */
87
- public static $include_secret;
88
 
89
  /**
90
  * Prepares the class and loads constructor.
@@ -103,6 +105,7 @@ final class Scripts {
103
  *
104
  * @since 3.1.0
105
  * @access private
 
106
  */
107
  public function __construct() {
108
 
@@ -115,6 +118,20 @@ final class Scripts {
115
  \add_action( 'admin_footer', [ $this, '_output_templates' ], 999 );
116
  }
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  /**
119
  * Returns the script status of $id for $type.
120
  *
@@ -131,7 +148,7 @@ final class Scripts {
131
  }
132
 
133
  /**
134
- * Enqueues registered scripts, styles, and templates.
135
  *
136
  * @since 3.1.0
137
  */
@@ -141,11 +158,14 @@ final class Scripts {
141
  }
142
 
143
  /**
144
- * Registers script to be enqueued.
 
 
145
  *
146
  * @since 3.1.0
147
  * @uses static::$scripts
148
- * @see $this->enqueue_scripts()
 
149
  *
150
  * @NOTE If the script is associative, it'll be registered as-is.
151
  * If the script is sequential, it'll be iterated over, and then registered.
@@ -181,62 +201,162 @@ final class Scripts {
181
  }
182
 
183
  /**
184
- * Prepares scripts for output on post edit screens.
185
  *
186
- * @since 3.1.0
187
- * @access private
188
  *
189
- * @param string $hook The current admin hook.
 
190
  */
191
- public function _prepare_admin_scripts( $hook = '' ) {
192
- $this->enqueue_scripts();
 
 
 
 
 
 
 
 
193
  }
194
 
195
  /**
196
- * Enqueues scripts, l10n and templates.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  *
198
  * @since 3.1.0
199
- * @uses static::$scripts
200
- * @uses $this->generate_file_url()
201
- * @uses $this->register_template()
 
 
 
 
 
202
  */
203
- private function enqueue_scripts() {
 
 
204
 
 
 
 
 
 
 
 
 
205
  //= Register them first to accomodate for dependencies.
206
  foreach ( static::$scripts as $s ) {
207
  if ( static::get_status_of( $s['id'], $s['type'] ) & static::REGISTERED ) continue;
208
-
209
- switch ( $s['type'] ) {
210
- case 'css' :
211
- \wp_register_style( $s['id'], $this->generate_file_url( $s, 'css' ), $s['deps'], $s['ver'], 'all' );
212
- isset( $s['inline'] )
213
- and \wp_add_inline_style( $s['id'], $this->get_inline_css( $s['inline'] ) );
214
- break;
215
- case 'js' :
216
- \wp_register_script( $s['id'], $this->generate_file_url( $s, 'js' ), $s['deps'], $s['ver'], true );
217
- isset( $s['l10n'] )
218
- and \wp_localize_script( $s['id'], $s['l10n']['name'], $s['l10n']['data'] );
219
- isset( $s['tmpl'] )
220
- and $this->register_template( $s['id'], $s['tmpl'] );
221
- break;
222
- }
223
- static::$queue[ $s['type'] ][ $s['id'] ] = static::REGISTERED;
224
  }
 
225
 
 
 
 
 
 
 
 
 
226
  foreach ( static::$scripts as $s ) {
227
- if ( static::get_status_of( $s['id'], $s['type'] ) & static::LOADED ) continue;
228
-
229
  if ( $s['autoload'] ) {
230
- switch ( $s['type'] ) {
231
- case 'css' :
232
- \wp_enqueue_style( $s['id'] );
233
- break;
234
- case 'js' :
235
- \wp_enqueue_script( $s['id'] );
236
- break;
237
- }
238
  }
239
- static::$queue[ $s['type'] ][ $s['id'] ] |= static::LOADED;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
  }
242
 
@@ -310,7 +430,7 @@ final class Scripts {
310
  $tsf = \the_seo_framework();
311
 
312
  if (
313
- ! isset( $_colors[ $_scheme ]->colors )
314
  || ! is_array( $_colors[ $_scheme ]->colors )
315
  || count( $_colors[ $_scheme ]->colors ) < 4
316
  ) {
@@ -385,14 +505,21 @@ final class Scripts {
385
  * The loop will only run when templates are registered.
386
  *
387
  * @since 3.1.0
388
- * @see $this->enqueue_scripts()
 
 
 
389
  * @access private
 
390
  */
391
  public function _output_templates() {
392
- foreach ( static::$templates as $id => $templates )
393
- if ( \wp_script_is( $id, 'enqueued' ) ) // This list retains scripts after they're outputted.
394
  foreach ( $templates as $t )
395
  $this->output_view( $t[0], $t[1] );
 
 
 
396
  }
397
 
398
  /**
@@ -419,21 +546,6 @@ final class Scripts {
419
  include $file;
420
  static::$include_secret = null;
421
  }
422
-
423
- /**
424
- * Verifies view inclusion secret.
425
- *
426
- * @since 3.1.0
427
- * @see static::output_view()
428
- * @uses static::$include_secret
429
- * @internal
430
- *
431
- * @param string $secret The passed secret.
432
- * @return bool True on success, false on failure.
433
- */
434
- public static function verify( $secret ) {
435
- return $secret && static::$include_secret === $secret;
436
- }
437
  }
438
 
439
  $_load_scripts_class();
7
 
8
  /**
9
  * The SEO Framework plugin
10
+ * Copyright (C) 2018 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
11
  *
12
  * This program is free software: you can redistribute it and/or modify
13
  * it under the terms of the GNU General Public License version 3 as published
82
 
83
  /**
84
  * @since 3.1.0
85
+ * @since 3.2.2 Is now a private variable.
86
+ * @see static::verify()
87
  * @param string|null $include_secret The inclusion secret generated on tab load.
88
  */
89
+ private static $include_secret;
90
 
91
  /**
92
  * Prepares the class and loads constructor.
105
  *
106
  * @since 3.1.0
107
  * @access private
108
+ * @internal
109
  */
110
  public function __construct() {
111
 
118
  \add_action( 'admin_footer', [ $this, '_output_templates' ], 999 );
119
  }
120
 
121
+ /**
122
+ * Prepares scripts for output on post edit screens.
123
+ *
124
+ * @since 3.1.0
125
+ * @access private
126
+ * @internal
127
+ *
128
+ * @param string $hook The current admin hook.
129
+ */
130
+ public function _prepare_admin_scripts( $hook = '' ) {
131
+ $this->forward_known_scripts();
132
+ $this->autoload_known_scripts();
133
+ }
134
+
135
  /**
136
  * Returns the script status of $id for $type.
137
  *
148
  }
149
 
150
  /**
151
+ * Enqueues all known registered scripts, styles, and templates.
152
  *
153
  * @since 3.1.0
154
  */
158
  }
159
 
160
  /**
161
+ * Registers script to be enqueued. Can register multiple scripts at once.
162
+ *
163
+ * A better name would've been "collect"...
164
  *
165
  * @since 3.1.0
166
  * @uses static::$scripts
167
+ * @see $this->forward_known_scripts()
168
+ * @see $this->autoload_known_scripts()
169
  *
170
  * @NOTE If the script is associative, it'll be registered as-is.
171
  * If the script is sequential, it'll be iterated over, and then registered.
201
  }
202
 
203
  /**
204
+ * Registers and enqueues known scripts.
205
  *
206
+ * @since 3.2.2
 
207
  *
208
+ * @param string $id The script ID.
209
+ * @param string $type The script type.
210
  */
211
+ public static function forward_known_script( $id, $type ) {
212
+ if ( ! ( static::get_status_of( $id, $type ) & static::REGISTERED ) ) {
213
+ foreach ( static::$scripts as $s ) {
214
+ if ( $s['id'] === $id ) {
215
+ if ( $s['type'] === $type ) {
216
+ static::forward_script( $s );
217
+ }
218
+ }
219
+ }
220
+ }
221
  }
222
 
223
  /**
224
+ * Registers and enqueues known scripts.
225
+ *
226
+ * @since 3.2.2
227
+ * @uses static::forward_known_script();
228
+ *
229
+ * @param string $id The script ID.
230
+ * @param string $type The script type.
231
+ */
232
+ public static function enqueue_known_script( $id, $type ) {
233
+
234
+ static::forward_known_script( $id, $type );
235
+
236
+ if ( static::get_status_of( $id, $type ) & static::REGISTERED ) {
237
+ if ( ! ( static::get_status_of( $id, $type ) & static::LOADED ) ) {
238
+ static::load_script( $id, $type );
239
+ }
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Verifies template view inclusion secret.
245
  *
246
  * @since 3.1.0
247
+ * @see static::output_view()
248
+ * @uses static::$include_secret
249
+ *
250
+ * @example template file header:
251
+ * `defined( 'THE_SEO_FRAMEWORK_PRESENT' ) and The_SEO_Framework\Builders\Scripts::verify( $_secret ) or die;`
252
+ *
253
+ * @param string $secret The passed secret.
254
+ * @return bool True on success, false on failure.
255
  */
256
+ public static function verify( $secret ) {
257
+ return $secret && static::$include_secret === $secret;
258
+ }
259
 
260
+ /**
261
+ * Forwards known scripts to WordPress' script handler. Also prepares l10n and templates.
262
+ *
263
+ * @since 3.2.2
264
+ * @uses static::$scripts
265
+ * @uses static::egister_script()
266
+ */
267
+ private function forward_known_scripts() {
268
  //= Register them first to accomodate for dependencies.
269
  foreach ( static::$scripts as $s ) {
270
  if ( static::get_status_of( $s['id'], $s['type'] ) & static::REGISTERED ) continue;
271
+ static::forward_script( $s );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  }
273
+ }
274
 
275
+ /**
276
+ * Enqueues known scripts, and invokes the l10n and templates.
277
+ *
278
+ * @since 3.2.2
279
+ * @uses static::$scripts
280
+ * @uses static::load_script()
281
+ */
282
+ private function autoload_known_scripts() {
283
  foreach ( static::$scripts as $s ) {
 
 
284
  if ( $s['autoload'] ) {
285
+ if ( static::get_status_of( $s['id'], $s['type'] ) & static::LOADED ) continue;
286
+ static::load_script( $s['id'], $s['type'] );
 
 
 
 
 
 
287
  }
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Enqueues scripts in WordPress' script handler. Also prepares l10n and templates.
293
+ *
294
+ * @since 3.2.2
295
+ * @see $this->forward_known_scripts();
296
+ * @see static::enqueue_known_script();
297
+ * @augments static::$queue
298
+ * @uses $this->generate_file_url()
299
+ * @uses $this->get_inline_css()
300
+ * @uses $this->register_template()
301
+ *
302
+ * @param array $s The script.
303
+ */
304
+ private static function forward_script( array $s ) {
305
+
306
+ $instance = static::$instance;
307
+ $registered = false;
308
+
309
+ switch ( $s['type'] ) {
310
+ case 'css':
311
+ \wp_register_style( $s['id'], $instance->generate_file_url( $s, 'css' ), $s['deps'], $s['ver'], 'all' );
312
+ isset( $s['inline'] )
313
+ and \wp_add_inline_style( $s['id'], $instance->get_inline_css( $s['inline'] ) );
314
+ $registered = true;
315
+ break;
316
+ case 'js':
317
+ \wp_register_script( $s['id'], $instance->generate_file_url( $s, 'js' ), $s['deps'], $s['ver'], true );
318
+ isset( $s['l10n'] )
319
+ and \wp_localize_script( $s['id'], $s['l10n']['name'], $s['l10n']['data'] );
320
+ isset( $s['tmpl'] )
321
+ and $instance->register_template( $s['id'], $s['tmpl'] );
322
+ $registered = true;
323
+ break;
324
+ }
325
+ if ( $registered ) {
326
+ isset( static::$queue[ $s['type'] ][ $s['id'] ] )
327
+ and static::$queue[ $s['type'] ][ $s['id'] ] |= static::REGISTERED
328
+ or static::$queue[ $s['type'] ][ $s['id'] ] = static::REGISTERED; // Precision alignment ok.
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Loads known registered script.
334
+ *
335
+ * @since 3.2.2
336
+ *
337
+ * @param string $id The script ID.
338
+ * @param string $type The script type.
339
+ */
340
+ private static function load_script( $id, $type ) {
341
+
342
+ if ( ! ( static::get_status_of( $id, $type ) & static::REGISTERED ) ) return;
343
+
344
+ $loaded = false;
345
+
346
+ switch ( $type ) {
347
+ case 'css':
348
+ \wp_enqueue_style( $id );
349
+ $loaded = true;
350
+ break;
351
+ case 'js':
352
+ \wp_enqueue_script( $id );
353
+ $loaded = true;
354
+ break;
355
+ }
356
+ if ( $loaded ) {
357
+ isset( static::$queue[ $type ][ $id ] )
358
+ and static::$queue[ $type ][ $id ] |= static::LOADED
359
+ or static::$queue[ $type ][ $id ] = static::LOADED; // Precision alignment ok.
360
  }
361
  }
362
 
430
  $tsf = \the_seo_framework();
431
 
432
  if (
433
+ ! isset( $_colors[ $_scheme ]->colors ) // Precision alignment OK.
434
  || ! is_array( $_colors[ $_scheme ]->colors )
435
  || count( $_colors[ $_scheme ]->colors ) < 4
436
  ) {
505
  * The loop will only run when templates are registered.
506
  *
507
  * @since 3.1.0
508
+ * @since 3.2.2 Now clears outputted templates, so to prevent duplications.
509
+ * @see $this->forward_known_scripts()
510
+ * @see $this->register_template()
511
+ * @see $this->autoload_scripts()
512
  * @access private
513
+ * @internal
514
  */
515
  public function _output_templates() {
516
+ foreach ( static::$templates as $id => $templates ) {
517
+ if ( \wp_script_is( $id, 'enqueued' ) ) { // This list retains scripts after they're outputted.
518
  foreach ( $templates as $t )
519
  $this->output_view( $t[0], $t[1] );
520
+ unset( static::$templates[ $id ] );
521
+ }
522
+ }
523
  }
524
 
525
  /**
546
  include $file;
547
  static::$include_secret = null;
548
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  }
550
 
551
  $_load_scripts_class();
inc/classes/cache.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -215,7 +215,7 @@ class Cache extends Sitemaps {
215
  $success = false;
216
 
217
  switch ( $type ) :
218
- case 'front' :
219
  $front_id = $this->get_the_front_page_ID();
220
 
221
  $this->object_cache_delete( $this->get_meta_output_cache_key_by_type( $front_id, '', 'frontpage' ) );
@@ -223,14 +223,14 @@ class Cache extends Sitemaps {
223
  $success = true;
224
  break;
225
 
226
- case 'post' :
227
  $post_type = \get_post_type( $id );
228
 
229
  if ( $post_type ) {
230
  switch ( $post_type ) {
231
- case 'page' :
232
- case 'post' :
233
- case 'attachment' :
234
  break;
235
 
236
  default:
@@ -246,35 +246,35 @@ class Cache extends Sitemaps {
246
  break;
247
 
248
  //* Careful, this can only run on archive pages. For now.
249
- case 'term' :
250
  $this->object_cache_delete( $this->get_meta_output_cache_key_by_type( $id, $args['term'], 'term' ) );
251
  $this->delete_ld_json_transient( $id, $args['term'], 'term' );
252
  $success = true;
253
  break;
254
 
255
- case 'author' :
256
  $this->object_cache_delete( $this->get_meta_output_cache_key_by_type( $id, 'author', 'author' ) );
257
  $this->delete_ld_json_transient( $id, 'author', 'author' );
258
  $success = true;
259
  break;
260
 
261
- case 'sitemap' :
262
  $success = $this->delete_sitemap_transient();
263
  break;
264
 
265
- case 'robots' :
266
  $success = $this->object_cache_delete( $this->get_robots_txt_cache_key() );
267
  break;
268
 
269
- case 'excluded_post_ids' :
270
  $success = $this->delete_excluded_post_ids_transient();
271
  break;
272
 
273
- case 'object' :
274
  $success = \wp_cache_flush();
275
  break;
276
 
277
- case 'detection' :
278
  break;
279
 
280
  /**
@@ -284,8 +284,9 @@ class Cache extends Sitemaps {
284
  * @NOTE Other caching plugins can override these groups. Therefore this
285
  * does NOT work.
286
  * @TODO make this work.
 
287
  */
288
- case 'objectflush' :
289
  //* @NOTE false can't pass.
290
  if ( false && $this->use_object_cache ) {
291
  if ( isset( $GLOBALS['wp_object_cache']->cache['the_seo_framework'] ) ) {
@@ -309,7 +310,7 @@ class Cache extends Sitemaps {
309
  * @param array $args Additional arguments. They can overwrite $type and $id.
310
  * @param bool $success Whether the action cleared.
311
  */
312
- do_action( "the_seo_framework_delete_cache_{$type}", $type, $id, $args, $success );
313
 
314
  return $success;
315
  }
@@ -492,7 +493,7 @@ class Cache extends Sitemaps {
492
  /**
493
  * Change key based on options.
494
  */
495
- $options = $this->enable_ld_json_breadcrumbs() ? '1' : '0';
496
  $options .= $this->enable_ld_json_searchbox() ? '1' : '0';
497
 
498
  return 'tsf_' . $revision . '_' . $options . '_ldjs_' . $cache_key;
@@ -636,15 +637,15 @@ class Cache extends Sitemaps {
636
  $post_type = \get_post_type( $page_id );
637
 
638
  switch ( $post_type ) :
639
- case 'page' :
640
  $the_id = 'page_' . $page_id;
641
  break;
642
 
643
- case 'post' :
644
  $the_id = 'post_' . $page_id;
645
  break;
646
 
647
- case 'attachment' :
648
  $the_id = 'attach_' . $page_id;
649
  break;
650
 
@@ -711,25 +712,25 @@ class Cache extends Sitemaps {
711
  public function generate_cache_key_by_type( $page_id, $taxonomy = '', $type = '' ) {
712
 
713
  switch ( $type ) :
714
- case 'author' :
715
  return $this->add_cache_key_suffix( 'author_' . $page_id );
716
  break;
717
- case 'frontpage' :
718
  return $this->add_cache_key_suffix( $this->generate_front_page_cache_key() );
719
  break;
720
- case 'page' :
721
  return $this->add_cache_key_suffix( 'page_' . $page_id );
722
  break;
723
- case 'post' :
724
  return $this->add_cache_key_suffix( 'post_' . $page_id );
725
  break;
726
- case 'attachment' :
727
  return $this->add_cache_key_suffix( 'attach_' . $page_id );
728
  break;
729
- case 'singular' :
730
  return $this->add_cache_key_suffix( 'singular_' . $page_id );
731
  break;
732
- case 'term' :
733
  return $this->add_cache_key_suffix( $this->generate_taxonomical_cache_key( $page_id, $taxonomy ) );
734
  break;
735
  default:
@@ -757,7 +758,7 @@ class Cache extends Sitemaps {
757
  static $locale = null;
758
 
759
  if ( is_null( $locale ) )
760
- $locale = strtolower( get_locale() );
761
 
762
  return $key . '_' . $GLOBALS['blog_id'] . '_' . $locale;
763
  }
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
215
  $success = false;
216
 
217
  switch ( $type ) :
218
+ case 'front':
219
  $front_id = $this->get_the_front_page_ID();
220
 
221
  $this->object_cache_delete( $this->get_meta_output_cache_key_by_type( $front_id, '', 'frontpage' ) );
223
  $success = true;
224
  break;
225
 
226
+ case 'post':
227
  $post_type = \get_post_type( $id );
228
 
229
  if ( $post_type ) {
230
  switch ( $post_type ) {
231
+ case 'page':
232
+ case 'post':
233
+ case 'attachment':
234
  break;
235
 
236
  default:
246
  break;
247
 
248
  //* Careful, this can only run on archive pages. For now.
249
+ case 'term':
250
  $this->object_cache_delete( $this->get_meta_output_cache_key_by_type( $id, $args['term'], 'term' ) );
251
  $this->delete_ld_json_transient( $id, $args['term'], 'term' );
252
  $success = true;
253
  break;
254
 
255
+ case 'author':
256
  $this->object_cache_delete( $this->get_meta_output_cache_key_by_type( $id, 'author', 'author' ) );
257
  $this->delete_ld_json_transient( $id, 'author', 'author' );
258
  $success = true;
259
  break;
260
 
261
+ case 'sitemap':
262
  $success = $this->delete_sitemap_transient();
263
  break;
264
 
265
+ case 'robots':
266
  $success = $this->object_cache_delete( $this->get_robots_txt_cache_key() );
267
  break;
268
 
269
+ case 'excluded_post_ids':
270
  $success = $this->delete_excluded_post_ids_transient();
271
  break;
272
 
273
+ case 'object':
274
  $success = \wp_cache_flush();
275
  break;
276
 
277
+ case 'detection':
278
  break;
279
 
280
  /**
284
  * @NOTE Other caching plugins can override these groups. Therefore this
285
  * does NOT work.
286
  * @TODO make this work.
287
+ * @see 'object' switch-index.
288
  */
289
+ case 'objectflush':
290
  //* @NOTE false can't pass.
291
  if ( false && $this->use_object_cache ) {
292
  if ( isset( $GLOBALS['wp_object_cache']->cache['the_seo_framework'] ) ) {
310
  * @param array $args Additional arguments. They can overwrite $type and $id.
311
  * @param bool $success Whether the action cleared.
312
  */
313
+ \do_action( "the_seo_framework_delete_cache_{$type}", $type, $id, $args, $success );
314
 
315
  return $success;
316
  }
493
  /**
494
  * Change key based on options.
495
  */
496
+ $options = $this->enable_ld_json_breadcrumbs() ? '1' : '0';
497
  $options .= $this->enable_ld_json_searchbox() ? '1' : '0';
498
 
499
  return 'tsf_' . $revision . '_' . $options . '_ldjs_' . $cache_key;
637
  $post_type = \get_post_type( $page_id );
638
 
639
  switch ( $post_type ) :
640
+ case 'page':
641
  $the_id = 'page_' . $page_id;
642
  break;
643
 
644
+ case 'post':
645
  $the_id = 'post_' . $page_id;
646
  break;
647
 
648
+ case 'attachment':
649
  $the_id = 'attach_' . $page_id;
650
  break;
651
 
712
  public function generate_cache_key_by_type( $page_id, $taxonomy = '', $type = '' ) {
713
 
714
  switch ( $type ) :
715
+ case 'author':
716
  return $this->add_cache_key_suffix( 'author_' . $page_id );
717
  break;
718
+ case 'frontpage':
719
  return $this->add_cache_key_suffix( $this->generate_front_page_cache_key() );
720
  break;
721
+ case 'page':
722
  return $this->add_cache_key_suffix( 'page_' . $page_id );
723
  break;
724
+ case 'post':
725
  return $this->add_cache_key_suffix( 'post_' . $page_id );
726
  break;
727
+ case 'attachment':
728
  return $this->add_cache_key_suffix( 'attach_' . $page_id );
729
  break;
730
+ case 'singular':
731
  return $this->add_cache_key_suffix( 'singular_' . $page_id );
732
  break;
733
+ case 'term':
734
  return $this->add_cache_key_suffix( $this->generate_taxonomical_cache_key( $page_id, $taxonomy ) );
735
  break;
736
  default:
758
  static $locale = null;
759
 
760
  if ( is_null( $locale ) )
761
+ $locale = strtolower( \get_locale() );
762
 
763
  return $key . '_' . $GLOBALS['blog_id'] . '_' . $locale;
764
  }
inc/classes/compat.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
inc/classes/core.class.php CHANGED
@@ -9,7 +9,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
9
 
10
  /**
11
  * The SEO Framework plugin
12
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
13
  *
14
  * This program is free software: you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License version 3 as published
@@ -67,6 +67,7 @@ class Core {
67
  * If the property never existed, default PHP behavior is invoked.
68
  *
69
  * @since 2.8.0
 
70
  *
71
  * @param string $name The property name.
72
  * @param mixed $value The property value.
@@ -75,29 +76,28 @@ class Core {
75
  /**
76
  * For now, no deprecation is being handled; as no properties have been deprecated. Just removed.
77
  */
78
- $this->_inaccessible_p_or_m( 'the_seo_framework()->' . \esc_html( $name ), 'unknown' );
79
 
80
- //* Invoke default behavior.
81
- $this->$name = $value;
 
82
  }
83
 
84
  /**
85
  * Handles unapproachable invoked properties.
 
86
  * Makes sure deprecated properties are still accessible.
87
- * If property never existed, default PHP behavior is invoked.
88
  *
89
  * @since 2.7.0
90
  * @since 3.1.0 Removed known deprecations.
 
91
  *
92
  * @param string $name The property name.
93
- * @return mixed $var The property value.
94
  */
95
  final public function __get( $name ) {
96
-
97
- $this->_inaccessible_p_or_m( 'the_seo_framework()->' . \esc_html( $name ), 'unknown' );
98
-
99
- //* Invoke default behavior.
100
- return $this->$name;
101
  }
102
 
103
  /**
@@ -120,7 +120,7 @@ class Core {
120
  return call_user_func_array( [ $depr_class, $name ], $arguments );
121
  }
122
 
123
- \the_seo_framework()->_inaccessible_p_or_m( 'the_seo_framework()->' . \esc_html( $name ) . '()' );
124
  return;
125
  }
126
 
@@ -159,7 +159,7 @@ class Core {
159
  */
160
  public function get_view( $view, array $__args = [], $instance = 'main' ) {
161
 
162
- //? extract().
163
  foreach ( $__args as $__k => $__v ) $$__k = $__v;
164
  unset( $__k, $__v, $__args );
165
 
@@ -235,22 +235,11 @@ class Core {
235
  '<a href="https://theseoframework.com/" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
236
  \esc_html__( 'About', 'autodescription' )
237
  );
238
-
239
- /**
240
- * These are weak checks.
241
- * But it has minimum to no UX/performance impact on failure.
242
- */
243
- if ( ! defined( 'TSF_EXTENSION_MANAGER_VERSION' ) ) {
244
- $tsfem = \get_plugins( '/the-seo-framework-extension-manager' );
245
- //... I want PHP 5.5 for empty expressions :(
246
- // TODO open a plugin installation screen?
247
- if ( empty( $tsfem ) )
248
- $tsf_links['tsfem'] = sprintf(
249
- '<a href="%s" rel="noreferrer noopener" target="_blank">%s</a>',
250
- \esc_url( \__( 'https://wordpress.org/plugins/the-seo-framework-extension-manager/', 'autodescription' ) ),
251
- \esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
252
- );
253
- }
254
 
255
  return array_merge( $links, $tsf_links );
256
  }
@@ -751,23 +740,23 @@ class Core {
751
  * The conversion list's keys are per reference only.
752
  */
753
  $conversions = [
754
- '**' => 'strong',
755
- '*' => 'em',
756
- '`' => 'code',
757
- '[]()' => 'a',
758
  '======' => 'h6',
759
- '=====' => 'h5',
760
- '====' => 'h4',
761
- '===' => 'h3',
762
- '==' => 'h2',
763
- '=' => 'h1',
764
  ];
765
 
766
  $md_types = empty( $convert ) ? $conversions : array_intersect( $conversions, $convert );
767
 
768
  foreach ( $md_types as $type ) :
769
  switch ( $type ) :
770
- case 'strong' :
771
  $count = preg_match_all( '/(?:\*{2})([^\*{\2}]+)(?:\*{2})/', $text, $matches, PREG_PATTERN_ORDER );
772
 
773
  for ( $i = 0; $i < $count; $i++ ) {
@@ -779,7 +768,7 @@ class Core {
779
  }
780
  break;
781
 
782
- case 'em' :
783
  $count = preg_match_all( '/(?:\*{1})([^\*{\1}]+)(?:\*{1})/', $text, $matches, PREG_PATTERN_ORDER );
784
 
785
  for ( $i = 0; $i < $count; $i++ ) {
@@ -791,7 +780,7 @@ class Core {
791
  }
792
  break;
793
 
794
- case 'code' :
795
  $count = preg_match_all( '/(?:`{1})([^`{\1}]+)(?:`{1})/', $text, $matches, PREG_PATTERN_ORDER );
796
 
797
  for ( $i = 0; $i < $count; $i++ ) {
@@ -803,12 +792,12 @@ class Core {
803
  }
804
  break;
805
 
806
- case 'h6' :
807
- case 'h5' :
808
- case 'h4' :
809
- case 'h3' :
810
- case 'h2' :
811
- case 'h1' :
812
  $amount = filter_var( $type, FILTER_SANITIZE_NUMBER_INT );
813
  //* Considers word non-boundary. @TODO consider removing this?
814
  $expression = sprintf( '/(?:\={%1$s})\B([^\={\%1$s}]+)\B(?:\={%1$s})/', $amount );
@@ -824,8 +813,8 @@ class Core {
824
  }
825
  break;
826
 
827
- case 'a' :
828
- $count = preg_match_all( '/(?:(?:\[{1})([^\]{1}]+)(?:\]{1})(?:\({1})([^\)\(]+)(?:\){1}))/', $text, $matches, PREG_PATTERN_ORDER );
829
 
830
  $_string = $args['a_internal'] ? '<a href="%s">%s</a>' : '<a href="%s" target="_blank" rel="nofollow noreferrer noopener">%s</a>';
831
 
9
 
10
  /**
11
  * The SEO Framework plugin
12
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
13
  *
14
  * This program is free software: you can redistribute it and/or modify
15
  * it under the terms of the GNU General Public License version 3 as published
67
  * If the property never existed, default PHP behavior is invoked.
68
  *
69
  * @since 2.8.0
70
+ * @since 3.2.2 This method no longer allows to overwrite protected or private variables.
71
  *
72
  * @param string $name The property name.
73
  * @param mixed $value The property value.
76
  /**
77
  * For now, no deprecation is being handled; as no properties have been deprecated. Just removed.
78
  */
79
+ $this->_inaccessible_p_or_m( 'the_seo_framework()->' . $name, 'unknown' );
80
 
81
+ //* Invoke default behavior: Write variable if it's not protected.
82
+ if ( ! isset( $this->$name ) )
83
+ $this->$name = $value;
84
  }
85
 
86
  /**
87
  * Handles unapproachable invoked properties.
88
+ *
89
  * Makes sure deprecated properties are still accessible.
 
90
  *
91
  * @since 2.7.0
92
  * @since 3.1.0 Removed known deprecations.
93
+ * @since 3.2.2 This method no longer invokes PHP errors, nor returns protected values.
94
  *
95
  * @param string $name The property name.
96
+ * @return void
97
  */
98
  final public function __get( $name ) {
99
+ $this->_inaccessible_p_or_m( 'the_seo_framework()->' . $name, 'unknown' );
100
+ return;
 
 
 
101
  }
102
 
103
  /**
120
  return call_user_func_array( [ $depr_class, $name ], $arguments );
121
  }
122
 
123
+ \the_seo_framework()->_inaccessible_p_or_m( 'the_seo_framework()->' . $name . '()' );
124
  return;
125
  }
126
 
159
  */
160
  public function get_view( $view, array $__args = [], $instance = 'main' ) {
161
 
162
+ //? A faster extract().
163
  foreach ( $__args as $__k => $__v ) $$__k = $__v;
164
  unset( $__k, $__v, $__args );
165
 
235
  '<a href="https://theseoframework.com/" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
236
  \esc_html__( 'About', 'autodescription' )
237
  );
238
+ $tsf_links['tsfem'] = sprintf(
239
+ '<a href="%s" rel="noreferrer noopener" target="_blank">%s</a>',
240
+ 'https://theseoframework.com/extensions/',
241
+ \esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
242
+ );
 
 
 
 
 
 
 
 
 
 
 
243
 
244
  return array_merge( $links, $tsf_links );
245
  }
740
  * The conversion list's keys are per reference only.
741
  */
742
  $conversions = [
743
+ '**' => 'strong',
744
+ '*' => 'em',
745
+ '`' => 'code',
746
+ '[]()' => 'a',
747
  '======' => 'h6',
748
+ '=====' => 'h5',
749
+ '====' => 'h4',
750
+ '===' => 'h3',
751
+ '==' => 'h2',
752
+ '=' => 'h1',
753
  ];
754
 
755
  $md_types = empty( $convert ) ? $conversions : array_intersect( $conversions, $convert );
756
 
757
  foreach ( $md_types as $type ) :
758
  switch ( $type ) :
759
+ case 'strong':
760
  $count = preg_match_all( '/(?:\*{2})([^\*{\2}]+)(?:\*{2})/', $text, $matches, PREG_PATTERN_ORDER );
761
 
762
  for ( $i = 0; $i < $count; $i++ ) {
768
  }
769
  break;
770
 
771
+ case 'em':
772
  $count = preg_match_all( '/(?:\*{1})([^\*{\1}]+)(?:\*{1})/', $text, $matches, PREG_PATTERN_ORDER );
773
 
774
  for ( $i = 0; $i < $count; $i++ ) {
780
  }
781
  break;
782
 
783
+ case 'code':
784
  $count = preg_match_all( '/(?:`{1})([^`{\1}]+)(?:`{1})/', $text, $matches, PREG_PATTERN_ORDER );
785
 
786
  for ( $i = 0; $i < $count; $i++ ) {
792
  }
793
  break;
794
 
795
+ case 'h6':
796
+ case 'h5':
797
+ case 'h4':
798
+ case 'h3':
799
+ case 'h2':
800
+ case 'h1':
801
  $amount = filter_var( $type, FILTER_SANITIZE_NUMBER_INT );
802
  //* Considers word non-boundary. @TODO consider removing this?
803
  $expression = sprintf( '/(?:\={%1$s})\B([^\={\%1$s}]+)\B(?:\={%1$s})/', $amount );
813
  }
814
  break;
815
 
816
+ case 'a':
817
+ $count = preg_match_all( '/(?:(?:\[{1})([^\]]+)(?:\]{1})(?:\({1})([^\)\(]+)(?:\){1}))/', $text, $matches, PREG_PATTERN_ORDER );
818
 
819
  $_string = $args['a_internal'] ? '<a href="%s">%s</a>' : '<a href="%s" target="_blank" rel="nofollow noreferrer noopener">%s</a>';
820
 
inc/classes/debug.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -284,13 +284,54 @@ final class Debug implements Debug_Interface {
284
  }
285
  }
286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  /**
288
  * The SEO Framework error handler.
289
  *
290
- * Only handles notices.
291
  * @see E_USER_NOTICE
292
  *
293
  * @since 2.6.0
 
294
  *
295
  * @param int Error handling code.
296
  * @param string The error message.
@@ -298,28 +339,15 @@ final class Debug implements Debug_Interface {
298
  protected function error_handler_deprecated( $code, $message ) {
299
 
300
  //* Only do so if E_USER_NOTICE is pased.
301
- if ( 1024 === $code && isset( $message ) ) {
302
-
303
- $backtrace = debug_backtrace();
304
- /**
305
- * 0 = This function. 1 = Debug function. 2 = Error trigger. 3 = Deprecated Class, 4 = Deprecated Method, 5 = Magic Method, 6 = Deprecated call.
306
- * 0 = This function. 1 = Debug function. 2 = Error trigger. 3 = Deprecated Class, 4 = Deprecated Filter, 5 = Deprecated call.
307
- */
308
- if ( 'Filter ' === substr( $message, 0, 7 ) ) {
309
- $error = $backtrace[5];
310
- } else {
311
- $error = $backtrace[6];
312
- }
313
-
314
- $this->error_handler( $error, $message );
315
  }
316
  }
317
 
318
  /**
319
  * The SEO Framework error handler.
320
  *
321
- * Only handles notices.
322
- * @see E_USER_NOTICE
323
  *
324
  * @since 2.6.0
325
  *
@@ -329,25 +357,18 @@ final class Debug implements Debug_Interface {
329
  protected function error_handler_doing_it_wrong( $code, $message ) {
330
 
331
  //* Only do so if E_USER_NOTICE is pased.
332
- if ( 1024 === $code && isset( $message ) ) {
333
-
334
- $backtrace = debug_backtrace();
335
- /**
336
- * 0 = This function. 1 = Debug function. 2 = magic methods, 3 = Error trigger.
337
- */
338
- $error = $backtrace[3];
339
-
340
- $this->error_handler( $error, $message );
341
  }
342
  }
343
 
344
  /**
345
  * The SEO Framework error handler.
346
  *
347
- * Only handles notices.
348
- * @see E_USER_ERROR
349
  *
350
  * @since 2.6.0
 
351
  *
352
  * @param int Error handling code.
353
  * @param string The error message.
@@ -355,16 +376,8 @@ final class Debug implements Debug_Interface {
355
  protected function error_handler_inaccessible_call( $code, $message ) {
356
 
357
  //* Only do so if E_USER_ERROR is pased.
358
- if ( 256 === $code && isset( $message ) ) {
359
-
360
- $backtrace = debug_backtrace();
361
-
362
- /**
363
- * 0 = This function. 1-3 = Debug functions. 4-5 = magic methods, 6 = user call.
364
- */
365
- $error = $backtrace[6];
366
-
367
- $this->error_handler( $error, $message, $code );
368
  }
369
  }
370
 
@@ -374,7 +387,7 @@ final class Debug implements Debug_Interface {
374
  * @since 2.6.0
375
  * @since 2.8.0 added $code parameter
376
  *
377
- * @param array $error The Error location and file.
378
  * @param string $message The error message. Expected to be escaped.
379
  * @param int $code The error handler code.
380
  */
@@ -690,7 +703,8 @@ final class Debug implements Debug_Interface {
690
  }
691
 
692
  $value = '<font color="harrisonford">' . $type . ' ' . $value . '</font>';
693
- $out = \esc_html( $name ) . ' => ' . $value;
 
694
  $output .= $out . PHP_EOL;
695
  }
696
 
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
284
  }
285
  }
286
 
287
+ /**
288
+ * Retrieves the erroneous caller data.
289
+ *
290
+ * Assesses the depth of the caller based on "consistent" tracing.
291
+ * This is inaccurate when an error is invoked internally; but, you can trust that
292
+ * the plugin doesn't trigger this behavior.
293
+ *
294
+ * @since 3.2.2
295
+ * @see PHP debug_backtrace()
296
+ *
297
+ * @return array The erroneous caller data
298
+ */
299
+ protected function get_error() {
300
+
301
+ $backtrace = debug_backtrace();
302
+ /**
303
+ * 0 = This function.
304
+ * 1 = Error handler.
305
+ * 2 = Error forwarder.
306
+ * 3 = Debug handler.
307
+ */
308
+ if ( isset( $backtrace[7]['object'] ) && is_a( $backtrace[7]['object'], \the_seo_framework_class(), false ) ) {
309
+ /**
310
+ * 4 = TSF Factory magic method.
311
+ * 5 = Error invoking thing.
312
+ * 6 = TSF Factory. (the_seo_framework(), or a variable that stored this)
313
+ * 7 = Erroneous caller.
314
+ */
315
+ $error = $backtrace[7];
316
+ } else {
317
+ /**
318
+ * 4 = Error invoking thing.
319
+ * 5 = Erroneous caller.
320
+ */
321
+ $error = $backtrace[5];
322
+ }
323
+
324
+ return $error;
325
+ }
326
+
327
  /**
328
  * The SEO Framework error handler.
329
  *
330
+ * Only handles user notices.
331
  * @see E_USER_NOTICE
332
  *
333
  * @since 2.6.0
334
+ * @since 3.2.2 Fixed unaccounted-for backtrace depth logic since this class decoupling in 3.1
335
  *
336
  * @param int Error handling code.
337
  * @param string The error message.
339
  protected function error_handler_deprecated( $code, $message ) {
340
 
341
  //* Only do so if E_USER_NOTICE is pased.
342
+ if ( E_USER_NOTICE === $code && isset( $message ) ) {
343
+ $this->error_handler( $this->get_error(), $message );
 
 
 
 
 
 
 
 
 
 
 
 
344
  }
345
  }
346
 
347
  /**
348
  * The SEO Framework error handler.
349
  *
350
+ * Only handles user notices.
 
351
  *
352
  * @since 2.6.0
353
  *
357
  protected function error_handler_doing_it_wrong( $code, $message ) {
358
 
359
  //* Only do so if E_USER_NOTICE is pased.
360
+ if ( E_USER_NOTICE === $code && isset( $message ) ) {
361
+ $this->error_handler( $this->get_error(), $message );
 
 
 
 
 
 
 
362
  }
363
  }
364
 
365
  /**
366
  * The SEO Framework error handler.
367
  *
368
+ * Only handles user errors.
 
369
  *
370
  * @since 2.6.0
371
+ * @since 3.2.2 Fixed unaccounted-for backtrace depth logic since this class decoupling in 3.1
372
  *
373
  * @param int Error handling code.
374
  * @param string The error message.
376
  protected function error_handler_inaccessible_call( $code, $message ) {
377
 
378
  //* Only do so if E_USER_ERROR is pased.
379
+ if ( E_USER_ERROR === $code && isset( $message ) ) {
380
+ $this->error_handler( $this->get_error(), $message, $code );
 
 
 
 
 
 
 
 
381
  }
382
  }
383
 
387
  * @since 2.6.0
388
  * @since 2.8.0 added $code parameter
389
  *
390
+ * @param array $error The Error location and file data extruded from debug_backtrace().
391
  * @param string $message The error message. Expected to be escaped.
392
  * @param int $code The error handler code.
393
  */
703
  }
704
 
705
  $value = '<font color="harrisonford">' . $type . ' ' . $value . '</font>';
706
+ $out = \esc_html( $name ) . ' => ' . $value;
707
+
708
  $output .= $out . PHP_EOL;
709
  }
710
 
inc/classes/deprecated.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -664,5 +664,4 @@ final class Deprecated {
664
  $tsf->_deprecated_function( 'the_seo_framework()->generate_description_from_id()', '3.1.0', 'the_seo_framework()->get_generated_description()' );
665
  return $tsf->get_generated_description( $args, $escape );
666
  }
667
-
668
  }
8
 
9
  /**
10
  * The SEO Framework plugin
11
+ * Copyright (C) 2015 - 2019 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
664
  $tsf->_deprecated_function( 'the_seo_framework()->generate_description_from_id()', '3.1.0', 'the_seo_framework()->get_generated_description()' );
665
  return $tsf->get_generated_description( $args, $escape );
666
  }
 
667
  }
inc/classes/detect.class.php CHANGED
@@ -8,7 +8,7 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
 
9
  /**
10
  * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
12
  *
13
  * This program is free software: you can redistribute it and/or modify
14
  * it under the terms of the GNU General Public License version 3 as published
@@ -43,6 +43,7 @@ class Detect extends Render {
43
  */
44
  public function doing_ajax() {
45
  static $cache = null;
 
46
  return isset( $cache ) ? $cache : $cache = defined( 'DOING_AJAX' ) && DOING_AJAX;
47
  }
48
 
@@ -121,15 +122,17 @@ class Detect extends Render {
121
  public function conflicting_plugins() {
122
 
123
  $conflicting_plugins = [
124
- 'seo_tools' => [
125
  'Yoast SEO' => 'wordpress-seo/wp-seo.php',
126
  'Yoast SEO Premium' => 'wordpress-seo-premium/wp-seo-premium.php',
127
  'All in One SEO Pack' => 'all-in-one-seo-pack/all_in_one_seo_pack.php',
128
  'SEO Ultimate' => 'seo-ultimate/seo-ultimate.php',
129
  'Gregs High Performance SEO' => 'gregs-high-performance-seo/ghpseo.php',
130
  'SEOPress' => 'wp-seopress/seopress.php',
 
 
131
  ],
132
- 'sitemaps' => [
133
  'Google XML Sitemaps' => 'google-sitemap-generator/sitemap.php',
134
  'Better WordPress Google XML Sitemaps' => 'bwp-google-xml-sitemaps/bwp-simple-gxs.php', // Remove?
135
  'Google XML Sitemaps for qTranslate' => 'google-xml-sitemaps-v3-for-qtranslate/sitemap.php', // Remove?
@@ -138,16 +141,16 @@ class Detect extends Render {
138
  'Simple Wp Sitemap' => 'simple-wp-sitemap/simple-wp-sitemap.php',
139
  'XML Sitemaps' => 'xml-sitemaps/xml-sitemaps.php',
140
  ],
141
- 'open_graph' => [
142
  'Facebook Open Graph Meta Tags for WordPress' => 'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
143
- 'Facebook Thumb Fixer' => 'facebook-thumb-fixer/_facebook-thumb-fixer.php',
144
- 'NextGEN Facebook OG' => 'nextgen-facebook/nextgen-facebook.php',
145
- 'Open Graph' => 'opengraph/opengraph.php',
146
- 'Open Graph Protocol Framework' => 'open-graph-protocol-framework/open-graph-protocol-framework.php',
147
- 'Shareaholic2' => 'shareaholic/sexy-bookmarks.php',
148
- 'Social Sharing Toolkit' => 'social-sharing-toolkit/social_sharing_toolkit.php',
149
- 'WordPress Social Sharing Optimization' => 'wpsso/wpsso.php',
150
- 'WP Facebook Open Graph protocol' => 'wp-facebook-open-graph-protocol/wp-facebook-ogp.php',
151
  ],
152
  'twitter_card' => [],
153
  ];
@@ -270,7 +273,7 @@ class Detect extends Render {
270
  }
271
 
272
  ksort( $mapped );
273
- $key = serialize( $mapped );
274
 
275
  if ( isset( $cache[ $key ] ) )
276
  return $cache[ $key ];
@@ -934,17 +937,23 @@ class Detect extends Render {
934
  * Gets all post types that could possibly support SEO.
935
  *
936
  * @since 3.1.0
 
 
937
  *
938
  * @return array The post types with rewrite capabilities.
939
  */
940
  protected function get_rewritable_post_types() {
941
-
942
- $post_types = (array) \get_post_types( [
943
- 'public' => true,
944
- 'rewrite' => true,
945
- ] );
946
  //? array_values() because get_post_types() gives a sequential array.
947
- return array_unique( array_merge( $this->get_forced_supported_post_types(), array_values( $post_types ) ) );
 
 
 
 
 
 
 
 
948
  }
949
 
950
  /**
@@ -1035,13 +1044,18 @@ class Detect extends Render {
1035
  * Detects if we're on a Gutenberg page.
1036
  *
1037
  * @since 3.1.0