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
1038
*
1039
* @return bool
1040
*/
1041
- protected function is_gutenberg_page() {
1042
- if ( function_exists( '\\is_gutenberg_page' ) ) {
1043
return \is_gutenberg_page();
1044
- }
1045
return false;
1046
}
1047
@@ -1074,9 +1088,7 @@ class Detect extends Render {
1074
return $cache;
1075
1076
$parsed_url = \wp_parse_url( \get_option( 'home' ) );
1077
- if ( ! empty( $parsed_url['path'] ) && ltrim( $parsed_url['path'], ' \\/' ) )
1078
- $cache = true;
1079
1080
- return $cache ?: $cache = false;
1081
}
1082
}
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
43
*/
44
public function doing_ajax() {
45
static $cache = null;
46
+
47
return isset( $cache ) ? $cache : $cache = defined( 'DOING_AJAX' ) && DOING_AJAX;
48
}
49
122
public function conflicting_plugins() {
123
124
$conflicting_plugins = [
125
+ 'seo_tools' => [
126
'Yoast SEO' => 'wordpress-seo/wp-seo.php',
127
'Yoast SEO Premium' => 'wordpress-seo-premium/wp-seo-premium.php',
128
'All in One SEO Pack' => 'all-in-one-seo-pack/all_in_one_seo_pack.php',
129
'SEO Ultimate' => 'seo-ultimate/seo-ultimate.php',
130
'Gregs High Performance SEO' => 'gregs-high-performance-seo/ghpseo.php',
131
'SEOPress' => 'wp-seopress/seopress.php',
132
+ 'Rank Math' => 'seo-by-rank-math/rank-math.php',
133
+ 'Smart Crawl' => 'smartcrawl-seo/wpmu-dev-seo.php',
134
],
135
+ 'sitemaps' => [
136
'Google XML Sitemaps' => 'google-sitemap-generator/sitemap.php',
137
'Better WordPress Google XML Sitemaps' => 'bwp-google-xml-sitemaps/bwp-simple-gxs.php', // Remove?
138
'Google XML Sitemaps for qTranslate' => 'google-xml-sitemaps-v3-for-qtranslate/sitemap.php', // Remove?
141
'Simple Wp Sitemap' => 'simple-wp-sitemap/simple-wp-sitemap.php',
142
'XML Sitemaps' => 'xml-sitemaps/xml-sitemaps.php',
143
],
144
+ 'open_graph' => [
145
'Facebook Open Graph Meta Tags for WordPress' => 'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
146
+ 'Facebook Thumb Fixer' => 'facebook-thumb-fixer/_facebook-thumb-fixer.php',
147
+ 'NextGEN Facebook OG' => 'nextgen-facebook/nextgen-facebook.php',
148
+ 'Open Graph' => 'opengraph/opengraph.php',
149
+ 'Open Graph Protocol Framework' => 'open-graph-protocol-framework/open-graph-protocol-framework.php',
150
+ 'Shareaholic2' => 'shareaholic/sexy-bookmarks.php',
151
+ 'Social Sharing Toolkit' => 'social-sharing-toolkit/social_sharing_toolkit.php',
152
+ 'WordPress Social Sharing Optimization' => 'wpsso/wpsso.php',
153
+ 'WP Facebook Open Graph protocol' => 'wp-facebook-open-graph-protocol/wp-facebook-ogp.php',
154
],
155
'twitter_card' => [],
156
];
273
}
274
275
ksort( $mapped );
276
+ $key = serialize( $mapped ); // phpcs:ignore -- No objects are inserted, nor is this ever unserialized.
277
278
if ( isset( $cache[ $key ] ) )
279
return $cache[ $key ];
937
* Gets all post types that could possibly support SEO.
938
*
939
* @since 3.1.0
940
+ * @since 3.2.1 Added cache.
941
+ * @staticvar $cache
942
*
943
* @return array The post types with rewrite capabilities.
944
*/
945
protected function get_rewritable_post_types() {
946
+ static $cache = null;
947
//? array_values() because get_post_types() gives a sequential array.
948
+ return isset( $cache ) ? $cache : $cache = array_unique(
949
+ array_merge(
950
+ $this->get_forced_supported_post_types(),
951
+ array_values( (array) \get_post_types( [
952
+ 'public' => true,
953
+ 'rewrite' => true,
954
+ ] ) )
955
+ )
956
+ );
957
}
958
959
/**
1044
* Detects if we're on a Gutenberg page.
1045
*
1046
* @since 3.1.0
1047
+ * @since 3.2.0 : 1. Now detects the WP 5.0 block editor.
1048
+ * 2. Method is now public.
1049
*
1050
* @return bool
1051
*/
1052
+ public function is_gutenberg_page() {
1053
+ if ( function_exists( '\\use_block_editor_for_post' ) )
1054
+ return ! empty( $GLOBALS['post'] ) && \use_block_editor_for_post( $GLOBALS['post'] );
1055
+
1056
+ if ( function_exists( '\\is_gutenberg_page' ) )
1057
return \is_gutenberg_page();
1058
+
1059
return false;
1060
}
1061
1088
return $cache;
1089
1090
$parsed_url = \wp_parse_url( \get_option( 'home' ) );
1091
1092
+ return $cache = ! empty( $parsed_url['path'] ) && ltrim( $parsed_url['path'], ' \\/' );
1093
}
1094
}
inc/classes/doing-it-right.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
@@ -1779,7 +1779,7 @@ class Doing_It_Right extends Generate_Ldjson {
1779
return $i18n;
1780
1781
$guideline_i18n = $this->get_input_guidelines_i18n()['long'];
1782
-
1783
return $i18n = [
1784
'title' => \esc_attr__( 'Title:', 'autodescription' ),
1785
'description' => \esc_attr__( 'Description:', 'autodescription' ),
@@ -1808,5 +1808,6 @@ class Doing_It_Right extends Generate_Ldjson {
1808
'length_far_too_long' => $guideline_i18n['farTooLong'],
1809
'length_good' => $guideline_i18n['good'],
1810
];
1811
}
1812
}
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
1779
return $i18n;
1780
1781
$guideline_i18n = $this->get_input_guidelines_i18n()['long'];
1782
+ // phpcs:disable WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned -- precision alignment OK.
1783
return $i18n = [
1784
'title' => \esc_attr__( 'Title:', 'autodescription' ),
1785
'description' => \esc_attr__( 'Description:', 'autodescription' ),
1808
'length_far_too_long' => $guideline_i18n['farTooLong'],
1809
'length_good' => $guideline_i18n['good'],
1810
];
1811
+ // phpcs:enable WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned
1812
}
1813
}
inc/classes/feed.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/generate-description.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
@@ -48,7 +48,7 @@ class Generate_Description extends Generate {
48
public function get_description( $args = null, $escape = true ) {
49
50
$desc = $this->get_description_from_custom_field( $args, false )
51
- ?: $this->get_generated_description( $args, false );
52
53
return $escape ? $this->escape_description( $desc ) : $desc;
54
}
@@ -70,7 +70,7 @@ class Generate_Description extends Generate {
70
public function get_open_graph_description( $args = null, $escape = true ) {
71
72
$desc = $this->get_open_graph_description_from_custom_field( $args, false )
73
- ?: $this->get_generated_open_graph_description( $args, false );
74
75
return $escape ? $this->escape_description( $desc ) : $desc;
76
}
@@ -104,6 +104,7 @@ class Generate_Description extends Generate {
104
* Falls back to meta description.
105
*
106
* @since 3.1.0
107
* @see $this->get_open_graph_description()
108
* @see $this->get_open_graph_description_from_custom_field()
109
*
@@ -114,13 +115,19 @@ class Generate_Description extends Generate {
114
$desc = '';
115
116
if ( $this->is_real_front_page() ) {
117
- $desc = $this->get_option( 'homepage_og_description' ) ?: '';
118
- }
119
- if ( ! $desc ) {
120
- if ( $this->is_singular() ) {
121
- $desc = $this->get_custom_field( '_open_graph_description' )
122
- ?: $this->get_description_from_custom_field();
123
}
124
}
125
126
return $desc;
@@ -131,6 +138,8 @@ class Generate_Description extends Generate {
131
* Falls back to meta description.
132
*
133
* @since 3.1.0
134
* @see $this->get_open_graph_description()
135
* @see $this->get_open_graph_description_from_custom_field()
136
*
@@ -142,14 +151,18 @@ class Generate_Description extends Generate {
142
$desc = '';
143
144
if ( $args['taxonomy'] ) {
145
- $desc = '';
146
} else {
147
- if ( $this->is_front_page_by_id( $args['id'] ) ) {
148
- $desc = $this->get_option( 'homepage_og_description' ) ?: '';
149
- }
150
- if ( ! $desc ) {
151
$desc = $this->get_custom_field( '_open_graph_description', $args['id'] )
152
- ?: $this->get_description_from_custom_field( $args );
153
}
154
}
155
@@ -174,7 +187,7 @@ class Generate_Description extends Generate {
174
public function get_twitter_description( $args = null, $escape = true ) {
175
176
$desc = $this->get_twitter_description_from_custom_field( $args, false )
177
- ?: $this->get_generated_twitter_description( $args, false );
178
179
return $escape ? $this->escape_description( $desc ) : $desc;
180
}
@@ -208,6 +221,8 @@ class Generate_Description extends Generate {
208
* Falls back to Open Graph description.
209
*
210
* @since 3.1.0
211
* @see $this->get_twitter_description()
212
* @see $this->get_twitter_description_from_custom_field()
213
*
@@ -218,17 +233,23 @@ class Generate_Description extends Generate {
218
$desc = '';
219
220
if ( $this->is_real_front_page() ) {
221
- $desc = $this->get_option( 'homepage_twitter_description' )
222
- ?: $this->get_custom_field( '_twitter_description' )
223
- ?: $this->get_option( 'homepage_og_description' )
224
- ?: $this->get_custom_field( '_open_graph_description' )
225
- ?: $this->get_description_from_custom_field();
226
- } else {
227
- if ( $this->is_singular() ) {
228
- $desc = $this->get_custom_field( '_twitter_description' )
229
- ?: $this->get_custom_field( '_open_graph_description' )
230
- ?: $this->get_description_from_custom_field();
231
}
232
}
233
234
return $desc;
@@ -239,6 +260,8 @@ class Generate_Description extends Generate {
239
* Falls back to Open Graph description.
240
*
241
* @since 3.1.0
242
* @see $this->get_twitter_description()
243
* @see $this->get_twitter_description_from_custom_field()
244
*
@@ -250,18 +273,22 @@ class Generate_Description extends Generate {
250
$desc = '';
251
252
if ( $args['taxonomy'] ) {