The SEO Framework - Version 4.0.2

Version Description

France recently amended its copyright laws. In short, in France, it's now forbidden for content aggregators to display excerpts and previews of your content when no consent is given.

To accommodate those laws, Google will soon look for new directives, and we added new site-wide options to output those. These new options are disabled (unspecified) by default when you update The SEO Framework, but they are enabled (some access) by default when you install The SEO Framework on a new site. Please see this issue for our take on this.

In this update, we also fixed a few bugs and added various improvements.

Download this release

Release Info

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

Code changes from version 3.2.4 to 4.0.2

Files changed (165) hide show
  1. autodescription.php +35 -38
  2. bootstrap/activation.php +2 -23
  3. bootstrap/deactivation.php +2 -21
  4. bootstrap/define.php +48 -20
  5. bootstrap/envtest.php +14 -10
  6. bootstrap/load.php +53 -31
  7. bootstrap/upgrade.php +178 -34
  8. inc/classes/admin-init.class.php +313 -652
  9. inc/classes/admin-pages.class.php +525 -344
  10. inc/classes/bridges/index.php +9 -0
  11. inc/classes/bridges/listedit.class.php +269 -0
  12. inc/classes/bridges/listtable.class.php +290 -0
  13. inc/classes/bridges/ping.class.php +129 -0
  14. inc/classes/bridges/postsettings.class.php +200 -0
  15. inc/classes/bridges/scripts.class.php +1015 -0
  16. inc/classes/bridges/seobar.class.php +173 -0
  17. inc/classes/bridges/seosettings.class.php +746 -0
  18. inc/classes/bridges/sitemap.class.php +511 -0
  19. inc/classes/bridges/termsettings.class.php +70 -0
  20. inc/classes/builders/images.class.php +284 -0
  21. inc/classes/builders/index.php +6 -0
  22. inc/classes/builders/scripts.class.php +94 -32
  23. inc/classes/builders/seobar-page.class.php +986 -0
  24. inc/classes/builders/seobar-term.class.php +930 -0
  25. inc/classes/builders/seobar.class.php +227 -0
  26. inc/classes/builders/sitemap-base.class.php +484 -0
  27. inc/classes/builders/sitemap.class.php +204 -0
  28. inc/classes/cache.class.php +49 -80
  29. inc/classes/compat.class.php +0 -117
  30. inc/classes/core.class.php +181 -159
  31. inc/classes/debug.class.php +91 -96
  32. inc/classes/deprecated.class.php +622 -424
  33. inc/classes/detect.class.php +185 -215
  34. inc/classes/doing-it-right.class.php +0 -1814
  35. inc/classes/feed.class.php +18 -36
  36. inc/classes/generate-description.class.php +231 -85
  37. inc/classes/generate-image.class.php +408 -661
  38. inc/classes/generate-ldjson.class.php +73 -40
  39. inc/classes/generate-title.class.php +198 -119
  40. inc/classes/generate-url.class.php +181 -83
  41. inc/classes/generate.class.php +448 -115
  42. inc/classes/index.php +1 -11
  43. inc/classes/init.class.php +173 -138
  44. inc/classes/inpost.class.php +0 -409
  45. inc/classes/interpreters/index.php +7 -0
  46. inc/classes/interpreters/seobar.class.php +436 -0
  47. inc/classes/load.class.php +101 -86
  48. inc/classes/metaboxes.class.php +0 -656
  49. inc/classes/post-data.class.php +406 -267
  50. inc/classes/profile.class.php +39 -34
  51. inc/classes/query.class.php +236 -131
  52. inc/classes/render.class.php +94 -164
  53. inc/classes/sanitize.class.php +533 -197
  54. inc/classes/silencer.class.php +4 -2
  55. inc/classes/site-options.class.php +70 -69
  56. inc/classes/sitemaps.class.php +0 -1346
  57. inc/classes/term-data.class.php +288 -154
  58. inc/classes/user-data.class.php +18 -20
  59. inc/compat/index.php +10 -0
  60. inc/compat/php-mbstring.php +3 -0
  61. inc/compat/plugin-bbpress.php +36 -25
  62. inc/compat/plugin-buddypress.php +2 -0
  63. inc/compat/plugin-polylang.php +35 -5
  64. inc/compat/plugin-ultimatemember.php +20 -12
  65. inc/compat/plugin-woocommerce.php +136 -7
  66. inc/compat/plugin-wpforo.php +26 -29
  67. inc/compat/plugin-wpml.php +7 -5
  68. inc/compat/theme-genesis.php +8 -6
  69. inc/compat/wp-470.php +0 -10
  70. inc/functions/api.php +17 -4
  71. inc/functions/deprecated.php +4 -3
  72. inc/functions/index.php +6 -0
  73. inc/functions/upgrade-suggestion.php +21 -11
  74. inc/interfaces/debug.interface.php +0 -92
  75. inc/traits/core/index.php +6 -0
  76. inc/traits/core/overload.trait.php +136 -0
  77. inc/traits/index.php +14 -0
  78. inc/views/{metaboxes → admin/metaboxes}/description-metabox.php +6 -5
  79. inc/views/admin/metaboxes/feed-metabox.php +64 -0
  80. inc/views/{metaboxes → admin/metaboxes}/general-metabox.php +156 -108
  81. inc/views/{metaboxes → admin/metaboxes}/homepage-metabox.php +265 -299
  82. inc/views/{metaboxes → admin/metaboxes}/index.php +0 -0
  83. inc/views/admin/metaboxes/robots-metabox.php +339 -0
  84. inc/views/{metaboxes → admin/metaboxes}/schema-metabox.php +68 -77
  85. inc/views/{metaboxes → admin/metaboxes}/sitemaps-metabox.php +118 -96
  86. inc/views/{metaboxes → admin/metaboxes}/social-metabox.php +109 -102
  87. inc/views/{metaboxes → admin/metaboxes}/title-metabox.php +43 -49
  88. inc/views/{metaboxes → admin/metaboxes}/webmaster-metabox.php +7 -6
  89. inc/views/admin/seo-settings-columns.php +1 -0
  90. inc/views/admin/seo-settings-wrap.php +15 -6
  91. inc/views/admin/wrap-content.php +59 -0
  92. inc/views/admin/wrap-nav.php +49 -0
  93. inc/views/debug/output.php +6 -3
  94. inc/views/{inpost → edit}/index.php +0 -0
  95. inc/views/{inpost → edit}/seo-settings-singular-gutenberg-data.php +3 -2
  96. inc/views/{inpost → edit}/seo-settings-singular.php +181 -166
  97. inc/views/edit/seo-settings-tt.php +348 -0
  98. inc/views/{inpost → edit}/wrap-content.php +8 -6
  99. inc/views/{inpost → edit}/wrap-nav.php +5 -2
  100. inc/views/inpost/seo-settings-tt.php +0 -174
  101. inc/views/list/bulk-post.php +67 -0
  102. inc/views/list/index.php +8 -0
  103. inc/views/list/quick-post.php +81 -0
  104. inc/views/list/quick-term.php +81 -0
  105. inc/views/metaboxes/feed-metabox.php +0 -65
  106. inc/views/metaboxes/robots-metabox.php +0 -200
  107. inc/views/profile/author.php +1 -0
  108. inc/views/sitemap/xml-sitemap.php +61 -0
  109. inc/views/sitemap/xsl-stylesheet.php +70 -51
  110. inc/views/templates/inpost/primary-term-selector.php +5 -1
  111. language/autodescription.pot +1538 -1023
  112. language/index.php +6 -0
  113. lib/css/index.php +6 -0
  114. lib/css/le.css +30 -0
  115. lib/css/le.min.css +1 -0
  116. lib/css/post.css +202 -0
  117. lib/css/post.min.css +1 -0
  118. lib/css/settings.css +219 -0
  119. lib/css/settings.min.css +1 -0
  120. lib/css/term.css +60 -0
  121. lib/css/term.min.css +1 -0
  122. lib/css/tsf.css +83 -609
  123. lib/css/tsf.min.css +1 -1
  124. lib/css/tsf.rtl.css +0 -1006
  125. lib/css/tsf.rtl.min.css +0 -1
  126. lib/css/tsfc.css +143 -0
  127. lib/css/tsfc.min.css +1 -0
  128. lib/css/tt.css +24 -10
  129. lib/css/tt.min.css +1 -1
  130. lib/index.php +8 -0
  131. lib/js/ays.js +354 -0
  132. lib/js/ays.min.js +1 -0
  133. lib/js/c.js +402 -0
  134. lib/js/c.min.js +1 -0
  135. lib/js/description.js +424 -0
  136. lib/js/description.min.js +1 -0
  137. lib/js/{tsf-gbc.js → gbc.js} +135 -28
  138. lib/js/gbc.min.js +1 -0
  139. lib/js/gutenberg.js +0 -166
  140. lib/js/gutenberg.min.js +0 -1
  141. lib/js/index.php +8 -0
  142. lib/js/le.js +252 -0
  143. lib/js/le.min.js +1 -0
  144. lib/js/media.js +214 -119
  145. lib/js/media.min.js +1 -1
  146. lib/js/post.js +672 -0
  147. lib/js/post.min.js +1 -0
  148. lib/js/pt-gb.js +34 -22
  149. lib/js/pt-gb.min.js +1 -1
  150. lib/js/pt.js +41 -32
  151. lib/js/pt.min.js +1 -1
  152. lib/js/settings.js +779 -0
  153. lib/js/settings.min.js +1 -0
  154. lib/js/social.js +359 -0
  155. lib/js/social.min.js +1 -0
  156. lib/js/term.js +243 -0
  157. lib/js/term.min.js +1 -0
  158. lib/js/title.js +765 -0
  159. lib/js/title.min.js +1 -0
  160. lib/js/tsf-gbc.min.js +0 -1
  161. lib/js/tsf.js +252 -2546
  162. lib/js/tsf.min.js +1 -1
  163. lib/js/tt.js +199 -137
  164. lib/js/tt.min.js +1 -1
  165. readme.txt +163 -155
autodescription.php CHANGED
@@ -3,12 +3,14 @@
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.4
7
- * Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
10
* Text Domain: autodescription
11
* Domain Path: /language
12
*/
13
14
defined( 'ABSPATH' ) or die;
@@ -33,18 +35,27 @@ defined( 'ABSPATH' ) or die;
33
/**
34
* @NOTE This file MUST be written according to WordPress' minimum PHP requirements.
35
* Which is PHP 5.2.
36
*/
37
38
- //* Debug. Not to be used on production websites as it dumps and/or disables all kinds of stuff everywhere.
39
// add_action( 'plugins_loaded', function() { if ( is_super_admin() ) {
40
- // if ( is_admin() ) {
41
- // define( 'THE_SEO_FRAMEWORK_DEBUG', true );
42
- // define( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS', true );
43
- // delete_option( 'the_seo_framework_upgraded_db_version' );
44
- // delete_option( 'the_seo_framework_tested_upgrade_version' );
45
- // add_filter( 'the_seo_framework_use_object_cache', '__return_false' );
46
- // }
47
// }},0);
48
49
/**
50
* The plugin version.
@@ -53,7 +64,7 @@ defined( 'ABSPATH' ) or die;
53
*
54
* @since 2.3.5
55
*/
56
- define( 'THE_SEO_FRAMEWORK_VERSION', '3.2.4' );
57
58
/**
59
* The plugin Database version.
@@ -62,22 +73,25 @@ define( 'THE_SEO_FRAMEWORK_VERSION', '3.2.4' );
62
*
63
* @since 2.7.0
64
*/
65
- define( 'THE_SEO_FRAMEWORK_DB_VERSION', '3104' );
66
67
/**
68
* The plugin file, absolute unix path.
69
* @since 2.2.9
70
*/
71
define( 'THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE', __FILE__ );
72
73
/**
74
* The plugin's bootstrap folder location.
75
* @since 3.1.0
76
*/
77
define( 'THE_SEO_FRAMEWORK_BOOTSTRAP_PATH', dirname( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) . DIRECTORY_SEPARATOR . 'bootstrap' . DIRECTORY_SEPARATOR );
78
79
/**
80
* Checks whether to start plugin or test the server environment first.
81
* @since 2.8.0
82
*/
83
if ( get_option( 'the_seo_framework_tested_upgrade_version' ) < THE_SEO_FRAMEWORK_DB_VERSION ) {
@@ -90,43 +104,26 @@ if ( get_option( 'the_seo_framework_tested_upgrade_version' ) < THE_SEO_FRAMEWOR
90
}
91
92
/**
93
- * Starts the plugin.
94
*
95
* @since 3.1.0
96
* @access private
97
*/
98
function the_seo_framework_boot() {
99
100
- /**
101
- * Defines environental constants.
102
- * @since 3.1.0
103
- */
104
require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'define.php';
105
106
- /**
107
- * Load plugin API functions.
108
- * @since 3.1.0
109
- */
110
require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'api.php';
111
112
- /**
113
- * Prepare plugin upgrader before the plugin loads.
114
- * @since 3.1.0
115
- * @since 3.1.2 Now performs a weak check.
116
- */
117
- if ( the_seo_framework_db_version() != THE_SEO_FRAMEWORK_DB_VERSION ) { // loose comparison OK.
118
- require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'upgrade.php';
119
- }
120
-
121
- /**
122
- * Load deprecated functions.
123
- * @since 3.1.0
124
- */
125
require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'deprecated.php';
126
127
- /**
128
- * Load plugin.
129
- * @since 3.1.0
130
- */
131
require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'load.php';
132
}
3
* Plugin Name: The SEO Framework
4
* Plugin URI: https://theseoframework.com/
5
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
6
+ * Version: 4.0.2
7
+ * Author: The SEO Framework Team
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
10
* Text Domain: autodescription
11
* Domain Path: /language
12
+ *
13
+ * @package The_SEO_Framework\Bootstrap
14
*/
15
16
defined( 'ABSPATH' ) or die;
35
/**
36
* @NOTE This file MUST be written according to WordPress' minimum PHP requirements.
37
* Which is PHP 5.2.
38
+ * When we only support WordPress 5.2+, it'll be PHP 5.6.
39
+ * When we only support WordPress 5.4?+, it'll be PHP 7.1.
40
*/
41
42
+ // phpcs:disable, Squiz.Commenting.InlineComment, Squiz.PHP.CommentedOutCode
43
+ //
44
+ // Debug: Not to be used on production websites as it dumps and/or disables all kinds of stuff everywhere.
45
+ //
46
// add_action( 'plugins_loaded', function() { if ( is_super_admin() ) {
47
+ // if ( is_admin() ) {
48
+ // define( 'THE_SEO_FRAMEWORK_DEBUG', true );
49
+ // define( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS', true );
50
+ // delete_option( 'the_seo_framework_upgraded_db_version' );
51
+ // ( $_GET['reset_tsf_upgrade'] ?? 0 ) and delete_option( 'the_seo_framework_upgraded_db_version' ) and delete_option( 'the_seo_framework_initial_db_version' );
52
+ // ( $_GET['downgrade_tsf'] ?? 0 ) and update_option( 'the_seo_framework_upgraded_db_version', (string) (int) $_GET['downgrade_tsf'] );
53
+ // ( $_GET['downgrade_tsf_initial'] ?? 0 ) and update_option( 'the_seo_framework_initial_db_version', (string) (int) $_GET['downgrade_tsf_initial'] );
54
+ // ( $_GET['reset_tsf_tested'] ?? 0 ) and delete_option( 'the_seo_framework_tested_upgrade_version' );
55
+ // add_filter( 'the_seo_framework_use_object_cache', '__return_false' );
56
+ // }
57
// }},0);
58
+ // phpcs:enable, Squiz.Commenting.InlineComment, Squiz.PHP.CommentedOutCode
59
60
/**
61
* The plugin version.
64
*
65
* @since 2.3.5
66
*/
67
+ define( 'THE_SEO_FRAMEWORK_VERSION', '4.0.2' );
68
69
/**
70
* The plugin Database version.
73
*
74
* @since 2.7.0
75
*/
76
+ define( 'THE_SEO_FRAMEWORK_DB_VERSION', '4000' );
77
78
/**
79
* The plugin file, absolute unix path.
80
+ *
81
* @since 2.2.9
82
*/
83
define( 'THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE', __FILE__ );
84
85
/**
86
* The plugin's bootstrap folder location.
87
+ *
88
* @since 3.1.0
89
*/
90
define( 'THE_SEO_FRAMEWORK_BOOTSTRAP_PATH', dirname( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) . DIRECTORY_SEPARATOR . 'bootstrap' . DIRECTORY_SEPARATOR );
91
92
/**
93
* Checks whether to start plugin or test the server environment first.
94
+ *
95
* @since 2.8.0
96
*/
97
if ( get_option( 'the_seo_framework_tested_upgrade_version' ) < THE_SEO_FRAMEWORK_DB_VERSION ) {
104
}
105
106
/**
107
+ * Starts the plugin, loads files outside of the global scope.
108
*
109
* @since 3.1.0
110
* @access private
111
*/
112
function the_seo_framework_boot() {
113
114
+ // Defines environental constants.
115
require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'define.php';
116
117
+ // Load plugin API functions.
118
require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'api.php';
119
120
+ // Prepare plugin upgrader before the plugin loads.
121
+ the_seo_framework_db_version() !== THE_SEO_FRAMEWORK_DB_VERSION
122
+ and require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'upgrade.php';
123
+
124
+ // Load deprecated functions.
125
require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'deprecated.php';
126
127
+ // Load plugin.
128
require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'load.php';
129
}
bootstrap/activation.php CHANGED
@@ -1,8 +1,8 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- * @subpackage Bootstrap
5
*/
6
namespace The_SEO_Framework\Bootstrap;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
@@ -29,7 +29,6 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
29
*/
30
31
//! @php7+ convert to IIFE
32
- _activation_setup_sitemap();
33
_activation_set_options_autoload();
34
_activation_set_plugin_check_caches();
35
@@ -50,26 +49,6 @@ function _activation_set_plugin_check_caches() {
50
}
51
}
52
53
- /**
54
- * Add and Flush rewrite rules on plugin activation.
55
- *
56
- * @since 2.6.6
57
- * @since 2.7.1: 1. Now no longer reinitializes global $wp_rewrite.
58
- * 2. Now always listens to the preconditions of the sitemap addition.
59
- * 3. Now flushes the rules on shutdown.
60
- * @since 2.8.0: Added namespace and renamed function.
61
- * @access private
62
- */
63
- function _activation_setup_sitemap() {
64
-
65
- $tsf = \the_seo_framework();
66
-
67
- if ( $tsf->loaded ) {
68
- $tsf->rewrite_rule_sitemap();
69
- \add_action( 'shutdown', 'flush_rewrite_rules' );
70
- }
71
- }
72
-
73
/**
74
* Turns on auto loading for The SEO Framework's main options.
75
*
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Bootstrap\Install
4
*/
5
+
6
namespace The_SEO_Framework\Bootstrap;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
29
*/
30
31
//! @php7+ convert to IIFE
32
_activation_set_options_autoload();
33
_activation_set_plugin_check_caches();
34
49
}
50
}
51
52
/**
53
* Turns on auto loading for The SEO Framework's main options.
54
*
bootstrap/deactivation.php CHANGED
@@ -1,8 +1,8 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- * @subpackage Bootstrap
5
*/
6
namespace The_SEO_Framework\Bootstrap;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
@@ -30,25 +30,6 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
30
31
//! @php7+ convert to IIFE
32
_deactivation_unset_options_autoload();
33
- _deactivation_unset_sitemap();
34
-
35
- /**
36
- * Flush rewrite rules on plugin deactivation.
37
- *
38
- * @since 2.6.6
39
- * @since 2.7.1: 1. Now no longer reinitializes global $wp_rewrite.
40
- * 2. Now flushes the rules on shutdown.
41
- * @since 2.8.0: Added namespace and renamed function.
42
- * @access private
43
- * @global \WP_Rewrite $wp_rewrite
44
- */
45
- function _deactivation_unset_sitemap() {
46
-
47
- unset( $GLOBALS['wp_rewrite']->extra_rules_top['sitemap\.xml#x27;] );
48
- unset( $GLOBALS['wp_rewrite']->extra_rules_top['sitemap\.xsl#x27;] );
49
-
50
- \add_action( 'shutdown', 'flush_rewrite_rules' );
51
- }
52
53
/**
54
* Turns off autoloading for The SEO Framework main options.
1
<?php
2
/**
3
+ * @package The_SEO_Framework/Bootstrap\Install
4
*/
5
+
6
namespace The_SEO_Framework\Bootstrap;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
30
31
//! @php7+ convert to IIFE
32
_deactivation_unset_options_autoload();
33
34
/**
35
* Turns off autoloading for The SEO Framework main options.
bootstrap/define.php CHANGED
@@ -1,10 +1,10 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- * @subpackage Bootstrap
5
- * No need to annotate namespacing here... there are only plain PHP queries.
6
*/
7
8
defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
9
10
/**
@@ -26,6 +26,7 @@ defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
26
27
/**
28
* Tells the world the plugin is present and to be used.
29
* @since 3.1.0
30
*/
31
define( 'THE_SEO_FRAMEWORK_PRESENT', true );
@@ -38,91 +39,118 @@ define( 'THE_SEO_FRAMEWORK_PRESENT', true );
38
* @since 2.2.2
39
* @param string THE_SEO_FRAMEWORK_SITE_OPTIONS
40
*/
41
- define( 'THE_SEO_FRAMEWORK_SITE_OPTIONS', (string) apply_filters( 'the_seo_framework_site_options', 'autodescription-site-settings' ) );
42
43
/**
44
* The plugin network options.
45
*
46
- * Unused in the code.
47
*
48
* @since 2.2.2
49
* @param string THE_SEO_FRAMEWORK_NETWORK_OPTIONS
50
*/
51
- define( 'THE_SEO_FRAMEWORK_NETWORK_OPTIONS', (string) apply_filters( 'the_seo_framework_network_settings', 'autodescription-network-settings' ) );
52
53
/**
54
* Plugin term options key.
55
* @since 2.7.0
56
* @param string THE_SEO_FRAMEWORK_TERM_OPTIONS
57
*/
58
- define( 'THE_SEO_FRAMEWORK_TERM_OPTIONS', (string) apply_filters( 'the_seo_framework_term_options', 'autodescription-term-settings' ) );
59
60
/**
61
* Plugin user term options key.
62
* @since 2.7.0
63
* @param string THE_SEO_FRAMEWORK_USER_OPTIONS
64
*/
65
- define( 'THE_SEO_FRAMEWORK_USER_OPTIONS', (string) apply_filters( 'the_seo_framework_user_options', 'autodescription-user-settings' ) );
66
67
/**
68
* Plugin updates cache key.
69
* @since 3.1.0
70
* @param string THE_SEO_FRAMEWORK_SITE_CACHE
71
*/
72
- define( 'THE_SEO_FRAMEWORK_SITE_CACHE', (string) apply_filters( 'the_seo_framework_site_cache', 'autodescription-updates-cache' ) );
73
74
/**
75
- * The plugin map URL. Has a trailing slash.
76
* Used for calling browser files.
77
* @since 2.2.2
78
*/
79
- define( 'THE_SEO_FRAMEWORK_DIR_URL', plugin_dir_url( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) );
80
81
/**
82
* The plugin file relative to the plugins dir. Does not have a trailing slash.
83
* @since 2.2.8
84
*/
85
- define( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME', plugin_basename( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) );
86
87
/**
88
- * The plugin map absolute path.
89
- * Used for calling php files.
90
* @since 2.2.2
91
*/
92
define( 'THE_SEO_FRAMEWORK_DIR_PATH', dirname( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) . DIRECTORY_SEPARATOR );
93
94
/**
95
- * The plugin views map absolute path.
96
* @since 2.7.0
97
*/
98
define( 'THE_SEO_FRAMEWORK_DIR_PATH_VIEWS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR );
99
100
/**
101
- * The plugin class map absolute path.
102
* @since 2.2.9
103
*/
104
define( 'THE_SEO_FRAMEWORK_DIR_PATH_CLASS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR );
105
106
/**
107
- * The plugin trait map absolute path.
108
* @since 3.1.0
109
*/
110
define( 'THE_SEO_FRAMEWORK_DIR_PATH_TRAIT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'traits' . DIRECTORY_SEPARATOR );
111
112
/**
113
- * The plugin interface map absolute path.
114
* @since 2.8.0
115
*/
116
define( 'THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'interfaces' . DIRECTORY_SEPARATOR );
117
118
/**
119
- * The plugin function map absolute path.
120
* @since 2.2.9
121
*/
122
define( 'THE_SEO_FRAMEWORK_DIR_PATH_FUNCT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR );
123
124
/**
125
- * The plugin function map absolute path.
126
* @since 2.8.0
127
*/
128
define( 'THE_SEO_FRAMEWORK_DIR_PATH_COMPAT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'compat' . DIRECTORY_SEPARATOR );
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Bootstrap
4
*/
5
6
+ namespace The_SEO_Framework;
7
+
8
defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
9
10
/**
26
27
/**
28
* Tells the world the plugin is present and to be used.
29
+ *
30
* @since 3.1.0
31
*/
32
define( 'THE_SEO_FRAMEWORK_PRESENT', true );
39
* @since 2.2.2
40
* @param string THE_SEO_FRAMEWORK_SITE_OPTIONS
41
*/
42
+ define( 'THE_SEO_FRAMEWORK_SITE_OPTIONS', (string) \apply_filters( 'the_seo_framework_site_options', 'autodescription-site-settings' ) );
43
44
/**
45
* The plugin network options.
46
*
47
+ * Unused in our code.
48
*
49
* @since 2.2.2
50
* @param string THE_SEO_FRAMEWORK_NETWORK_OPTIONS
51
*/
52
+ define( 'THE_SEO_FRAMEWORK_NETWORK_OPTIONS', (string) \apply_filters( 'the_seo_framework_network_settings', 'autodescription-network-settings' ) );
53
54
/**
55
* Plugin term options key.
56
+ *
57
* @since 2.7.0
58
* @param string THE_SEO_FRAMEWORK_TERM_OPTIONS
59
*/
60
+ define( 'THE_SEO_FRAMEWORK_TERM_OPTIONS', (string) \apply_filters( 'the_seo_framework_term_options', 'autodescription-term-settings' ) );
61
62
/**
63
* Plugin user term options key.
64
+ *
65
* @since 2.7.0
66
* @param string THE_SEO_FRAMEWORK_USER_OPTIONS
67
*/
68
+ define( 'THE_SEO_FRAMEWORK_USER_OPTIONS', (string) \apply_filters( 'the_seo_framework_user_options', 'autodescription-user-settings' ) );
69
70
/**
71
* Plugin updates cache key.
72
+ *
73
* @since 3.1.0
74
* @param string THE_SEO_FRAMEWORK_SITE_CACHE
75
*/
76
+ define( 'THE_SEO_FRAMEWORK_SITE_CACHE', (string) \apply_filters( 'the_seo_framework_site_cache', 'autodescription-updates-cache' ) );
77
78
/**
79
+ * The plugin folder URL. Has a trailing slash.
80
* Used for calling browser files.
81
+ *
82
* @since 2.2.2
83
*/
84
+ define( 'THE_SEO_FRAMEWORK_DIR_URL', \plugin_dir_url( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) );
85
86
/**
87
* The plugin file relative to the plugins dir. Does not have a trailing slash.
88
+ *
89
* @since 2.2.8
90
*/
91
+ define( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME', \plugin_basename( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) );
92
93
/**
94
+ * The plugin folder absolute path. Used for calling php files.
95
+ *
96
* @since 2.2.2
97
*/
98
define( 'THE_SEO_FRAMEWORK_DIR_PATH', dirname( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) . DIRECTORY_SEPARATOR );
99
100
/**
101
+ * The plugin views folder absolute path.
102
+ *
103
* @since 2.7.0
104
*/
105
define( 'THE_SEO_FRAMEWORK_DIR_PATH_VIEWS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR );
106
107
/**
108
+ * The plugin class folder absolute path.
109
+ *
110
* @since 2.2.9
111
*/
112
define( 'THE_SEO_FRAMEWORK_DIR_PATH_CLASS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR );
113
114
/**
115
+ * The plugin trait folder absolute path.
116
+ *
117
* @since 3.1.0
118
*/
119
define( 'THE_SEO_FRAMEWORK_DIR_PATH_TRAIT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'traits' . DIRECTORY_SEPARATOR );
120
121
/**
122
+ * The plugin interface folder absolute path.
123
+ *
124
* @since 2.8.0
125
*/
126
define( 'THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'interfaces' . DIRECTORY_SEPARATOR );
127
128
/**
129
+ * The plugin function folder absolute path.
130
+ *
131
* @since 2.2.9
132
*/
133
define( 'THE_SEO_FRAMEWORK_DIR_PATH_FUNCT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR );
134
135
/**
136
+ * The plugin compatibility folder absolute path.
137
+ *
138
* @since 2.8.0
139
*/
140
define( 'THE_SEO_FRAMEWORK_DIR_PATH_COMPAT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'compat' . DIRECTORY_SEPARATOR );
141
+
142
+ /**
143
+ * Robots setting, ignore protection.
144
+ *
145
+ * @since 4.0.0
146
+ * @see \The_SEO_Framework\Generate\robots_meta()
147
+ */
148
+ const ROBOTS_IGNORE_PROTECTION = 0b01;
149
+
150
+ /**
151
+ * Robots setting, ignore settings.
152
+ *
153
+ * @since 4.0.0
154
+ * @see \The_SEO_Framework\Generate\robots_meta()
155
+ */
156
+ const ROBOTS_IGNORE_SETTINGS = 0b10;
bootstrap/envtest.php CHANGED
@@ -1,10 +1,11 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- * @subpackage Bootstrap
5
*
6
* @NOTE This file MUST be written according to WordPress' minimum PHP requirements.
7
* Which is PHP 5.2.
8
*/
9
10
defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
@@ -69,15 +70,15 @@ function the_seo_framework_pre_boot_test() {
69
}
70
71
$requirements = array(
72
- 'php' => '50400',
73
'wp' => '37965',
74
);
75
76
- // phpcs:disable Generic.Formatting.MultipleStatementAlignment.NotSameWarning
77
- ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $requirements['php'] and $test = 1 // precision alignment ok.
78
or $GLOBALS['wp_db_version'] < $requirements['wp'] and $test = 2
79
or $test = true;
80
- // phpcs:enable Generic.Formatting.MultipleStatementAlignment.NotSameWarning
81
82
//* All good.
83
if ( true === $test ) {
@@ -108,7 +109,7 @@ function the_seo_framework_pre_boot_test() {
108
switch ( $test ) :
109
case 1:
110
//* PHP requirements not met, always count up to encourage best standards.
111
- $requirement = 'PHP 5.4.0 or later';
112
$issue = 'PHP version';
113
$version = PHP_VERSION;
114
$subtitle = 'Server Requirements';
@@ -116,7 +117,7 @@ function the_seo_framework_pre_boot_test() {
116
117
case 2:
118
//* WordPress requirements not met.
119
- $requirement = 'WordPress 4.6 or later';
120
$issue = 'WordPress version';
121
$version = $GLOBALS['wp_version'];
122
$subtitle = 'WordPress Requirements';
@@ -137,9 +138,12 @@ function the_seo_framework_pre_boot_test() {
137
sprintf(
138
'<p><strong>The SEO Framework</strong> requires <em>%s</em>. Sorry about that!<br>Your %s is: <code>%s</code></p>
139
<p>Do you want to <strong><a onclick="window.history.back()" href="%s">go back</a></strong>?</p>',
140
- esc_html( $requirement ), esc_html( $issue ), esc_html( $version ), esc_url( $pluginspage )
141
),
142
- sprintf( 'The SEO Framework &laquo; %s', esc_attr( $subtitle ) ),
143
array( 'response' => intval( $response ) )
144
);
145
}
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Bootstrap\Install
4
*
5
* @NOTE This file MUST be written according to WordPress' minimum PHP requirements.
6
* Which is PHP 5.2.
7
+ * When we only support WordPress 5.2+, it'll be PHP 5.6.
8
+ * When we only support WordPress 5.4?+, it'll be PHP 7.1.
9
*/
10
11
defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
70
}
71
72
$requirements = array(
73
+ 'php' => '50600',
74
'wp' => '37965',
75
);
76
77
+ // phpcs:disable, Generic.Formatting.MultipleStatementAlignment, WordPress.WhiteSpace.PrecisionAlignment
78
+ ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $requirements['php'] and $test = 1
79
or $GLOBALS['wp_db_version'] < $requirements['wp'] and $test = 2
80
or $test = true;
81
+ // phpcs:enable, Generic.Formatting.MultipleStatementAlignment, WordPress.WhiteSpace.PrecisionAlignment
82
83
//* All good.
84
if ( true === $test ) {
109
switch ( $test ) :
110
case 1:
111
//* PHP requirements not met, always count up to encourage best standards.
112
+ $requirement = 'PHP 5.5.0 or later';
113
$issue = 'PHP version';
114
$version = PHP_VERSION;
115
$subtitle = 'Server Requirements';
117
118
case 2:
119
//* WordPress requirements not met.
120
+ $requirement = 'WordPress 4.9 or later';
121
$issue = 'WordPress version';
122
$version = $GLOBALS['wp_version'];
123
$subtitle = 'WordPress Requirements';
138
sprintf(
139
'<p><strong>The SEO Framework</strong> requires <em>%s</em>. Sorry about that!<br>Your %s is: <code>%s</code></p>
140
<p>Do you want to <strong><a onclick="window.history.back()" href="%s">go back</a></strong>?</p>',
141
+ esc_html( $requirement ),
142
+ esc_html( $issue ),
143
+ esc_html( $version ),
144
+ esc_url( $pluginspage )
145
),
146
+ esc_attr( sprintf( 'The SEO Framework &laquo; %s', $subtitle ) ),
147
array( 'response' => intval( $response ) )
148
);
149
}
bootstrap/load.php CHANGED
@@ -1,10 +1,8 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- * @subpackage Bootstrap
5
- * @TODO change namespace to The_SEO_Framework\Bootstrap
6
- * in a future major release.
7
*/
8
namespace The_SEO_Framework;
9
10
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
@@ -28,9 +26,11 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
28
29
\add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_locale', 4 );
30
/**
31
- * Plugin locale 'autodescription'
32
* Files located in plugin folder `../autodescription/language/`
33
* @since 2.8.0
34
*/
35
function _init_locale() {
36
/**
@@ -39,10 +39,18 @@ function _init_locale() {
39
\load_plugin_textdomain(
40
'autodescription',
41
false,
42
- THE_SEO_FRAMEWORK_DIR_PATH . 'language'
43
);
44
}
45
46
\add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_tsf', 5 );
47
/**
48
* Load The_SEO_Framework_Load class
@@ -72,23 +80,27 @@ function _init_tsf() {
72
*/
73
if ( \The_SEO_Framework\_can_load() ) {
74
if ( \is_admin() ) {
75
- //! TODO: admin-only loader.
76
$tsf = new \The_SEO_Framework\Load();
77
$tsf->loaded = true;
78
79
/**
80
- * Runs after TSF is loaded in the admin.
81
* @since 3.1.0
82
*/
83
\do_action( 'the_seo_framework_admin_loaded' );
84
} else {
85
$tsf = new \The_SEO_Framework\Load();
86
$tsf->loaded = true;
87
}
88
89
/**
90
- * Runs after TSF is loaded.
91
* @since 3.1.0
92
*/
93
\do_action( 'the_seo_framework_loaded' );
94
} else {
@@ -97,7 +109,7 @@ function _init_tsf() {
97
}
98
99
// did_action() checks for current action too.
100
- if ( false === \did_action( 'plugins_loaded' ) )
101
$tsf->_doing_it_wrong( 'the_seo_framework() or ' . __FUNCTION__, 'Use <code>the_seo_framework()</code> after action <code>plugins_loaded</code> priority 5.', '3.1' );
102
103
return $tsf;
@@ -109,43 +121,53 @@ spl_autoload_register( __NAMESPACE__ . '\\_autoload_classes', true, true );
109
* the plugin classes.
110
*
111
* @since 2.8.0
112
- * @since 3.1.0 1. No longer maintains cache.
113
- * 2. Now always returns void.
114
* @uses THE_SEO_FRAMEWORK_DIR_PATH_CLASS
115
* @access private
116
*
117
* @NOTE 'The_SEO_Framework\' is a reserved namespace. Using it outside of this
118
- * plugin's scope coul result in an error.
119
*
120
* @param string $class The class name.
121
* @return void Early if the class is not within the current namespace.
122
*/
123
function _autoload_classes( $class ) {
124
125
- if ( 0 !== strpos( $class, 'The_SEO_Framework\\', 0 ) )
126
- return;
127
-
128
- $strip = 'The_SEO_Framework\\';
129
130
- if ( strpos( $class, '_Interface' ) ) {
131
- $path = THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE;
132
- $extension = '.interface.php';
133
- $class = str_replace( '_Interface', '', $class );
134
} else {
135
- $path = THE_SEO_FRAMEWORK_DIR_PATH_CLASS;
136
- $extension = '.class.php';
137
138
- //: substr_count( $class, '\\', 2 ) >= 2 // strrpos... str_split...
139
- if ( 0 === strpos( $class, 'The_SEO_Framework\\Builders\\' ) ) {
140
- $path .= 'builders' . DIRECTORY_SEPARATOR;
141
- $strip .= 'Builders\\';
142
- }
143
}
144
145
- $class = strtolower( str_replace( $strip, '', $class ) );
146
- $class = str_replace( '_', '-', $class );
147
148
- require $path . $class . $extension;
149
}
150
151
\add_action( 'activate_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, __NAMESPACE__ . '\\_do_plugin_activation' );
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Bootstrap
4
*/
5
+
6
namespace The_SEO_Framework;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
26
27
\add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_locale', 4 );
28
/**
29
+ * Loads plugin locale 'autodescription'.
30
* Files located in plugin folder `../autodescription/language/`
31
+ *
32
* @since 2.8.0
33
+ * @since 4.0.2 Now points to the correct plugin folder for fallback MO-file loading (which was never used).
34
*/
35
function _init_locale() {
36
/**
39
\load_plugin_textdomain(
40
'autodescription',
41
false,
42
+ dirname( THE_SEO_FRAMEWORK_PLUGIN_BASENAME ) . DIRECTORY_SEPARATOR . 'language'
43
);
44
}
45
46
+ /**
47
+ * Loads base overloading trait-collection.
48
+ *
49
+ * For now, other traits must be loaded via this function.
50
+ * However, we might deprecate this method in favor of an autoloader.
51
+ */
52
+ _load_trait( 'core/overload' );
53
+
54
\add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_tsf', 5 );
55
/**
56
* Load The_SEO_Framework_Load class
80
*/
81
if ( \The_SEO_Framework\_can_load() ) {
82
if ( \is_admin() ) {
83
+ //! TODO: admin-only loader?
84
$tsf = new \The_SEO_Framework\Load();
85
$tsf->loaded = true;
86
87
+ $tsf->_load_early_compat_files();
88
+
89
/**
90
* @since 3.1.0
91
+ * Runs after TSF is loaded in the admin.
92
*/
93
\do_action( 'the_seo_framework_admin_loaded' );
94
} else {
95
$tsf = new \The_SEO_Framework\Load();
96
$tsf->loaded = true;
97
+
98
+ $tsf->_load_early_compat_files();
99
}
100
101
/**
102
* @since 3.1.0
103
+ * Runs after TSF is loaded.
104
*/
105
\do_action( 'the_seo_framework_loaded' );
106
} else {
109
}
110
111
// did_action() checks for current action too.
112
+ if ( ! \did_action( 'plugins_loaded' ) )
113
$tsf->_doing_it_wrong( 'the_seo_framework() or ' . __FUNCTION__, 'Use <code>the_seo_framework()</code> after action <code>plugins_loaded</code> priority 5.', '3.1' );
114
115
return $tsf;
121
* the plugin classes.
122
*
123
* @since 2.8.0
124
+ * @since 3.1.0 : 1. No longer maintains cache.
125
+ * 2. Now always returns void.
126
+ * @since 4.0.0 : 1. Streamlined folder lookup by more effectively using the namespace.
127
+ * 2. Added timing functionality
128
+ * 3. No longer loads interfaces automatically.
129
* @uses THE_SEO_FRAMEWORK_DIR_PATH_CLASS
130
* @access private
131
+ * @staticvar bool $_timenow Whether to time this request. Used to prevent stacking timers during class extending.
132
*
133
* @NOTE 'The_SEO_Framework\' is a reserved namespace. Using it outside of this
134
+ * plugin's scope could result in an error.
135
*
136
* @param string $class The class name.
137
* @return void Early if the class is not within the current namespace.
138
*/
139
function _autoload_classes( $class ) {
140
141
+ if ( 0 !== strpos( $class, 'The_SEO_Framework\\', 0 ) ) return;
142
143
+ static $_timenow = true;
144
+ if ( $_timenow ) {
145
+ $_bootstrap_timer = microtime( true );
146
+ $_timenow = false;
147
} else {
148
+ $_bootstrap_timer = 0;
149
+ }
150
151
+ $_chunks = explode( '\\', strtolower( $class ) );
152
+ $_chunck_count = count( $_chunks );
153
+
154
+ if ( $_chunck_count > 2 ) {
155
+ //? directory position = $_chunck_count - ( 2 = (The_SEO_Framework)\ + (Bridges/Builders/Interpreters)\ )
156
+ $rel_dir = implode( DIRECTORY_SEPARATOR, array_splice( $_chunks, 1, $_chunck_count - 2 ) ) . DIRECTORY_SEPARATOR;
157
+ } else {
158
+ $rel_dir = '';
159
}
160
161
+ // The last part of the chunks is the class name--which corresponds to the file.
162
+ $file = str_replace( '_', '-', end( $_chunks ) );
163
164
+ // The extension is deemed to be ".class.php" always. We may wish to alter this for traits?
165
+ require THE_SEO_FRAMEWORK_DIR_PATH_CLASS . $rel_dir . $file . '.class.php';
166
+
167
+ if ( $_bootstrap_timer ) {
168
+ _bootstrap_timer( microtime( true ) - $_bootstrap_timer );
169
+ $_timenow = true;
170
+ }
171
}
172
173
\add_action( 'activate_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, __NAMESPACE__ . '\\_do_plugin_activation' );
bootstrap/upgrade.php CHANGED
@@ -1,8 +1,8 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- * @subpackage Bootstrapp
5
*/
6
namespace The_SEO_Framework\Bootstrap;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
@@ -85,6 +85,11 @@ function _previous_db_version() {
85
* 8. Now tries to increase memory limit. This probably isn't needed.
86
* 9. Now runs on the front-end, too, via `init`, instead of `admin_init`.
87
* @since 3.1.4 Now flushes object cache before the upgrade settings are called.
88
*/
89
function _do_upgrade() {
90
@@ -92,20 +97,34 @@ function _do_upgrade() {
92
93
if ( ! $tsf->loaded ) return;
94
95
if ( $tsf->is_seo_settings_page( false ) ) {
96
- \wp_redirect( \self_admin_url() ); // phpcs:ignore -- self_admin_url() is safe.
97
exit;
98
}
99
100
\wp_raise_memory_limit( 'tsf_upgrade' );
101
102
/**
103
- * From WordPress' .../update-core.php
104
* @since 3.1.4
105
*/
106
- // Clear the cache to prevent an update_option() from saving a stale database version to the cache
107
\wp_cache_flush();
108
- // (Not all cache back ends listen to 'flush')
109
\wp_cache_delete( 'alloptions', 'options' );
110
111
$version = _previous_db_version();
@@ -147,17 +166,35 @@ function _do_upgrade() {
147
148
//! From here, the upgrade procedures should be backward compatible.
149
//? This means no data may be erased for at least 1 major version, or 1 year, whichever is later.
150
if ( $version < '3103' ) {
151
_do_upgrade_3103();
152
$version = '3103';
153
}
154
155
/**
156
* @since 2.7.0
157
*/
158
\do_action( 'the_seo_framework_upgraded' );
159
}
160
161
\add_action( 'the_seo_framework_upgraded', __NAMESPACE__ . '\\_upgrade_to_current' );
162
/**
163
* Upgrades the Database version to the latest version.
@@ -174,26 +211,73 @@ function _upgrade_to_current() {
174
\update_option( 'the_seo_framework_upgraded_db_version', THE_SEO_FRAMEWORK_DB_VERSION );
175
176
/**
177
- * From WordPress' .../update-core.php
178
* @since 3.1.4
179
*/
180
- // Clear the cache to prevent a get_option() from retrieving a stale database version to the cache
181
\wp_cache_flush();
182
- // (Not all cache back ends listen to 'flush')
183
\wp_cache_delete( 'alloptions', 'options' );
184
}
185
186
- \add_action( 'the_seo_framework_upgraded', __NAMESPACE__ . '\\_upgrade_reinitialize_rewrite', 99 );
187
/**
188
- * Reinitializes the rewrite cache.
189
*
190
- * This happens after the plugin's upgraded, because it's not critical, and when
191
- * this fails, the upgrader won't be locked.
192
*
193
- * @since 3.1.2
194
*/
195
- function _upgrade_reinitialize_rewrite() {
196
- \the_seo_framework()->reinitialize_rewrite();
197
}
198
199
\add_action( 'the_seo_framework_upgraded', __NAMESPACE__ . '\\_prepare_upgrade_suggestion', 100 );
@@ -208,17 +292,22 @@ function _upgrade_reinitialize_rewrite() {
208
* @return void Early when already enqueued
209
*/
210
function _prepare_upgrade_suggestion() {
211
- static $run = false;
212
- if ( $run ) return;
213
-
214
- if ( \is_admin() ) {
215
- \add_action( 'admin_init', function() {
216
- if ( ! _previous_db_version() ) return;
217
- require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'upgrade-suggestion.php';
218
- }, 20 );
219
- }
220
221
- $run = true;
222
}
223
224
/**
@@ -228,7 +317,7 @@ function _prepare_upgrade_suggestion() {
228
* @staticvar array $cache The cached notice strings.
229
*
230
* @param string $notice The upgrade notice.
231
- * @param bool $get Whether to return the upgrade notices.
232
* @return array|void The notices when $get is true.
233
*/
234
function _add_upgrade_notice( $notice = '', $get = false ) {
@@ -285,7 +374,7 @@ function _do_upgrade_2701() {
285
\add_term_meta( $term_id, THE_SEO_FRAMEWORK_TERM_OPTIONS, $meta, true );
286
}
287
288
- //= Rudimentary test for remaining ~300 users of the past passed, set initial version to 2600.
289
\update_option( 'the_seo_framework_initial_db_version', '2600', 'no' );
290
}
291
@@ -294,7 +383,6 @@ function _do_upgrade_2701() {
294
295
/**
296
* Removes term metadata for version 2802.
297
- * Reinitializes rewrite data for for sitemap stylesheet.
298
*
299
* @since 2.8.0
300
*/
@@ -394,8 +482,6 @@ function _do_upgrade_3060() {
394
* Migrates `attachment_nofollow` option to post type settings.
395
* Migrates `attachment_noarchive` option to post type settings.
396
*
397
- * Loads suggestion for TSFEM.
398
- *
399
* @since 3.1.0
400
*/
401
function _do_upgrade_3103() {
@@ -411,14 +497,14 @@ function _do_upgrade_3103() {
411
412
// Transport title separator.
413
if ( isset( $defaults['title_separator'] ) )
414
- $tsf->update_option( 'title_separator', $tsf->get_option( 'title_seperator' ) ?: $defaults['title_separator'] );
415
416
// Transport attachment_noindex, attachment_nofollow, and attachment_noarchive settings.
417
foreach ( [ 'noindex', 'nofollow', 'noarchive' ] as $r ) {
418
$_option = $tsf->get_robots_post_type_option_id( $r );
419
if ( isset( $defaults[ $_option ] ) ) {
420
- $_value = (array) ( $tsf->get_option( $_option ) ?: $defaults[ $_option ] );
421
- $_value['attachment'] = (int) (bool) $tsf->get_option( "attachment_$r" );
422
$tsf->update_option( $_option, $_value );
423
}
424
}
@@ -442,3 +528,61 @@ function _do_upgrade_3103() {
442
443
\update_option( 'the_seo_framework_upgraded_db_version', '3103' );
444
}
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Bootstrap\Install
4
*/
5
+
6
namespace The_SEO_Framework\Bootstrap;
7
8
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
85
* 8. Now tries to increase memory limit. This probably isn't needed.
86
* 9. Now runs on the front-end, too, via `init`, instead of `admin_init`.
87
* @since 3.1.4 Now flushes object cache before the upgrade settings are called.
88
+ * @since 4.0.0 1. Removed rewrite flushing; unless upgrading from <3300 to 3300
89
+ * 2. Added time limit.
90
+ * 3. No longer runs during AJAX.
91
+ * 4. Added an upgrading lock. Preventing upgrades running simultaneously.
92
+ * While this lock is active, the SEO Settings can't be accessed, either.
93
*/
94
function _do_upgrade() {
95
97
98
if ( ! $tsf->loaded ) return;
99
100
+ if ( \wp_doing_ajax() ) return;
101
+
102
if ( $tsf->is_seo_settings_page( false ) ) {
103
+ // phpcs:ignore, WordPress.Security.SafeRedirect -- self_admin_url() is safe.
104
+ \wp_redirect( \self_admin_url() );
105
exit;
106
}
107
108
+ // Check if upgrade is locked. Otherwise, lock it.
109
+ if ( \get_transient( 'tsf_upgrade_lock' ) ) return;
110
+ \set_transient( 'tsf_upgrade_lock', true, 300 );
111
+
112
+ // Register this AFTER the transient is set. Otherwise, it may clear the transient in another thread.
113
+ register_shutdown_function( __NAMESPACE__ . '\\_release_upgrade_lock' );
114
+
115
\wp_raise_memory_limit( 'tsf_upgrade' );
116
117
+ // phpcs:ignore, WordPress.PHP.NoSilencedErrors -- Feature may be disabled.
118
+ @set_time_limit( 300 );
119
+
120
/**
121
+ * Clear the cache to prevent an update_option() from saving a stale database version to the cache.
122
+ * Not all caching plugins recognize 'flush', so delete the options cache too, just to be safe.
123
+ *
124
+ * @see WordPress' `.../update-core.php`
125
* @since 3.1.4
126
*/
127
\wp_cache_flush();
128
\wp_cache_delete( 'alloptions', 'options' );
129
130
$version = _previous_db_version();
166
167
//! From here, the upgrade procedures should be backward compatible.
168
//? This means no data may be erased for at least 1 major version, or 1 year, whichever is later.
169
+ //? We must manually delete settings that are no longer used; we merge them otherwise.
170
if ( $version < '3103' ) {
171
_do_upgrade_3103();
172
$version = '3103';
173
}
174
175
+ if ( $version < '3300' ) {
176
+ _do_upgrade_3300();
177
+ $version = '3300';
178
+ }
179
+
180
/**
181
* @since 2.7.0
182
*/
183
\do_action( 'the_seo_framework_upgraded' );
184
}
185
186
+ /**
187
+ * Releases the upgrade lock on shutdown.
188
+ *
189
+ * When the upgrader halts, timeouts, or crashes for any reason, this will run.
190
+ *
191
+ * @since 4.0.0
192
+ * @TODO add cache flush? @see _upgrade_to_current()
193
+ */
194
+ function _release_upgrade_lock() {
195
+ \delete_transient( 'tsf_upgrade_lock' );
196
+ }
197
+
198
\add_action( 'the_seo_framework_upgraded', __NAMESPACE__ . '\\_upgrade_to_current' );
199
/**
200
* Upgrades the Database version to the latest version.
211
\update_option( 'the_seo_framework_upgraded_db_version', THE_SEO_FRAMEWORK_DB_VERSION );
212
213
/**
214
+ * Clear the cache to prevent a get_option() from retrieving a stale database version to the cache.
215
+ * Not all caching plugins recognize 'flush', so delete the options cache too, just to be safe.
216
+ *
217
+ * @see WordPress' `.../update-core.php`
218
* @since 3.1.4
219
*/
220
\wp_cache_flush();
221
\wp_cache_delete( 'alloptions', 'options' );
222
}
223
224
+ \add_action( 'the_seo_framework_upgraded', __NAMESPACE__ . '\\_prepare_upgrade_notice', 99 );
225
/**
226
+ * Prepares a notice when the upgrade is completed.
227
*
228
+ * @since 4.0.0
229
+ */
230
+ function _prepare_upgrade_notice() {
231
+ \add_action( 'admin_notices', __NAMESPACE__ . '\\_do_upgrade_notice' );
232
+ }
233
+
234
+ /**
235
+ * Outputs "your site has been upgraded" notification to applicable plugin users on upgrade.
236
*
237
+ * @since 3.0.6
238
*/
239
+ function _do_upgrade_notice() {
240
+
241
+ if ( ! \current_user_can( 'update_plugins' ) ) return;
242
+
243
+ $tsf = \the_seo_framework();
244
+
245
+ if ( _previous_db_version() ) {
246
+ $tsf->do_dismissible_notice(
247
+ $tsf->convert_markdown(
248
+ sprintf(
249
+ /* translators: %s = Version number, surrounded in markdown-backticks. */
250
+ \esc_html__( 'Thank you for updating The SEO Framework! Your website has been upgraded successfully to use The SEO Framework at database version `%s`.', 'autodescription' ),
251
+ \esc_html( THE_SEO_FRAMEWORK_DB_VERSION )
252
+ ),
253
+ [ 'code' ]
254
+ ),
255
+ 'updated',
256
+ true,
257
+ false
258
+ );
259
+ } else {
260
+ $tsf->do_dismissible_notice(
261
+ \esc_html__( 'Thank you for installing The SEO Framework! Your website is now optimized for SEO, automatically. We hope you enjoy our free plugin. Good luck with your site!', 'autodescription' ),
262
+ 'updated',
263
+ false,
264
+ false
265
+ );
266
+ $tsf->do_dismissible_notice(
267
+ $tsf->convert_markdown(
268
+ sprintf(
269
+ /* translators: %s = Link, markdown. */
270
+ \esc_html__( "The SEO Framework only identifies itself rarely during plugin upgrades. We'd like to use this opportunity to highlight our [plugin setup guide](%s).", 'autodescription' ),
271
+ 'https://theseoframework.com/docs/seo-plugin-setup/' // Use https://tsf.fyi/docs/setup ? Needless redirection...
272
+ ),
273
+ [ 'a' ],
274
+ [ 'a_internal' => false ]
275
+ ),
276
+ 'updated',
277
+ false,
278
+ false
279
+ );
280
+ }
281
}
282
283
\add_action( 'the_seo_framework_upgraded', __NAMESPACE__ . '\\_prepare_upgrade_suggestion', 100 );
292
* @return void Early when already enqueued
293
*/
294
function _prepare_upgrade_suggestion() {
295
+ if ( ! \is_admin() ) return;
296
+ if ( ! _previous_db_version() ) return;
297
+
298
+ \add_action( 'admin_init', __NAMESPACE__ . '\\_include_upgrade_suggestion', 20 );
299
+ }
300
+
301
+ /**
302
+ * Loads plugin suggestion file
303
+ *
304
+ * @since 4.0.0
305
+ */
306
+ function _include_upgrade_suggestion() {
307
+
308
+ if ( \The_SEO_Framework\_has_run( __METHOD__ ) ) return;
309
310
+ require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'upgrade-suggestion.php';
311
}
312
313
/**
317
* @staticvar array $cache The cached notice strings.
318
*
319
* @param string $notice The upgrade notice.
320
+ * @param bool $get Whether to return the upgrade notices.
321
* @return array|void The notices when $get is true.
322
*/
323
function _add_upgrade_notice( $notice = '', $get = false ) {
374
\add_term_meta( $term_id, THE_SEO_FRAMEWORK_TERM_OPTIONS, $meta, true );
375
}
376
377
+ //= Rudimentary test for remaining ~300 users of earlier versions passed, set initial version to 2600.
378
\update_option( 'the_seo_framework_initial_db_version', '2600', 'no' );
379
}
380
383
384
/**
385
* Removes term metadata for version 2802.
386
*
387
* @since 2.8.0
388
*/
482
* Migrates `attachment_nofollow` option to post type settings.
483
* Migrates `attachment_noarchive` option to post type settings.
484
*
485
* @since 3.1.0
486
*/
487
function _do_upgrade_3103() {
497
498
// Transport title separator.
499
if ( isset( $defaults['title_separator'] ) )
500
+ $tsf->update_option( 'title_separator', $tsf->get_option( 'title_seperator', false ) ?: $defaults['title_separator'] );
501
502
// Transport attachment_noindex, attachment_nofollow, and attachment_noarchive settings.
503
foreach ( [ 'noindex', 'nofollow', 'noarchive' ] as $r ) {
504
$_option = $tsf->get_robots_post_type_option_id( $r );
505
if ( isset( $defaults[ $_option ] ) ) {
506
+ $_value = (array) ( $tsf->get_option( $_option, false ) ?: $defaults[ $_option ] );
507
+ $_value['attachment'] = (int) (bool) $tsf->get_option( "attachment_$r", false );
508
$tsf->update_option( $_option, $_value );
509
}
510
}
528
529
\update_option( 'the_seo_framework_upgraded_db_version', '3103' );
530
}
531
+
532
+ /**
533
+ * Flushes rewrite rules for one last time.
534
+ * Converts title separator's dash option to ndash.
535
+ * Enables pinging via cron.
536
+ * Flips the home_title_location option from left to right, and vice versa.
537
+ *
538
+ * Annotated as 3300, because 4.0 was supposed to be the 3.3 update before we
539
+ * refactored the whole API.
540
+ *
541
+ * @since 4.0.0
542
+ */
543
+ function _do_upgrade_3300() {
544
+
545
+ $tsf = \the_seo_framework();
546
+
547
+ if ( \get_option( 'the_seo_framework_initial_db_version' ) < '3300' ) {
548
+ // Remove old rewrite rules.
549
+ unset(
550
+ $GLOBALS['wp_rewrite']->extra_rules_top['sitemap\.xml#x27;],
551
+ $GLOBALS['wp_rewrite']->extra_rules_top['sitemap\.xsl#x27;]
552
+ ); // redundant?
553
+ \add_action( 'shutdown', 'flush_rewrite_rules' );
554
+
555
+ $defaults = _upgrade_default_site_options();
556
+
557
+ // Convert 'dash' title option to 'ndash', silently. Nothing really changes for the user.
558
+ if ( 'dash' === $tsf->get_option( 'title_separator', false ) )
559
+ $tsf->update_option( 'title_separator', 'ndash' );
560
+
561
+ // Add default cron pinging option.
562
+ if ( isset( $defaults['ping_use_cron'] ) ) {
563
+ $tsf->update_option( 'ping_use_cron', $defaults['ping_use_cron'] );
564
+
565
+ if ( $defaults['ping_use_cron'] ) {
566
+ if ( $tsf->get_option( 'ping_google', false ) || $tsf->get_option( 'ping_bing', false ) ) {
567
+ _add_upgrade_notice(
568
+ \esc_html__( 'A cronjob is now used to ping search engines, and it alerts them to changes in your sitemap.', 'autodescription' )
569
+ );
570
+ }
571
+ }
572
+ }
573
+
574
+ // Flip the homepage title location to make it in line with all other titles.
575
+ $home_title_location = $tsf->get_option( 'home_title_location', false );
576
+ if ( 'left' === $home_title_location ) {
577
+ $tsf->update_option( 'home_title_location', 'right' );
578
+ } else {
579
+ $tsf->update_option( 'home_title_location', 'left' );
580
+ }
581
+
582
+ _add_upgrade_notice(
583
+ \esc_html__( 'The positions in the "Meta Title Additions Location" setting for the homepage have been reversed, left to right, but the output has not been changed. If you must downgrade for some reason, remember to switch the location back again.', 'autodescription' )
584
+ );
585
+ }
586
+
587
+ \update_option( 'the_seo_framework_upgraded_db_version', '3300' );
588
+ }
inc/classes/admin-init.class.php CHANGED
@@ -1,7 +1,9 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework\Classes
4
*/
5
namespace The_SEO_Framework;
6
7
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
@@ -34,665 +36,211 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
34
class Admin_Init extends Init {
35
36
/**
37
- * Prepares scripts in the admin area.
38
*
39
- * @since 3.1.0
40
* @access private
41
- *
42
- * @param string|null $hook The current page hook.
43
*/
44
- public function _init_admin_scripts( $hook = null ) {
45
-
46
- $autoenqueue = false;
47
48
- if ( $this->is_seo_settings_page() ) {
49
- $autoenqueue = true;
50
- } else {
51
- $enqueue_hooks = [
52
- 'edit.php',
53
- 'post.php',
54
- 'post-new.php',
55
- 'edit-tags.php',
56
- 'term.php',
57
- ];
58
-
59
- if ( ! $this->get_option( 'display_seo_bar_tables' ) ) {
60
- $enqueue_hooks = array_diff( $enqueue_hooks, [ 'edit.php', 'edit-tags.php' ] );
61
- }
62
-
63
- if ( isset( $hook ) && $hook && in_array( $hook, $enqueue_hooks, true ) ) {
64
- if ( $this->post_type_supports_custom_seo() )
65
- $autoenqueue = true;
66
- }
67
}
68
-
69
- $autoenqueue and $this->init_admin_scripts();
70
}
71
72
/**
73
- * Returns the static scripts class object.
74
- *
75
- * The first letter of the method is capitalized, to indicate it's a class caller.
76
- *
77
- * @since 3.1.0
78
- * @builder
79
*
80
- * @return string The scripts class name.
81
*/
82
- public function Scripts() {
83
- // return Builder\Scripts::class; //= PHP 5.5+
84
- return '\\The_SEO_Framework\\Builders\\Scripts';
85
}
86
87
/**
88
- * Registers admin scripts and styles.
89
*
90
- * @since 2.6.0
91
- * @since 3.1.0 First parameter is now deprecated.
92
*
93
- * @param bool|null $dpr Deprecated.
94
- * @return void Early if already enqueued.
95
*/
96
- public function init_admin_scripts( $dpr = null ) {
97
98
- if ( null !== $dpr ) $this->_doing_it_wrong( __METHOD__, 'The first argument is deprecated. Use <code>the_seo_framework()->Scripts()::enqueue()</code> after calling this instead.', '3.1.0' );
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',
137
- 'type' => 'css',
138
- 'deps' => [ 'tsf-tt' ],
139
- 'autoload' => true,
140
- 'hasrtl' => true,
141
- 'name' => 'tsf',
142
- 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/css/',
143
- 'ver' => THE_SEO_FRAMEWORK_VERSION,
144
- 'inline' => [
145
- '.tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked + .tsf-flex-nav-tab-label' => [
146
- 'box-shadow:0 -2px 0 0 {{$color_accent}} inset, 0 0 0 0 {{$color_accent}} inset',
147
- ],
148
- '.tsf-flex-nav-tab .tsf-flex-nav-tab-radio:focus + .tsf-flex-nav-tab-label:not(.tsf-no-focus-ring)' => [
149
- 'box-shadow:0 -2px 0 0 {{$color_accent}} inset, 0 0 0 1px {{$color_accent}} inset',
150
- ],
151
- ],
152
- ],
153
- [
154
- 'id' => 'tsf',
155
- 'type' => 'js',
156
- 'deps' => [ 'jquery', 'tsf-tt' ],
157
- 'autoload' => true,
158
- 'name' => 'tsf',
159
- 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/js/',
160
- 'ver' => THE_SEO_FRAMEWORK_VERSION,
161
- 'l10n' => [
162
- 'name' => 'tsfL10n',
163
- 'data' => $this->get_javascript_l10n(),
164
- ],
165
- ],
166
- [
167
- 'id' => 'tsf-tt',
168
- 'type' => 'css',
169
- 'deps' => [],
170
- 'autoload' => true,
171
- 'hasrtl' => false,
172
- 'name' => 'tt',
173
- 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/css/',
174
- 'ver' => THE_SEO_FRAMEWORK_VERSION,
175
- 'inline' => [
176
- '.tsf-tooltip-text-wrap' => [
177
- 'background-color:{{$bg_accent}}',
178
- 'color:{{$rel_bg_accent}}',
179
- ],
180
- '.tsf-tooltip-arrow:after' => [
181
- 'border-top-color:{{$bg_accent}}',
182
- ],
183
- '.tsf-tooltip-down .tsf-tooltip-arrow:after' => [
184
- 'border-bottom-color:{{$bg_accent}}',
185
- ],
186
- '.tsf-tooltip-text' => [
187
- \is_rtl() ? 'direction:rtl' : '',
188
- ],
189
- ],
190
- ],
191
- [
192
- 'id' => 'tsf-tt',
193
- 'type' => 'js',
194
- 'deps' => [ 'jquery' ],
195
- 'autoload' => true,
196
- 'name' => 'tt',
197
- 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/js/',
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
-
240
- if ( _has_run( __METHOD__ ) ) return;
241
-
242
- $args = [];
243
- if ( $this->is_post_edit() ) {
244
- $args['post'] = $this->get_the_real_admin_ID();
245
- }
246
- \wp_enqueue_media( $args );
247
-
248
- //! PHP 5.4 compat: put in var.
249
- $scripts = $this->Scripts();
250
- $scripts::register( [
251
- 'id' => 'tsf-media',
252
- 'type' => 'js',
253
- 'deps' => [ 'jquery', 'tsf' ],
254
- 'autoload' => true,
255
- 'name' => 'media',
256
- 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/js/',
257
- 'ver' => THE_SEO_FRAMEWORK_VERSION,
258
- 'l10n' => [
259
- 'name' => 'tsfMediaL10n',
260
- 'data' => [
261
- 'labels' => [
262
- 'social' => [
263
- 'imgSelect' => \esc_attr__( 'Select Image', 'autodescription' ),
264
- 'imgSelectTitle' => \esc_attr_x( 'Select social image', 'Button hover', 'autodescription' ),
265
- 'imgChange' => \esc_attr__( 'Change Image', 'autodescription' ),
266
- 'imgRemove' => \esc_attr__( 'Remove Image', 'autodescription' ),
267
- 'imgRemoveTitle' => \esc_attr__( 'Remove selected social image', 'autodescription' ),
268
- 'imgFrameTitle' => \esc_attr_x( 'Select Social Image', 'Frame title', 'autodescription' ),
269
- 'imgFrameButton' => \esc_attr__( 'Use this image', 'autodescription' ),
270
- ],
271
- 'logo' => [
272
- 'imgSelect' => \esc_attr__( 'Select Logo', 'autodescription' ),
273
- 'imgSelectTitle' => '',
274
- 'imgChange' => \esc_attr__( 'Change Logo', 'autodescription' ),
275
- 'imgRemove' => \esc_attr__( 'Remove Logo', 'autodescription' ),
276
- 'imgRemoveTitle' => \esc_attr__( 'Unset selected logo', 'autodescription' ),
277
- 'imgFrameTitle' => \esc_attr_x( 'Select Logo', 'Frame title', 'autodescription' ),
278
- 'imgFrameButton' => \esc_attr__( 'Use this image', 'autodescription' ),
279
- ],
280
- ],
281
- ],
282
- ],
283
- ] );
284
- }
285
-
286
- /**
287
- * Enqueues Primary Term Selection scripts.
288
*
289
* @since 3.1.0
290
*
291
- * @return void Early if already enqueued.
292
- */
293
- public function enqueue_primaryterm_scripts() {
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 = [];
330
- if ( \is_rtl() ) {
331
- $inline_css = [
332
- '.tsf-primary-term-selector' => [
333
- 'float:left;',
334
- ],
335
- '.tsf-primary-term-selector-help-wrap' => [
336
- 'left:25px;',
337
- 'right:initial;',
338
- ],
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' => [
368
- 'name' => 'tsfPTL10n',
369
- 'data' => [
370
- 'taxonomies' => $taxonomies,
371
- ],
372
- ],
373
- 'tmpl' => [
374
- 'file' => $this->get_view_location( 'templates/inpost/primary-term-selector' ),
375
- ],
376
- ],
377
- [
378
- 'id' => 'tsf-pt',
379
- 'type' => 'css',
380
- 'deps' => [ 'tsf-tt' ],
381
- 'autoload' => true,
382
- 'hasrtl' => false,
383
- 'name' => 'pt',
384
- 'base' => THE_SEO_FRAMEWORK_DIR_URL . 'lib/css/',
385
- 'ver' => THE_SEO_FRAMEWORK_VERSION,
386
- 'inline' => $inline_css,
387
- ],
388
- ] );
389
- }
390
-
391
- /**
392
- * Generate Javascript Localization.
393
- *
394
- * @TODO rewrite, it's slow and a mess.
395
- *
396
- * @since 2.6.0
397
- * @staticvar array $strings : The l10n strings.
398
- * @since 2.7.0 Added AJAX nonce: 'autodescription-ajax-nonce'
399
- * @since 2.8.0 1 : Added input detection: 'hasInput'
400
- * 2 : Reworked output.
401
- * 3 : Removed unused caching.
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
- }
471
-
472
- $this->set_js_nonces( [
473
- /**
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
-
489
- $social_settings_locks = [];
490
-
491
- if ( $page_on_front ) {
492
- if ( $is_settings_page ) {
493
- // PH = placeholder
494
- $social_settings_locks = [
495
- 'ogTitlePHLock' => (bool) $this->get_custom_field( '_open_graph_title', $id ),
496
- 'ogDescriptionPHLock' => (bool) $this->get_custom_field( '_open_graph_description', $id ),
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' ),
504
- 'ogTitleLock' => (bool) $this->get_option( 'homepage_og_title' ),
505
- 'ogDescriptionLock' => (bool) $this->get_option( 'homepage_og_description' ),
506
- 'twTitleLock' => (bool) $this->get_option( 'homepage_twitter_title' ),
507
- 'twDescriptionLock' => (bool) $this->get_option( 'homepage_twitter_description' ),
508
];
509
- }
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();
548
- $input_guidelines_i18n = $this->get_input_guidelines_i18n();
549
}
550
551
- $l10n = [
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,
559
- 'taglineLocked' => (bool) $this->get_option( 'title_rem_additions' ),
560
- 'useTermPrefix' => $use_term_prefix,
561
- 'isSettingsPage' => $is_settings_page,
562
- 'isPostEdit' => $is_post_edit,
563
- 'isTermEdit' => $is_term_edit,
564
- 'postType' => $is_post_edit ? \get_post_type( $id ) : false,
565
- 'isPrivate' => $has_input && $is_post_edit && $id && $this->is_private( $id ),
566
- 'isPasswordProtected' => $has_input && $is_post_edit && $id && $this->is_password_protected( $id ),
567
- 'debug' => $this->script_debug,
568
- 'homeLocks' => $social_settings_locks,
569
- 'stripTitleTags' => (bool) $this->get_option( 'title_strip_tags' ),
570
- 'isGutenbergPage' => $this->is_gutenberg_page(),
571
- ],
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
-
604
- /**
605
- * @since 3.0.0
606
- * @param array $l10n The JS l10n values.
607
- */
608
- return (array) \apply_filters( 'the_seo_framework_js_l10n', $l10n );
609
- }
610
-
611
- /**
612
- * Sets up additional JS l10n values for nonces.
613
- *
614
- * They are put under object 'tsfemL10n.nonces[ $key ] = $val'.
615
- *
616
- * @since 2.9.0
617
- * @access private
618
- *
619
- * @param string|array $key Required. The object key or array of keys and values. Requires escape.
620
- * @param mixed $val The object value if $key is string. Requires escape.
621
- */
622
- public function set_js_nonces( $key, $val = null ) {
623
- $this->get_js_nonces( $key, $val, false );
624
}
625
626
/**
627
- * Maintains and Returns additional JS l10n.
628
- *
629
- * They are put under object 'tsfemL10n.nonces[ $key ] = $val'.
630
- *
631
- * If $key is an array, $val is ignored and $key's values are used instead.
632
*
633
- * @since 2.9.0
634
- * @access private
635
- * @staticvar object $nonces The cached nonces object.
636
*
637
- * @param string|array $key The object key or array of keys and values. Requires escape.
638
- * @param mixed $val The object value if $key is string. Requires escape.
639
- * @param bool $get Whether to return the cached nonces.
640
- * @return object Early when $get is true
641
*/
642
- public function get_js_nonces( $key = null, $val = null, $get = true ) {
643
-
644
- static $nonces = null;
645
-
646
- if ( null === $nonces )
647
- $nonces = new \stdClass();
648
649
- if ( $get )
650
- return $nonces;
651
652
- if ( is_string( $key ) ) {
653
- $nonces->$key = $val;
654
- } elseif ( is_array( $key ) ) {
655
- foreach ( $key as $k => $v ) {
656
- $nonces->$k = $v;
657
- }
658
- }
659
}
660
661
/**
662
* Returns the title and description input guideline table, for
663
* (Google) search, Open Graph, and Twitter.
664
*
665
* @since 3.1.0
666
* @staticvar array $guidelines
667
* @TODO Consider splitting up search into Google, Bing, etc., as we might
668
* want users to set their preferred search engine. Now, these engines
669
* are barely any different.
670
*
671
* @return array
672
*/
673
- public function get_input_guidelines() {
674
- static $guidelines;
675
/**
676
* @since 3.1.0
677
* @param array $guidelines The title and description guidelines.
678
* Don't alter the format. Only change the numeric values.
679
*/
680
- return isset( $guidelines ) ? $guidelines : $guidelines = (array) \apply_filters(
681
'the_seo_framework_input_guidelines',
682
[
683
'title' => [
684
'search' => [
685
'chars' => [
686
- 'lower' => 25,
687
- 'goodLower' => 35,
688
- 'goodUpper' => 65,
689
- 'upper' => 75,
690
],
691
'pixels' => [
692
- 'lower' => 200,
693
- 'goodLower' => 280,
694
- 'goodUpper' => 520,
695
- 'upper' => 600,
696
],
697
],
698
'opengraph' => [
@@ -717,16 +265,16 @@ class Admin_Init extends Init {
717
'description' => [
718
'search' => [
719
'chars' => [
720
- 'lower' => 45,
721
- 'goodLower' => 80,
722
- 'goodUpper' => 160,
723
- 'upper' => 320,
724
],
725
'pixels' => [
726
- 'lower' => 256,
727
- 'goodLower' => 455,
728
- 'goodUpper' => 910,
729
- 'upper' => 1820,
730
],
731
],
732
'opengraph' => [
@@ -750,6 +298,7 @@ class Admin_Init extends Init {
750
],
751
]
752
);
753
}
754
755
/**
@@ -758,12 +307,13 @@ class Admin_Init extends Init {
758
* Already attribute-escaped.
759
*
760
* @since 3.1.0
761
*
762
* @return array
763
*/
764
public function get_input_guidelines_i18n() {
765
return [
766
- 'long' => [
767
'empty' => \esc_attr__( "There's no content.", 'autodescription' ),
768
'farTooShort' => \esc_attr__( "It's too short and it should have more information.", 'autodescription' ),
769
'tooShort' => \esc_attr__( "It's short and it could have more information.", 'autodescription' ),
@@ -771,7 +321,7 @@ class Admin_Init extends Init {
771
'farTooLong' => \esc_attr__( "It's too long and it will get truncated in search.", 'autodescription' ),
772
'good' => \esc_attr__( 'Length is good.', 'autodescription' ),
773
],
774
- 'short' => [
775
'empty' => \esc_attr_x( 'Empty', 'The string is empty', 'autodescription' ),
776
'farTooShort' => \esc_attr__( 'Far too short', 'autodescription' ),
777
'tooShort' => \esc_attr__( 'Too short', 'autodescription' ),
@@ -779,6 +329,14 @@ class Admin_Init extends Init {
779
'farTooLong' => \esc_attr__( 'Far too long', 'autodescription' ),
780
'good' => \esc_attr__( 'Good', 'autodescription' ),
781
],
782
];
783
}
784
@@ -793,6 +351,7 @@ class Admin_Init extends Init {
793
* @uses WP Core check_ajax_referer()
794
* @see @link https://developer.wordpress.org/reference/functions/check_ajax_referer/
795
*
796
* @return false|int False if the nonce is invalid, 1 if the nonce is valid
797
* and generated between 0-12 hours ago, 2 if the nonce is
798
* valid and generated between 12-24 hours ago.
@@ -801,24 +360,6 @@ class Admin_Init extends Init {
801
return \check_ajax_referer( 'tsf-ajax-' . $capability, 'nonce', true );
802
}
803
804
- /**
805
- * Adds removable query args to WordPress query arg handler.
806
- *
807
- * @since 2.8.0
808
- *
809
- * @param array $removable_query_args
810
- * @return array The adjusted removable query args.
811
- */
812
- public function add_removable_query_args( $removable_query_args = [] ) {
813
-
814
- if ( is_array( $removable_query_args ) ) {
815
- $removable_query_args[] = 'tsf-settings-reset';
816
- $removable_query_args[] = 'tsf-settings-updated';
817
- }
818
-
819
- return $removable_query_args;
820
- }
821
-
822
/**
823
* Redirect the user to an admin page, and add query args to the URL string
824
* for alerts, etc.
@@ -846,7 +387,7 @@ class Admin_Init extends Init {
846
}
847
848
$target = \add_query_arg( $query_args, $url );
849
- $target = \esc_url_raw( $target, [ 'http', 'https' ] );
850
851
//* Predict white screen:
852
$headers_sent = headers_sent();
@@ -877,8 +418,7 @@ class Admin_Init extends Init {
877
*/
878
protected function handle_admin_redirect_error( $target = '' ) {
879
880
- if ( empty( $target ) )
881
- return;
882
883
$headers_list = headers_list();
884
$location = sprintf( 'Location: %s', \wp_sanitize_redirect( $target ) );
@@ -887,17 +427,19 @@ class Admin_Init extends Init {
887
if ( in_array( $location, $headers_list, true ) )
888
return;
889
890
printf( '<p><strong>%s</strong></p>',
891
$this->convert_markdown(
892
sprintf(
893
/* translators: %s = Redirect URL markdown */
894
\esc_html__( 'There has been an error redirecting. Refresh the page or follow [this link](%s).', 'autodescription' ),
895
- $target
896
),
897
[ 'a' ],
898
[ 'a_internal' => true ]
899
)
900
);
901
}
902
903
/**
@@ -909,42 +451,155 @@ class Admin_Init extends Init {
909
*/
910
public function _wp_ajax_update_counter_type() {
911
912
- if ( $this->is_admin() && $this->doing_ajax() ) :
913
- $this->_check_tsf_ajax_referer( 'edit_posts' );
914
915
- //* Remove output buffer.
916
- $this->clean_response_header();
917
918
- //* If current user isn't allowed to edit posts, don't do anything and kill PHP.
919
- if ( ! \current_user_can( 'edit_posts' ) ) {
920
- //* Encode and echo results. Requires JSON decode within JS.
921
- \wp_send_json( [
922
- 'type' => 'failure',
923
- 'value' => '',
924
- ] );
925
- }
926
927
- /**
928
- * Count up, reset to 0 if needed. We have 4 options: 0, 1, 2, 3
929
- * $_POST['val'] already contains updated number.
930
- */
931
- $value = isset( $_POST['val'] ) ? intval( $_POST['val'] ) : $this->get_user_option( 0, 'counter_type', 3 ) + 1; // input var ok
932
- $value = \absint( $value );
933
934
- if ( $value > 3 )
935
- $value = 0;
936
937
- //* Update the option and get results of action.
938
- $type = $this->update_user_option( 0, 'counter_type', $value ) ? 'success' : 'error';
939
940
- $results = [
941
- 'type' => $type,
942
- 'value' => $value,
943
- ];
944
945
- //* Encode and echo results. Requires JSON decode within JS.
946
- \wp_send_json( $results );
947
- endif;
948
}
949
950
/**
@@ -952,6 +607,9 @@ class Admin_Init extends Init {
952
*
953
* Copied from WordPress Core wp_ajax_crop_image.
954
* Adjusted: 1. It accepts capability 'upload_files', instead of 'customize'.
955
* 2. It now only accepts TSF own AJAX nonces.
956
* 3. It now only accepts context 'tsf-image'
957
* 4. It no longer accepts a default context.
@@ -962,18 +620,18 @@ class Admin_Init extends Init {
962
*/
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
975
- $context = str_replace( '_', '-', \sanitize_key( $_POST['context'] ) ); // input var ok.
976
- $data = array_map( 'absint', $_POST['cropDetails'] ); // input var ok.
977
$cropped = \wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] );
978
979
if ( ! $cropped || \is_wp_error( $cropped ) )
@@ -1000,7 +658,8 @@ class Admin_Init extends Init {
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 = [
@@ -1042,5 +701,7 @@ class Admin_Init extends Init {
1042
endswitch;
1043
1044
\wp_send_json_success( \wp_prepare_attachment_for_js( $attachment_id ) );
1045
}
1046
}
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Classes\Facade\Admin_Init
4
+ * @subpackage The_SEO_Framework\Admin
5
*/
6
+
7
namespace The_SEO_Framework;
8
9
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
36
class Admin_Init extends Init {
37
38
/**
39
+ * Initializes SEO Bar tables.
40
*
41
+ * @since 4.0.0
42
* @access private
43
*/
44
+ public function _init_seo_bar_tables() {
45
46
+ if ( $this->get_option( 'display_seo_bar_tables' ) ) {
47
+ new Bridges\SeoBar;
48
}
49
}
50
51
/**
52
+ * Initializes List Edit tables.
53
*
54
+ * @since 4.0.0
55
+ * @access private
56
*/
57
+ public function _init_list_edit() {
58
+ new Bridges\ListEdit;
59
}
60
61
/**
62
+ * Adds post states in post/page edit.php query
63
*
64
+ * @since 4.0.0
65
*
66
+ * @param array $states The current post states array
67
+ * @param \WP_Post $post The Post Object.
68
+ * @return array Adjusted $states
69
*/
70
+ public function _add_post_state( $states = [], $post ) {
71
72
+ $post_id = isset( $post->ID ) ? $post->ID : false;
73
74
+ if ( $post_id ) {
75
+ $search_exclude = $this->get_option( 'alter_search_query' ) && $this->get_post_meta_item( 'exclude_local_search', $post_id );
76
+ $archive_exclude = $this->get_option( 'alter_archive_query' ) && $this->get_post_meta_item( 'exclude_from_archive', $post_id );
77
78
+ if ( $search_exclude )
79
+ $states[] = \esc_html__( 'No Search', 'autodescription' );
80
81
+ if ( $archive_exclude )
82
+ $states[] = \esc_html__( 'No Archive', 'autodescription' );
83
}
84
85
+ return $states;
86
}
87
88
/**
89
+ * Prepares scripts in the admin area.
90
*
91
* @since 3.1.0
92
+ * @since 4.0.0 Now discerns autoloading between taxonomies and singular types.
93
+ * @access private
94
*
95
+ * @param string|null $hook The current page hook.
96
*/
97
+ public function _init_admin_scripts( $hook = null ) {
98
99
+ $autoenqueue = false;
100
101
+ if ( $this->is_seo_settings_page() ) {
102
+ $autoenqueue = true;
103
+ } elseif ( $hook ) {
104
105
+ $enqueue_hooks = [];
106
107
+ if ( $this->is_archive_admin() ) {
108
+ $prepare_edit_screen = $this->is_taxonomy_supported();
109
+ } elseif ( $this->is_singular_admin() ) {
110
+ $prepare_edit_screen = $this->is_post_type_supported();
111
} else {
112
+ $prepare_edit_screen = false;
113
}
114
115
+ if ( $prepare_edit_screen ) {
116
+