The SEO Framework - Version 3.1.4

Version Description

This update brings improved compatibility with WooCommerce, adds a few filters, and fixes various logic issues.

Download this release

Release Info

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

Code changes from version 3.0.6 to 3.1.4

Files changed (106) hide show
  1. autodescription.php +46 -135
  2. inc/functions/plugin-activation.php → bootstrap/activation.php +33 -10
  3. inc/functions/plugin-deactivation.php → bootstrap/deactivation.php +9 -5
  4. bootstrap/define.php +126 -0
  5. inc/functions/plugin-test-server.php → bootstrap/envtest.php +38 -39
  6. bootstrap/index.php +6 -0
  7. bootstrap/load.php +168 -0
  8. bootstrap/upgrade.php +435 -0
  9. inc/classes/admin-init.class.php +527 -432
  10. inc/classes/admin-pages.class.php +468 -286
  11. inc/classes/builders/scripts.class.php +439 -0
  12. inc/classes/cache.class.php +155 -400
  13. inc/classes/compat.class.php +24 -44
  14. inc/classes/core.class.php +173 -307
  15. inc/classes/debug.class.php +92 -478
  16. inc/classes/deprecated.class.php +438 -1782
  17. inc/classes/detect.class.php +326 -396
  18. inc/classes/doing-it-right.class.php +477 -445
  19. inc/classes/feed.class.php +9 -17
  20. inc/classes/generate-description.class.php +588 -877
  21. inc/classes/generate-image.class.php +163 -122
  22. inc/classes/generate-ldjson.class.php +194 -225
  23. inc/classes/generate-title.class.php +791 -1088
  24. inc/classes/generate-url.class.php +213 -359
  25. inc/classes/generate.class.php +190 -155
  26. inc/classes/index.php +4 -0
  27. inc/classes/init.class.php +138 -177
  28. inc/classes/inpost.class.php +170 -303
  29. inc/classes/load.class.php +54 -53
  30. inc/classes/metaboxes.class.php +191 -105
  31. inc/classes/post-data.class.php +154 -227
  32. inc/classes/profile.class.php +34 -31
  33. inc/classes/query.class.php +242 -195
  34. inc/classes/render.class.php +359 -307
  35. inc/classes/sanitize.class.php +314 -166
  36. inc/classes/silencer.class.php +57 -0
  37. inc/classes/site-options.class.php +326 -512
  38. inc/classes/sitemaps.class.php +301 -274
  39. inc/classes/term-data.class.php +82 -132
  40. inc/classes/user-data.class.php +10 -18
  41. inc/compat/php-mbstring.php +1 -1
  42. inc/compat/plugin-bbpress.php +27 -103
  43. inc/compat/plugin-buddypress.php +2 -2
  44. inc/compat/plugin-polylang.php +36 -0
  45. inc/compat/plugin-ultimatemember.php +95 -23
  46. inc/compat/plugin-woocommerce.php +27 -0
  47. inc/compat/plugin-wpforo.php +41 -15
  48. inc/compat/plugin-wpml.php +45 -3
  49. inc/compat/theme-genesis.php +21 -18
  50. inc/compat/wp-460.php +0 -58
  51. inc/compat/wp-470.php +10 -0
  52. inc/functions/api.php +146 -0
  53. inc/functions/deprecated.php +203 -1
  54. inc/functions/optionsapi.php +0 -272
  55. inc/functions/tsfem-suggestion.php +21 -15
  56. inc/functions/upgrade.php +0 -250
  57. inc/interfaces/debug.interface.php +2 -16
  58. inc/views/admin/seo-settings-columns.php +2 -2
  59. inc/views/admin/seo-settings-wrap.php +11 -11
  60. inc/views/debug/index.php +6 -1
  61. inc/views/debug/output.php +68 -72
  62. inc/views/inpost/seo-settings-singular.php +130 -124
  63. inc/views/inpost/seo-settings-tt.php +52 -86
  64. inc/views/inpost/wrap-content.php +57 -0
  65. inc/views/inpost/wrap-nav.php +52 -0
  66. inc/views/inpost/wrap.php +0 -100
  67. inc/views/metaboxes/description-metabox.php +128 -97
  68. inc/views/metaboxes/feed-metabox.php +31 -15
  69. inc/views/metaboxes/general-metabox.php +168 -145
  70. inc/views/metaboxes/homepage-metabox.php +286 -199
  71. inc/views/metaboxes/robots-metabox.php +109 -83
  72. inc/views/metaboxes/schema-metabox.php +101 -82
  73. inc/views/metaboxes/sitemaps-metabox.php +145 -103
  74. inc/views/metaboxes/social-metabox.php +53 -54
  75. inc/views/metaboxes/title-metabox.php +127 -91
  76. inc/views/metaboxes/webmaster-metabox.php +17 -11
  77. inc/views/profile/author.php +11 -4
  78. inc/views/sitemap/xsl-stylesheet.php +414 -216
  79. inc/views/templates/inpost/primary-term-selector.php +8 -6
  80. index.php +6 -1
  81. language/autodescription.pot +947 -846
  82. lib/css/pt.css +52 -0
  83. lib/css/pt.min.css +1 -0
  84. lib/css/tsf-rtl.min.css +0 -1
  85. lib/css/tsf.css +101 -372
  86. lib/css/tsf.min.css +1 -1
  87. lib/css/{tsf-rtl.css → tsf.rtl.css} +102 -373
  88. lib/css/tsf.rtl.min.css +1 -0
  89. lib/css/tt.css +123 -0
  90. lib/css/tt.min.css +1 -0
  91. lib/js/externs/tsf.externs.js +0 -282
  92. lib/js/externs/tsf.externs.protected.js +0 -406
  93. lib/js/gutenberg.js +166 -0
  94. lib/js/gutenberg.min.js +1 -0
  95. lib/js/media.js +619 -0
  96. lib/js/media.min.js +1 -0
  97. lib/js/pt.js +349 -0
  98. lib/js/pt.min.js +1 -0
  99. lib/js/tsf.js +807 -1559
  100. lib/js/tsf.min.js +1 -1
  101. lib/js/tt.js +504 -0
  102. lib/js/tt.min.js +1 -0
  103. load.php +0 -175
  104. readme.txt +96 -261
  105. seotips/index.php +0 -2
  106. seotips/seotips.txt +0 -149
autodescription.php CHANGED
@@ -3,7 +3,7 @@
3
* Plugin Name: The SEO Framework
4
* Plugin URI: https://theseoframework.com/
5
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
- * Version: 3.0.6
7
* Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
@@ -30,14 +30,18 @@ defined( 'ABSPATH' ) or die;
30
* along with this program. If not, see <http://www.gnu.org/licenses/>.
31
*/
32
33
//* Debug. Not to be used on production websites as it dumps and/or disables all kinds of stuff everywhere.
34
// add_action( 'plugins_loaded', function() { if ( is_super_admin() ) {
35
// if ( is_admin() ) {
36
// define( 'THE_SEO_FRAMEWORK_DEBUG', true );
37
- // define( 'THE_SEO_FRAMEWORK_DEBUG_HIDDEN', true );
38
// define( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS', true );
39
- // update_option( 'the_seo_framework_upgraded_db_version', '3060' );
40
- // update_option( 'the_seo_framework_tested_upgrade_version', '0' );
41
// add_filter( 'the_seo_framework_use_object_cache', '__return_false' );
42
// }
43
// }},0);
@@ -45,14 +49,11 @@ defined( 'ABSPATH' ) or die;
45
/**
46
* The plugin version.
47
*
48
- * Used as a CDN and Browser Cache buster.
49
- * Chrome and Firefox cache admin scripts.
50
- *
51
* 3 point: x.x.y; x.x is major; y is minor.
52
*
53
- * @since 1.0.0
54
*/
55
- define( 'THE_SEO_FRAMEWORK_VERSION', '3.0.6' );
56
57
/**
58
* The plugin Database version.
@@ -61,66 +62,7 @@ define( 'THE_SEO_FRAMEWORK_VERSION', '3.0.6' );
61
*
62
* @since 2.7.0
63
*/
64
- define( 'THE_SEO_FRAMEWORK_DB_VERSION', '3060' );
65
-
66
- /**
67
- * The plugin options database option_name.
68
- *
69
- * Used for storing the SEO options array.
70
- *
71
- * @todo document filter.
72
- *
73
- * @since 2.2.2
74
- */
75
- define( 'THE_SEO_FRAMEWORK_SITE_OPTIONS', (string) apply_filters( 'the_seo_framework_site_options', 'autodescription-site-settings' ) );
76
-
77
- /**
78
- * The plugin network options.
79
- *
80
- * @todo document filter.
81
- * Unused. @todo remove
82
- *
83
- * @since 2.2.2
84
- */
85
- define( 'THE_SEO_FRAMEWORK_NETWORK_OPTIONS', (string) apply_filters( 'the_seo_framework_network_settings', 'autodescription-network-settings' ) );
86
-
87
- /**
88
- * Plugin term options filter.
89
- * @since 2.7.0
90
- */
91
- define( 'THE_SEO_FRAMEWORK_TERM_OPTIONS', (string) apply_filters( 'the_seo_framework_term_options', 'autodescription-term-settings' ) );
92
-
93
- /**
94
- * Plugin user term options filter.
95
- * @since 2.7.0
96
- */
97
- define( 'THE_SEO_FRAMEWORK_USER_OPTIONS', (string) apply_filters( 'the_seo_framework_user_options', 'autodescription-user-settings' ) );
98
-
99
- /**
100
- * Plugin updates cache database name.
101
- * @since 2.9.3
102
- */
103
- define( 'THE_SEO_FRAMEWORK_UPDATES_CACHE', (string) apply_filters( 'the_seo_framework_updates_cache', 'autodescription-updates-cache' ) );
104
-
105
- /**
106
- * The plugin map url.
107
- * Used for calling browser files.
108
- * @since 2.2.2
109
- */
110
- define( 'THE_SEO_FRAMEWORK_DIR_URL', plugin_dir_url( __FILE__ ) );
111
-
112
- /**
113
- * The plugin map absolute path.
114
- * Used for calling php files.
115
- * @since 2.2.2
116
- */
117
- define( 'THE_SEO_FRAMEWORK_DIR_PATH', plugin_dir_path( __FILE__ ) );
118
-
119
- /**
120
- * The plugin file relative to the plugins dir.
121
- * @since 2.2.8
122
- */
123
- define( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
124
125
/**
126
* The plugin file, absolute unix path.
@@ -129,93 +71,62 @@ define( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
129
define( 'THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE', __FILE__ );
130
131
/**
132
- * The plugin views map absolute path.
133
- * @since 2.7.0
134
*/
135
- define( 'THE_SEO_FRAMEWORK_DIR_PATH_VIEWS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR );
136
137
/**
138
- * The plugin class map absolute path.
139
- * @since 2.2.9
140
- */
141
- define( 'THE_SEO_FRAMEWORK_DIR_PATH_CLASS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR );
142
-
143
- /**
144
- * The plugin interface map absolute path.
145
* @since 2.8.0
146
*/
147
- define( 'THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'interfaces' . DIRECTORY_SEPARATOR );
148
149
- /**
150
- * The plugin function map absolute path.
151
- * @since 2.2.9
152
- */
153
- define( 'THE_SEO_FRAMEWORK_DIR_PATH_FUNCT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR );
154
-
155
- /**
156
- * The plugin function map absolute path.
157
- * @since 2.8.0
158
- */
159
- define( 'THE_SEO_FRAMEWORK_DIR_PATH_COMPAT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'compat' . DIRECTORY_SEPARATOR );
160
-
161
- the_seo_framework_pre_load();
162
- /**
163
- * Determines whether we can "just" load the plugin, or require verification beforehand.
164
- *
165
- * @since 2.8.0
166
- * @since 2.9.4 The option is now autoloaded.
167
- * @uses get_site_option(), so it will only test once per WordPress installation; multisite included.
168
- * @todo This option isn't autoloaded... use is_multisite() condition?
169
- */
170
- function the_seo_framework_pre_load() {
171
- if ( get_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION ) {
172
- the_seo_framework_load_base_files();
173
- } else {
174
- the_seo_framework_test_server();
175
- }
176
}
177
178
/**
179
- * Tests plugin upgrade.
180
*
181
- * @since 2.8.0
182
*/
183
- function the_seo_framework_test_server() {
184
185
- //* Load on init action (manual FTP upload) or after plugin has been upgraded.
186
- require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'plugin-test-server.php';
187
188
- if ( get_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
189
- the_seo_framework_load_base_files();
190
- }
191
192
- /**
193
- * Loads plugin base files.
194
- *
195
- * @since 2.8.0
196
- */
197
- function the_seo_framework_load_base_files() {
198
/**
199
- * Load plugin files.
200
- *
201
- * @since 1.0.0
202
- * @uses THE_SEO_FRAMEWORK_DIR_PATH
203
*/
204
- require THE_SEO_FRAMEWORK_DIR_PATH . 'load.php';
205
206
/**
207
* Load deprecated functions.
208
- *
209
- * @since 2.7.0
210
- * @since 2.9.2 No longer called to improve performance.
211
- * @uses THE_SEO_FRAMEWORK_DIR_PATH_FUNCT
212
*/
213
- // require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'deprecated.php';
214
215
/**
216
- * Load API files.
217
- * @since 2.1.6
218
- * @uses THE_SEO_FRAMEWORK_DIR_PATH_FUNCT
219
*/
220
- require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'optionsapi.php';
221
}
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
30
* along with this program. If not, see <http://www.gnu.org/licenses/>.
31
*/
32
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);
49
/**
50
* The plugin version.
51
*
52
* 3 point: x.x.y; x.x is major; y is minor.
53
*
54
+ * @since 2.3.5
55
*/
56
+ define( 'THE_SEO_FRAMEWORK_VERSION', '3.1.4' );
57
58
/**
59
* The plugin Database version.
62
*
63
* @since 2.7.0
64
*/
65
+ define( 'THE_SEO_FRAMEWORK_DB_VERSION', '3104' );
66
67
/**
68
* The plugin file, absolute unix path.
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 ) {
84
+ require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'envtest.php';
85
86
+ if ( get_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
87
+ the_seo_framework_boot();
88
+ } else {
89
+ the_seo_framework_boot();
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
}
inc/functions/plugin-activation.php → bootstrap/activation.php RENAMED
@@ -4,7 +4,7 @@
4
*/
5
namespace The_SEO_Framework;
6
7
- defined( 'THE_SEO_FRAMEWORK_DIR_PATH' ) or die;
8
9
/**
10
* The SEO Framework plugin
@@ -26,6 +26,24 @@ defined( 'THE_SEO_FRAMEWORK_DIR_PATH' ) or die;
26
//! @php7+ convert to IIFE
27
\The_SEO_Framework\_activation_setup_sitemap();
28
\The_SEO_Framework\_activation_set_options_autoload();
29
30
/**
31
* Add and Flush rewrite rules on plugin activation.
@@ -39,34 +57,39 @@ defined( 'THE_SEO_FRAMEWORK_DIR_PATH' ) or die;
39
*/
40
function _activation_setup_sitemap() {
41
42
- $the_seo_framework = \the_seo_framework();
43
44
- if ( isset( $the_seo_framework ) ) {
45
- $the_seo_framework->rewrite_rule_sitemap();
46
\add_action( 'shutdown', 'flush_rewrite_rules' );
47
}
48
}
49
50
/**
51
- * Turns on autoloading for The SEO Framework main options.
52
*
53
* @since 2.9.2
54
* @access private
55
*/
56
function _activation_set_options_autoload() {
57
58
- $the_seo_framework = \the_seo_framework();
59
60
- if ( isset( $the_seo_framework ) ) {
61
- $options = $the_seo_framework->get_all_options();
62
$setting = THE_SEO_FRAMEWORK_SITE_OPTIONS;
63
64
\remove_all_filters( "pre_update_option_{$setting}" );
65
\remove_all_actions( "update_option_{$setting}" );
66
\remove_all_filters( "sanitize_option_{$setting}" );
67
68
- // Set to false, so we can reset the options.
69
- $_success = \update_option( $setting, false );
70
if ( $_success )
71
\update_option( $setting, $options, 'yes' );
72
}
4
*/
5
namespace The_SEO_Framework;
6
7
+ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
9
/**
10
* The SEO Framework plugin
26
//! @php7+ convert to IIFE
27
\The_SEO_Framework\_activation_setup_sitemap();
28
\The_SEO_Framework\_activation_set_options_autoload();
29
+ \The_SEO_Framework\_activation_set_plugin_check_caches();
30
+
31
+ /**
32
+ * Nudges the plugin to check for conflicting SEO plugins.
33
+ *
34
+ * When found, it'll output a single dismissible notification.
35
+ *
36
+ * @since 3.1.0
37
+ * @access private
38
+ */
39
+ function _activation_set_plugin_check_caches() {
40
+
41
+ $tsf = \the_seo_framework();
42
+
43
+ if ( $tsf->loaded ) {
44
+ $tsf->set_plugin_check_caches();
45
+ }
46
+ }
47
48
/**
49
* Add and Flush rewrite rules on plugin activation.
57
*/
58
function _activation_setup_sitemap() {
59
60
+ $tsf = \the_seo_framework();
61
62
+ if ( $tsf->loaded ) {
63
+ $tsf->rewrite_rule_sitemap();
64
\add_action( 'shutdown', 'flush_rewrite_rules' );
65
}
66
}
67
68
/**
69
+ * Turns on auto loading for The SEO Framework's main options.
70
*
71
* @since 2.9.2
72
+ * @since 3.1.0 No longer deletes the whole option array, trying to reactivate auto loading.
73
* @access private
74
*/
75
function _activation_set_options_autoload() {
76
77
+ $tsf = \the_seo_framework();
78
79
+ if ( $tsf->loaded ) {
80
+ $options = $tsf->get_all_options();
81
$setting = THE_SEO_FRAMEWORK_SITE_OPTIONS;
82
83
\remove_all_filters( "pre_update_option_{$setting}" );
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
+
92
+ $_success = \update_option( $setting, $temp_options, 'yes' );
93
if ( $_success )
94
\update_option( $setting, $options, 'yes' );
95
}
inc/functions/plugin-deactivation.php → bootstrap/deactivation.php RENAMED
@@ -4,7 +4,7 @@
4
*/
5
namespace The_SEO_Framework;
6
7
- defined( 'THE_SEO_FRAMEWORK_DIR_PATH' ) or die;
8
9
/**
10
* The SEO Framework plugin
@@ -35,7 +35,7 @@ defined( 'THE_SEO_FRAMEWORK_DIR_PATH' ) or die;
35
* 2. Now flushes the rules on shutdown.
36
* @since 2.8.0: Added namespace and renamed function.
37
* @access private
38
- * @global object $wp_rewrite
39
*/
40
function _deactivation_unset_sitemap() {
41
@@ -49,13 +49,14 @@ function _deactivation_unset_sitemap() {
49
* Turns off autoloading for The SEO Framework main options.
50
*
51
* @since 2.9.2
52
* @access private
53
*/
54
function _deactivation_unset_options_autoload() {
55
56
$the_seo_framework = \the_seo_framework();
57
58
- if ( isset( $the_seo_framework ) ) {
59
$options = $the_seo_framework->get_all_options();
60
$setting = THE_SEO_FRAMEWORK_SITE_OPTIONS;
61
@@ -63,8 +64,11 @@ function _deactivation_unset_options_autoload() {
63
\remove_all_actions( "update_option_{$setting}" );
64
\remove_all_filters( "sanitize_option_{$setting}" );
65
66
- // Set to false, so we can reset the options.
67
- $_success = \update_option( $setting, false );
68
if ( $_success )
69
\update_option( $setting, $options, 'no' );
70
}
4
*/
5
namespace The_SEO_Framework;
6
7
+ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
9
/**
10
* The SEO Framework plugin
35
* 2. Now flushes the rules on shutdown.
36
* @since 2.8.0: Added namespace and renamed function.
37
* @access private
38
+ * @global \WP_Rewrite $wp_rewrite
39
*/
40
function _deactivation_unset_sitemap() {
41
49
* Turns off autoloading for The SEO Framework main options.
50
*
51
* @since 2.9.2
52
+ * @since 3.1.0 No longer deletes the whole option array, trying to reactivate auto loading.
53
* @access private
54
*/
55
function _deactivation_unset_options_autoload() {
56
57
$the_seo_framework = \the_seo_framework();
58
59
+ if ( $the_seo_framework->loaded ) {
60
$options = $the_seo_framework->get_all_options();
61
$setting = THE_SEO_FRAMEWORK_SITE_OPTIONS;
62
64
\remove_all_actions( "update_option_{$setting}" );
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
+
71
+ $_success = \update_option( $setting, $temp_options, 'no' );
72
if ( $_success )
73
\update_option( $setting, $options, 'no' );
74
}
bootstrap/define.php ADDED
@@ -0,0 +1,126 @@
1
+ <?php
2
+ /**
3
+ * @package The_SEO_Framework/Bootstrap
4
+ */
5
+
6
+ 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
14
+ * by the Free Software Foundation.
15
+ *
16
+ * This program is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
+ */
24
+
25
+ /**
26
+ * Tells the world the plugin is present and to be used.
27
+ * @since 3.1.0
28
+ */
29
+ define( 'THE_SEO_FRAMEWORK_PRESENT', true );
30
+
31
+ /**
32
+ * The plugin options database option_name key.
33
+ *
34
+ * Used for storing the SEO options array.
35
+ *
36
+ * @since 2.2.2
37
+ * @param string THE_SEO_FRAMEWORK_SITE_OPTIONS
38
+ */
39
+ define( 'THE_SEO_FRAMEWORK_SITE_OPTIONS', (string) apply_filters( 'the_seo_framework_site_options', 'autodescription-site-settings' ) );
40
+
41
+ /**
42
+ * The plugin network options.
43
+ *
44
+ * Unused in the code.
45
+ *
46
+ * @since 2.2.2
47
+ * @param string THE_SEO_FRAMEWORK_NETWORK_OPTIONS
48
+ */
49
+ define( 'THE_SEO_FRAMEWORK_NETWORK_OPTIONS', (string) apply_filters( 'the_seo_framework_network_settings', 'autodescription-network-settings' ) );
50
+
51
+ /**
52
+ * Plugin term options key.
53
+ * @since 2.7.0
54
+ * @param string THE_SEO_FRAMEWORK_TERM_OPTIONS
55
+ */
56
+ define( 'THE_SEO_FRAMEWORK_TERM_OPTIONS', (string) apply_filters( 'the_seo_framework_term_options', 'autodescription-term-settings' ) );
57
+
58
+ /**
59
+ * Plugin user term options key.
60
+ * @since 2.7.0
61
+ * @param string THE_SEO_FRAMEWORK_USER_OPTIONS
62
+ */
63
+ define( 'THE_SEO_FRAMEWORK_USER_OPTIONS', (string) apply_filters( 'the_seo_framework_user_options', 'autodescription-user-settings' ) );
64
+
65
+ /**
66
+ * Plugin updates cache key.
67
+ * @since 3.1.0
68
+ * @param string THE_SEO_FRAMEWORK_SITE_CACHE
69
+ */
70
+ define( 'THE_SEO_FRAMEWORK_SITE_CACHE', (string) apply_filters( 'the_seo_framework_site_cache', 'autodescription-updates-cache' ) );
71
+
72
+ /**
73
+ * The plugin map URL. Has a trailing slash.
74
+ * Used for calling browser files.
75
+ * @since 2.2.2
76
+ */
77
+ define( 'THE_SEO_FRAMEWORK_DIR_URL', plugin_dir_url( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) );
78
+
79
+ /**
80
+ * The plugin file relative to the plugins dir. Does not have a trailing slash.
81
+ * @since 2.2.8
82
+ */
83
+ define( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME', plugin_basename( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) );
84
+
85
+ /**
86
+ * The plugin map absolute path.
87
+ * Used for calling php files.
88
+ * @since 2.2.2
89
+ */
90
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH', dirname( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ) . DIRECTORY_SEPARATOR );
91
+
92
+ /**
93
+ * The plugin views map absolute path.
94
+ * @since 2.7.0
95
+ */
96
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_VIEWS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR );
97
+
98
+ /**
99
+ * The plugin class map absolute path.
100
+ * @since 2.2.9
101
+ */
102
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_CLASS', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR );
103
+
104
+ /**
105
+ * The plugin trait map absolute path.
106
+ * @since 3.1.0
107
+ */
108
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_TRAIT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'traits' . DIRECTORY_SEPARATOR );
109
+
110
+ /**
111
+ * The plugin interface map absolute path.
112
+ * @since 2.8.0
113
+ */
114
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_INTERFACE', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'interfaces' . DIRECTORY_SEPARATOR );
115
+
116
+ /**
117
+ * The plugin function map absolute path.
118
+ * @since 2.2.9
119
+ */
120
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_FUNCT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR );
121
+
122
+ /**
123
+ * The plugin function map absolute path.
124
+ * @since 2.8.0
125
+ */
126
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_COMPAT', THE_SEO_FRAMEWORK_DIR_PATH . 'inc' . DIRECTORY_SEPARATOR . 'compat' . DIRECTORY_SEPARATOR );
inc/functions/plugin-test-server.php → bootstrap/envtest.php RENAMED
@@ -1,7 +1,13 @@
1
<?php
2
/**
3
* The SEO Framework plugin
4
- * Copyright (C) 2015 - 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
5
*
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 3 as published
@@ -16,34 +22,32 @@
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
- defined( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME' ) or die;
20
-
21
/**
22
* This file holds functions for testing the plugin after upgrade.
23
* This file will only be called ONCE if the required version option is lower
24
* compared to The SEO Framework version constant.
25
*
26
- * @since 2.8.0
27
* @access private
28
*/
29
30
- the_seo_framework_test_server_phase();
31
/**
32
* Tests plugin upgrade.
33
*
34
- * @since 2.8.0
35
- * @since 2.9.4 Changed the testing option from a site option to a blog option.
36
* @access private
37
* @link http://php.net/eol.php
38
* @link https://codex.wordpress.org/WordPress_Versions
39
*/
40
- function the_seo_framework_test_server_phase() {
41
42
$ms = is_multisite();
43
44
- //* @TODO clean this up @ 4.6 requirement. i.e. only check for `get_network()` and $nw->site_id.
45
- //= WP_Network is WP > 4.4.
46
- if ( $ms && class_exists( 'WP_Network', false ) ) {
47
//* Try bypassing testing and deactivation gaming when the main blog has already been tested.
48
49
/**
@@ -52,25 +56,20 @@ function the_seo_framework_test_server_phase() {
52
*/
53
delete_site_option( 'the_seo_framework_tested_upgrade_version' );
54
55
- //= WP < 4.6 doesn't have get_network().
56
- $nw = function_exists( 'get_network' ) ? get_network() : $GLOBALS['current_site'];
57
if ( $nw instanceof WP_Network ) {
58
- //= WP < 4.6 doesn't have property 'site_id'.
59
- $site_id = isset( $nw->site_id ) ? $nw->site_id : (int) $nw->blog_id;
60
-
61
- //= Free memory. Var is not passed by reference, so it's safe.
62
- unset( $nw );
63
-
64
- if ( get_blog_option( $site_id, 'the_seo_framework_tested_upgrade_version' ) ) {
65
update_option( 'the_seo_framework_tested_upgrade_version', THE_SEO_FRAMEWORK_DB_VERSION );
66
return;
67
}
68
}
69
}
70
71
$requirements = array(
72
- 'php' => '50300',
73
- 'wp' => '35700',
74
);
75
76
! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $requirements['php'] and $test = 1
@@ -84,8 +83,8 @@ function the_seo_framework_test_server_phase() {
84
}
85
86
if ( $ms ) {
87
- $plugins = get_site_option( 'active_sitewide_plugins' );
88
- $network_mode = isset( $plugins[ THE_SEO_FRAMEWORK_PLUGIN_BASENAME ] );
89
} else {
90
$network_mode = false;
91
}
@@ -93,35 +92,35 @@ function the_seo_framework_test_server_phase() {
93
if ( ! function_exists( 'deactivate_plugins' ) )
94
require_once ABSPATH . 'wp-admin/includes/plugin.php';
95
96
- $admin = is_admin();
97
$silent = ! $admin;
98
99
//* Not good. Deactivate plugin.
100
- deactivate_plugins( THE_SEO_FRAMEWORK_PLUGIN_BASENAME, $silent, $network_mode );
101
102
- //* Don't die on front-end.
103
if ( ! $admin )
104
return;
105
106
switch ( $test ) :
107
- case 1 :
108
//* PHP requirements not met, always count up to encourage best standards.
109
- $requirement = 'PHP 5.3.0 or later';
110
- $issue = 'PHP version';
111
- $version = phpversion();
112
- $subtitle = 'Server Requirements';
113
break;
114
115
- case 2 :
116
//* WordPress requirements not met.
117
- $requirement = 'WordPress 4.4 or later';
118
- $issue = 'WordPress version';
119
- $version = $GLOBALS['wp_version'];
120
- $subtitle = 'WordPress Requirements';
121
break;
122
123
- default :
124
- wp_die();
125
break;
126
endswitch;
127
1
<?php
2
+ /**
3
+ * @package The_SEO_Framework/Bootstrap
4
+ */
5
+
6
+ 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
22
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23
*/
24
25
/**
26
* This file holds functions for testing the plugin after upgrade.
27
* This file will only be called ONCE if the required version option is lower
28
* compared to The SEO Framework version constant.
29
*
30
+ * @NOTE This file MUST be written according to WordPress' minimum PHP requirements.
31
+ * Which is PHP 5.2.
32
+ *
33
+ * @since 3.1.0
34
* @access private
35
*/
36
37
+ the_seo_framework_pre_boot_test();
38
/**
39
* Tests plugin upgrade.
40
*
41
+ * @since 3.1.0
42
* @access private
43
* @link http://php.net/eol.php
44
* @link https://codex.wordpress.org/WordPress_Versions
45
*/
46
+ function the_seo_framework_pre_boot_test() {
47
48
$ms = is_multisite();
49
50
+ if ( $ms && function_exists( 'get_network' ) ) {
51
//* Try bypassing testing and deactivation gaming when the main blog has already been tested.
52
53
/**
56
*/
57
delete_site_option( 'the_seo_framework_tested_upgrade_version' );
58
59
+ $nw = get_network();
60
if ( $nw instanceof WP_Network ) {
61
+ if ( get_blog_option( $nw->site_id, 'the_seo_framework_tested_upgrade_version' ) ) {
62
update_option( 'the_seo_framework_tested_upgrade_version', THE_SEO_FRAMEWORK_DB_VERSION );
63
return;
64
}
65
}
66
+ //= Free memory.
67
+ unset( $nw );
68
}
69
70
$requirements = array(
71
+ 'php' => '50400',
72
+ 'wp' => '37965',
73
);
74
75
! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $requirements['php'] and $test = 1
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;
90
}
92
if ( ! function_exists( 'deactivate_plugins' ) )
93
require_once ABSPATH . 'wp-admin/includes/plugin.php';
94
95
+ $admin = is_admin();
96
$silent = ! $admin;
97
98
//* Not good. Deactivate plugin.
99
+ deactivate_plugins( plugin_basename( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE ), $silent, $network_mode );
100
101
+ //* Don't die on front-end. Live, my friend.
102
if ( ! $admin )
103
return;
104
105
switch ( $test ) :
106
+ case 1:
107
//* PHP requirements not met, always count up to encourage best standards.
108
+ $requirement = 'PHP 5.4.0 or later';
109
+ $issue = 'PHP version';
110
+ $version = PHP_VERSION;
111
+ $subtitle = 'Server Requirements';
112
break;
113
114
+ case 2:
115
//* WordPress requirements not met.
116
+ $requirement = 'WordPress 4.6 or later';
117
+ $issue = 'WordPress version';
118
+ $version = $GLOBALS['wp_version'];
119
+ $subtitle = 'WordPress Requirements';
120
break;
121
122
+ default:
123
+ wp_die( 'oi' );
124
break;
125
endswitch;
126
bootstrap/index.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+ /**
3
+ * Well-lit streets discourage sin, but don't overdo it.
4
+ *
5
+ * - William J. Kennedy
6
+ */
bootstrap/load.php ADDED
@@ -0,0 +1,168 @@
1
+ <?php
2
+ /**
3
+ * @package The_SEO_Framework/Bootstrap
4
+ */
5
+ namespace The_SEO_Framework;
6
+
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
15
+ * by the Free Software Foundation.
16
+ *
17
+ * This program is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License
23
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
24
+ */
25
+
26
+ \add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_locale', 4 );
27
+ /**
28
+ * Plugin locale 'autodescription'
29
+ * Files located in plugin folder `../autodescription/language/`
30
+ * @since 2.8.0
31
+ */
32
+ function _init_locale() {
33
+ /**
34
+ * @since 1.0.0
35
+ */
36
+ \load_plugin_textdomain(
37
+ 'autodescription',
38
+ false,
39
+ THE_SEO_FRAMEWORK_DIR_PATH . 'language'
40
+ );
41
+ }
42
+
43
+ \add_action( 'plugins_loaded', __NAMESPACE__ . '\\_init_tsf', 5 );
44
+ /**
45
+ * Load The_SEO_Framework_Load class
46
+ *
47
+ * @action plugins_loaded
48
+ * @priority 5 Use anything above 5, or any action later than plugins_loaded and
49
+ * you can access the class and functions.
50
+ *
51
+ * @since 3.1.0
52
+ * @access private
53
+ * @see function the_seo_framework().
54
+ * @staticvar object $tsf
55
+ * @factory
56
+ *
57
+ * @return object|null The SEO Framework Facade class object. Null on failure.
58
+ */
59
+ function _init_tsf() {
60
+
61
+ //* Cache the class. Do not run constructors more than once.
62
+ static $tsf = null;
63
+
64
+ if ( $tsf )
65
+ return $tsf;
66
+
67
+ /**
68
+ * @package The_SEO_Framework
69
+ */
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
+ /**
77
+ * Runs after TSF is loaded in the admin.
78
+ * @since 3.1.0
79
+ */
80
+ \do_action( 'the_seo_framework_admin_loaded' );
81
+ } else {
82
+ $tsf = new \The_SEO_Framework\Load();
83
+ $tsf->loaded = true;
84
+ }
85
+
86
+ /**
87
+ * Runs after TSF is loaded.
88
+ * @since 3.1.0
89
+ */
90
+ \do_action( 'the_seo_framework_loaded' );
91
+ } else {
92
+ $tsf = new \The_SEO_Framework\Silencer();
93
+ $tsf->loaded = false;
94
+ }
95
+
96
+ // did_action() checks for current action too.
97
+ if ( false === \did_action( 'plugins_loaded' ) )
98
+ $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' );
99
+
100
+ return $tsf;
101
+ }
102
+
103
+ spl_autoload_register( __NAMESPACE__ . '\\_autoload_classes', true, true );
104
+ /**
105
+ * Autoloads all class files. To be used when requiring access to all or any of
106
+ * the plugin classes.
107
+ *
108
+ * @since 2.8.0
109
+ * @since 3.1.0 1. No longer maintains cache.
110
+ * 2. Now always returns void.
111
+ * @uses THE_SEO_FRAMEWORK_DIR_PATH_CLASS
112
+ * @access private
113
+ *
114
+ * @NOTE 'The_SEO_Framework\' is a reserved namespace. Using it outside of this
115
+ * plugin's scope coul result in an error.
116
+ *
117
+ * @param string $class The class name.
118
+ * @return void Early if the class is not within the current namespace.
119
+ */
120
+ function _autoload_classes( $class ) {
121
+
122
+ if ( 0 !== strpos( $class, 'The_SEO_Framework\\', 0 ) )
123
+ return;
124
+
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...
136
+ if ( 0 === strpos( $class, 'The_SEO_Framework\\Builders\\' ) ) {
137
+ $path .= 'builders' . DIRECTORY_SEPARATOR;
138
+ $strip .= 'Builders\\';
139
+ }
140
+ }
141
+
142
+ $class = strtolower( str_replace( $strip, '', $class ) );
143
+ $class = str_replace( '_', '-', $class );
144
+
145
+ require $path . $class . $extension;
146
+ }
147
+
148
+ \add_action( 'activate_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, __NAMESPACE__ . '\\_do_plugin_activation' );
149
+ /**
150
+ * Performs plugin activation actions.
151
+ *
152
+ * @since 2.8.0
153
+ * @access private
154
+ */
155
+ function _do_plugin_activation() {
156
+ require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'activation.php';
157
+ }
158
+
159
+ \add_action( 'deactivate_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, __NAMESPACE__ . '\\_do_plugin_deactivation' );
160
+ /**
161
+ * Performs plugin deactivation actions.
162
+ *
163
+ * @since 2.8.0
164
+ * @access private
165
+ */
166
+ function _do_plugin_deactivation() {
167
+ require THE_SEO_FRAMEWORK_BOOTSTRAP_PATH . 'deactivation.php';
168
+ }
bootstrap/upgrade.php ADDED
@@ -0,0 +1,435 @@
1
+ <?php
2
+ /**
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
12
+ * by the Free Software Foundation.
13
+ *
14
+ * This program is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
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
28
+ * compared to The SEO Framework version constant.
29
+ *
30
+ * @since 2.7.0
31
+ * @access private
32
+ * @TODO convert to class, see \TSF_Extension_Manager\Upgrader
33
+ * It's a generator/iterator, so we must wait to PHP>5.5 support.
34
+ */
35
+
36
+ /**
37
+ * Returns the default site options.
38
+ *
39
+ * @since 3.1.0
40
+ * @staticvar array $cache
41
+ *
42
+ * @return array The default site options.
43
+ */
44
+ function the_seo_framework_upgrade_default_site_options() {
45
+ static $cache;
46
+ return isset( $cache ) ? $cache : $cache = the_seo_framework()->get_default_site_options();
47
+ }
48
+
49
+ the_seo_framework_previous_db_version(); // sets cache.
50
+ /**
51
+ * Returns the version set before upgrading began.
52
+ *
53
+ * @since 3.0.0
54
+ * @staticvar string $cache
55
+ *
56
+ * @return string The prior-to-upgrade TSF db version.
57
+ */
58
+ function the_seo_framework_previous_db_version() {
59
+ static $cache;
60
+ return isset( $cache ) ? $cache : $cache = get_option( 'the_seo_framework_upgraded_db_version', '0' );
61
+ }
62
+
63
+ add_action( 'init', 'the_seo_framework_do_upgrade', 20 );
64
+ /**
65
+ * Upgrade The SEO Framework to the latest version.
66
+ *
67
+ * Does an iteration of upgrades in order of upgrade appearance.
68
+ * Each called function will upgrade the version by its iteration.
69
+ *
70
+ * @thanks StudioPress for some code.
71
+ * @since 2.7.0
72
+ * @since 2.9.4 No longer tests WP version. This file won't be loaded anyway if rendered incompatible.
73
+ * @since 3.0.0 Fewer option calls are now made when version is higher than former checks.
74
+ * @since 3.1.0 1. Now always updates the database version to the current version, even if it's ahead.
75
+ * 2. No longer checks for WordPress upgrade, this is handled by WordPress in ..\wp-admin\admin.php, before admin_init.
76
+ * 3. Now sets the initial database version to the previous version (if known), or the current version.
77
+ * 4. Now redirects from the SEO settings page, as the options can conflict during upgrade.
78
+ * 5. Now always flushes rewrite rules after an upgrade.
79
+ * 6. Now registers the settings on the first run.
80
+ * 7. Now checks if The SEO Framework is loaded.
81
+ * 8. Now tries to increase memory limit. This probably isn't needed.
82
+ * 9. Now runs on the front-end, too, via `init`, instead of `admin_init`.
83
+ * @since 3.1.4 Now flushes object cache before the upgrade settings are called.
84
+ */
85
+ function the_seo_framework_do_upgrade() {
86
+
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
+
94
+ \wp_raise_memory_limit( 'tsf_upgrade' );
95
+
96
+ /**
97
+ * From WordPress' .../update-core.php
98
+ * @since 3.1.4
99
+ */
100
+ // Clear the cache to prevent an update_option() from saving a stale database version to the cache
101
+ wp_cache_flush();
102
+ // (Not all cache back ends listen to 'flush')
103
+ wp_cache_delete( 'alloptions', 'options' );
104
+
105
+ $version = the_seo_framework_previous_db_version();
106
+
107
+ if ( ! get_option( 'the_seo_framework_initial_db_version' ) ) {
108
+ //* Sets to previous if previous is known. This is a late addition.
109
+ update_option( 'the_seo_framework_initial_db_version', $version ?: THE_SEO_FRAMEWORK_DB_VERSION, 'no' );
110
+ }
111
+
112
+ if ( $version >= THE_SEO_FRAMEWORK_DB_VERSION ) {
113
+ the_seo_framework_upgrade_to_current();
114
+ return;
115
+ }
116
+
117
+ if ( ! $version ) {
118
+ the_seo_framework_do_upgrade_1();
119
+ $version = '1';
120
+ }
121
+ if ( $version < '2701' ) {
122
+ the_seo_framework_do_upgrade_2701();
123
+ $version = '2701';
124
+ }
125
+ if ( $version < '2802' ) {
126
+ the_seo_framework_do_upgrade_2802();
127
+ $version = '2802';
128
+ }
129
+ if ( $version < '2900' ) {
130
+ the_seo_framework_do_upgrade_2900();
131
+ $version = '2900';
132
+ }
133
+ if ( $version < '3001' ) {
134
+ the_seo_framework_do_upgrade_3001();
135
+ $version = '3001';
136
+ }
137
+ if ( $version < '3060' ) {
138
+ the_seo_framework_do_upgrade_3060();
139
+ $version = '3060';
140
+ }
141
+
142
+ //! From here, the upgrade procedures should be backward compatible.
143
+ //? This means no data may be erased for at least 1 major version, or 1 year, whichever is later.
144
+ if ( $version < '3103' ) {
145
+ the_seo_framework_do_upgrade_3103();
146
+ $version = '3103';
147
+ }
148
+
149
+ /**
150
+ * @since 2.7.0
151
+ */
152
+ do_action( 'the_seo_framework_upgraded' );
153
+ }
154
+
155
+ add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_to_current' );
156
+ /**
157
+ * Upgrades the Database version to the latest version.
158
+ *
159
+ * This happens if all iterations have been executed. This ensure this file will
160
+ * no longer be required.
161
+ * This should run once after every plugin update.
162
+ *
163
+ * @since 2.7.0
164
+ * @since 3.1.4 Now flushes the object cache after the setting's updated.
165
+ */
166
+ function the_seo_framework_upgrade_to_current() {
167
+ update_option( 'the_seo_framework_upgraded_db_version', THE_SEO_FRAMEWORK_DB_VERSION );
168
+
169
+ /**
170
+ * From WordPress' .../update-core.php
171
+ * @since 3.1.4
172
+ */
173
+ // Clear the cache to prevent a get_option() from retrieving a stale database version to the cache
174
+ wp_cache_flush();
175
+ // (Not all cache back ends listen to 'flush')
176
+ wp_cache_delete( 'alloptions', 'options' );
177
+ }
178
+
179
+ add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_reinitialize_rewrite', 99 );
180
+ /**
181
+ * Reinitializes the rewrite cache.
182
+ *
183
+ * This happens after the plugin's upgraded, because it's not critical, and when
184
+ * this fails, the upgrader won't be locked.
185
+ *
186
+ * @since 3.1.2
187
+ */
188
+ function the_seo_framework_upgrade_reinitialize_rewrite() {
189
+ the_seo_framework()->reinitialize_rewrite();
190
+ }
191
+
192
+ add_action( 'the_seo_framework_upgraded', 'the_seo_framework_prepare_extension_manager_suggestion', 100 );
193
+ /**
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
200
+ */
201
+ function the_seo_framework_prepare_extension_manager_suggestion() {
202
+ static $run = false;
203
+ if ( $run ) return;
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 );
210
+ }
211
+
212
+ $run = true;
213
+ }
214
+
215
+ /**
216
+ * Lists and returns upgrade notices to be outputted in admin.
217
+ *
218
+ * @since 2.9.0
219
+ * @staticvar array $cache The cached notice strings.
220
+ *
221
+ * @param string $notice The upgrade notice.
222
+ * @param bool $get Whether to return the upgrade notices.
223
+ * @return array|void The notices when $get is true.
224
+ */
225
+ function the_seo_framework_add_upgrade_notice( $notice = '', $get = false ) {
226
+
227
+ static $cache = [];
228
+
229
+ if ( $get )
230
+ return $cache;
231
+
232
+ $cache[] = $notice;
233
+ }
234
+
235
+ add_action( 'admin_notices', 'the_seo_framework_output_upgrade_notices' );
236
+ /**
237
+ * Outputs available upgrade notices.
238
+ *
239
+ * @since 2.9.0
240
+ * @since 3.0.0 Added prefix.
241
+ * @uses the_seo_framework_add_upgrade_notice()
242
+ */
243
+ function the_seo_framework_output_upgrade_notices() {
244
+
245
+ $notices = the_seo_framework_add_upgrade_notice( '', true );
246
+
247
+ foreach ( $notices as $notice ) {
248
+ //* @TODO rtl?
249
+ the_seo_framework()->do_dismissible_notice( 'SEO: ' . $notice, 'updated' );
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Sets initial values for The SEO Framework.
255
+ *
256
+ * @since 3.1.0
257
+ */
258
+ function the_seo_framework_do_upgrade_1() {
259
+ the_seo_framework()->register_settings();
260
+ update_option( 'the_seo_framework_upgraded_db_version', '1' );
261
+ }
262
+
263
+ /**
264
+ * Upgrades term metadata for version 2701.
265
+ *
266
+ * @since 2.7.0
267
+ * @since 3.1.0 No longer tries to set term meta for ID 0.
268
+ * `add_metadata()` already blocked this, this is defensive.
269
+ */
270
+ function the_seo_framework_do_upgrade_2701() {
271
+
272
+ $term_meta = get_option( 'autodescription-term-meta' );
273
+
274
+ if ( $term_meta ) {
275
+ foreach ( (array) $term_meta as $term_id => $meta ) {
276
+ add_term_meta( $term_id, THE_SEO_FRAMEWORK_TERM_OPTIONS, $meta, true );
277
+ }
278
+
279
+ //= Rudimentary test for remaining ~300 users of the past passed, set initial version to 2600.
280
+ update_option( 'the_seo_framework_initial_db_version', '2600', 'no' );
281
+ }
282
+
283
+ update_option( 'the_seo_framework_upgraded_db_version', '2701' );
284
+ }
285
+
286
+ /**
287
+ * Removes term metadata for version 2802.
288
+ * Reinitializes rewrite data for for sitemap stylesheet.
289
+ *
290
+ * @since 2.8.0
291
+ */
292
+ function the_seo_framework_do_upgrade_2802() {
293
+
294
+ //* Delete old values from database. Removes backwards compatibility.
295
+ if ( get_option( 'the_seo_framework_initial_db_version' ) < '2701' )
296
+ delete_option( 'autodescription-term-meta' );
297
+
298
+ update_option( 'the_seo_framework_upgraded_db_version', '2802' );
299
+ }
300
+
301
+ /**
302
+ * Updates Twitter 'photo' card option to 'summary_large_image'.
303
+ *
304
+ * @since 2.9.0
305
+ * @since 3.1.0 Now only sets new options when defaults exists.
306
+ */
307
+ function the_seo_framework_do_upgrade_2900() {
308
+
309
+ if ( get_option( 'the_seo_framework_initial_db_version' ) < '2900' ) {
310
+ $defaults = the_seo_framework_upgrade_default_site_options();
311
+
312
+ if ( isset( $defaults['twitter_card'] ) ) {
313
+ $tsf = the_seo_framework();
314
+
315
+ $card_type = trim( esc_attr( $tsf->get_option( 'twitter_card', false ) ) );
316
+ if ( 'photo' === $card_type ) {
317
+ $tsf->update_option( 'twitter_card', 'summary_large_image' );
318
+ the_seo_framework_add_upgrade_notice(
319
+ esc_html__( 'Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable.', 'autodescription' )
320
+ );
321
+ }
322
+ }
323
+ }
324
+
325
+ update_option( 'the_seo_framework_upgraded_db_version', '2900' );
326
+ }
327
+
328
+ /**
329
+ * Converts sitemap timestamp settings to global timestamp settings.
330
+ * Adds new character counter settings.
331
+ *
332
+ * @since 3.0.0
333
+ * @since 3.0.6 'display_character_counter' option now correctly defaults to 1.
334
+ * @since 3.1.0 Now only sets new options when defaults exist, and when it's an upgraded site.
335
+ */
336
+ function the_seo_framework_do_upgrade_3001() {
337
+
338
+ if ( get_option( 'the_seo_framework_initial_db_version' ) < '3001' ) {
339
+ $tsf = the_seo_framework();
340
+
341
+ $defaults = the_seo_framework_upgrade_default_site_options();
342
+
343
+ if ( isset( $defaults['timestamps_format'] ) ) {
344
+ //= Only change if old option exists. Falls back to default upgrader otherwise.
345
+ $sitemap_timestamps = $tsf->get_option( 'sitemap_timestamps', false );
346
+ $tsf->update_option( 'timestamps_format', (string) (int) $sitemap_timestamps ?: $defaults['timestamps_format'] );
347
+ if ( '' !== $sitemap_timestamps ) {
348
+ the_seo_framework_add_upgrade_notice(
349
+ esc_html__( 'The previous sitemap timestamp settings have been converted into new global timestamp settings.', 'autodescription' )
350
+ );
351
+ }
352
+ }
353
+
354
+ if ( isset( $defaults['display_character_counter'] ) )
355
+ $tsf->update_option( 'display_character_counter', $defaults['display_character_counter'] );
356
+
357
+ if ( isset( $defaults['display_pixel_counter'] ) )
358
+ $tsf->update_option( 'display_pixel_counter', $defaults['display_pixel_counter'] );
359
+ }
360
+
361
+ update_option( 'the_seo_framework_upgraded_db_version', '3001' );
362
+ }
363
+
364
+ /**
365
+ * Loads suggestion for TSFEM.
366
+ * Also deletes sitemap cache.
367
+ *
368
+ * @since 3.0.6
369
+ */
370
+ function the_seo_framework_do_upgrade_3060() {
371
+
372
+ if ( get_option( 'the_seo_framework_initial_db_version' ) < '3060' )
373
+ the_seo_framework()->delete_cache( 'sitemap' );
374
+
375
+ update_option( 'the_seo_framework_upgraded_db_version', '3060' );
376
+ }
377
+
378
+ /**
379
+ * Adds global cache option.
380
+ * Sets `auto_description` option.
381
+ * Migrates `title_seperator` option to `title_separator`.
382
+ * Sets `sitemap_query_limit` option.
383
+ * Sets `title_strip_tags` option to known behavior.
384
+ * Migrates `attachment_noindex` option to post type settings.
385
+ * Migrates `attachment_nofollow` option to post type settings.
386
+ * Migrates `attachment_noarchive` option to post type settings.
387
+ *
388
+ * Loads suggestion for TSFEM.
389
+ *
390
+ * @since 3.1.0
391
+ */
392
+ function the_seo_framework_do_upgrade_3103() {
393
+
394
+ // Prevent database lookups when checking for cache.
395
+ add_option( THE_SEO_FRAMEWORK_SITE_CACHE, [] );
396
+
397
+ // If it's an older installation, upgrade these options.
398
+ if ( get_option( 'the_seo_framework_initial_db_version' ) < '3103' ) {
399
+ $tsf = the_seo_framework();
400
+
401
+ $defaults = the_seo_framework_upgrade_default_site_options();
402
+
403
+ // Transport title separator.
404
+ if ( isset( $defaults['title_separator'] ) )
405
+ $tsf->update_option( 'title_separator', $tsf->get_option( 'title_seperator' ) ?: $defaults['title_separator'] );
406
+
407
+ // Transport attachment_noindex, attachment_nofollow, and attachment_noarchive settings.
408
+ foreach ( [ 'noindex', 'nofollow', 'noarchive' ] as $r ) {
409
+ $_option = $tsf->get_robots_post_type_option_id( $r );
410
+ if ( isset( $defaults[ $_option ] ) ) {
411
+ $_value = (array) ( $tsf->get_option( $_option ) ?: $defaults[ $_option ] );
412
+ $_value['attachment'] = (int) (bool) $tsf->get_option( "attachment_$r" );
413
+ $tsf->update_option( $_option, $_value );
414
+ }
415
+ }
416
+
417
+ // Adds default auto description option.
418
+ if ( isset( $defaults['auto_description'] ) )
419
+ $tsf->update_option( 'auto_description', $defaults['auto_description'] );
420
+
421
+ // Add default sitemap limit option.
422
+ if ( isset( $defaults['sitemap_query_limit'] ) )
423
+ $tsf->update_option( 'sitemap_query_limit', $defaults['sitemap_query_limit'] );
424
+
425
+ // Add non-default HTML stripping option. Defaulting to previous behavior.
426
+ if ( isset( $defaults['title_strip_tags'] ) )
427
+ $tsf->update_option( 'title_strip_tags', 0 );
428
+
429
+ // Adds non-default priority option.
430
+ if ( isset( $defaults['sitemaps_priority'] ) )
431
+ $tsf->update_option( 'sitemaps_priority', 1 );
432
+ }
433
+
434
+ update_option( 'the_seo_framework_upgraded_db_version', '3103' );
435
+ }
inc/classes/admin-init.class.php CHANGED
@@ -4,7 +4,7 @@
4
*/
5
namespace The_SEO_Framework;
6
7
- defined( 'ABSPATH' ) or die;
8
9
/**
10
* The SEO Framework plugin
@@ -34,173 +34,295 @@ defined( 'ABSPATH' ) or die;
34
class Admin_Init extends Init {
35
36
/**
37
- * The page base file.
38
*
39
- * @since 2.5.2.2
40
*
41
- * @var string Holds Admin page base file.
42
*/
43
- protected $page_base_file;
44
45
- /**
46
- * JavaScript name identifier to be used with enqueuing.
47
- *
48
- * @since 2.5.2.2
49
- * @since 2.8.0 Renamed
50
- *
51
- * @var string JavaScript name identifier.
52
- */
53
- public $js_name = 'tsf';
54
55
- /**
56
- * CSS script name identifier to be used with enqueuing.
57
- *
58
- * @since 2.6.0
59
- * @since 2.8.0 Renamed
60
- *
61
- * @var string CSS name identifier.
62
- */
63
- public $css_name = 'tsf';
64
65
- /**
66
- * Constructor. Loads parent constructor, registers script names and adds actions.
67
- */
68
- protected function __construct() {
69
- parent::__construct();
70
}
71
72
/**
73
- * Enqueues scripts in the admin area on the supported screens.
74
*
75
- * @since 2.3.3
76
*
77
- * @param string $hook The current page hook.
78
*/
79
- public function enqueue_admin_scripts( $hook ) {
80
-
81
- $enqueue_hooks = array(
82
- 'edit.php',
83
- 'post.php',
84
- 'post-new.php',
85
- 'edit-tags.php',
86
- 'term.php',
87
- );
88
-
89
- if ( ! $this->is_option_checked( 'display_seo_bar_tables' ) ) {
90
- $enqueue_hooks = array_diff( $enqueue_hooks, array( 'edit.php', 'edit-tags.php' ) );
91
- }
92
-
93
- /**
94
- * Check hook first.
95
- * @since 2.3.9
96
- */
97
- if ( isset( $hook ) && $hook && in_array( $hook, $enqueue_hooks, true ) ) {
98
- /**
99
- * @uses $this->post_type_supports_custom_seo()
100
- * @since 2.3.9
101
- */
102
- if ( $this->post_type_supports_custom_seo() )
103
- $this->init_admin_scripts();
104
- }
105
}
106
107
/**
108
* Registers admin scripts and styles.
109
*
110
* @since 2.6.0
111
*
112
- * @param bool $direct Whether to directly include the files, or let the action handler do it.
113
*/
114
- public function init_admin_scripts( $direct = false ) {
115
116
- if ( $direct ) {
117
- $this->enqueue_admin_css( $this->page_base_file );
118
- $this->enqueue_admin_javascript( $this->page_base_file );
119
- } else {
120
- \add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_css' ), 1 );
121
- \add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_javascript' ), 1 );
122
- }
123
- }
124
125
- /**
126
- * Enqueues scripts.
127
- *
128
- * @since 2.0.2
129
- * @since 3.0.6 Now attaches the post ID to `wp_enqueue_media` on post edit.
130
- *
131
- * @param string $hook The current page hook.
132
- */
133
- public function enqueue_admin_javascript( $hook ) {
134
135
/**
136
- * Put hook and js name in class vars.
137
- * @since 2.5.2.2
138
*/
139
- $this->page_base_file = $this->page_base_file ?: $hook;
140
-
141
- //* Register the script.
142
- $this->_register_admin_javascript();
143
144
if ( $this->is_post_edit() ) {
145
- \wp_enqueue_media( array( 'post' => $this->get_the_real_admin_ID() ) );
146
} elseif ( $this->is_seo_settings_page() ) {
147
- \wp_enqueue_media();
148
- }
149
-
150
- if ( $this->is_seo_settings_page() )
151
\wp_enqueue_script( 'wp-color-picker' );
152
-
153
- \wp_enqueue_script( $this->js_name );
154
-
155
- /**
156
- * Localize JavaScript.
157
- * @since 2.5.2.2
158
- */
159
- \add_action( 'admin_footer', array( $this, '_localize_admin_javascript' ) );
160
}
161
162
/**
163
- * Registers admin CSS.
164
- *
165
- * @since 2.6.0
166
- * @staticvar bool $registered : Prevents Re-registering of the style.
167
- * @access private
168
*
169
- * @return void Early if already registered.
170
*/
171
- public function _register_admin_javascript() {
172
-
173
- static $registered = null;
174
-
175
- if ( isset( $registered ) )
176
- return;
177
-
178
- $suffix = $this->script_debug ? '' : '.min';
179
180
- \wp_register_script( $this->js_name, THE_SEO_FRAMEWORK_DIR_URL . "lib/js/{$this->js_name}{$suffix}.js", array( 'jquery' ), THE_SEO_FRAMEWORK_VERSION, true );
181
182
- $registered = true;
183
}
184
185
/**
186
- * Localizes admin javascript.
187
*
188
- * @since 2.5.2.2
189
- * @staticvar bool $localized : Prevents Re-registering of the l10n.
190
- * @access private
191
*/
192
- public function _localize_admin_javascript() {
193
194
- static $localized = null;
195
196
- if ( isset( $localized ) )
197
- return;
198
199
- $strings = $this->get_javascript_l10n();
200
201
- \wp_localize_script( $this->js_name, "{$this->js_name}L10n", $strings );
202
203
- $localized = true;
204
}
205
206
/**
@@ -223,19 +345,15 @@ class Admin_Init extends Init {
223
protected function get_javascript_l10n() {
224
225
$id = $this->get_the_real_ID();
226
- $blog_name = $this->get_blogname();
227
- $description = $this->get_blogdescription();
228
$default_title = '';
229
- $additions = '';
230
231
- $use_additions = (bool) $this->get_option( 'homepage_tagline' );
232
$home_tagline = $this->get_option( 'homepage_title_tagline' );
233
$title_location = $this->get_option( 'title_location' );
234
- $title_add_additions = $this->add_title_additions();
235
- $counter_type = (int) $this->get_user_option( 0, 'counter_type', 3 );
236
237
- $title_separator = $this->get_separator( 'title' );
238
- $description_separator = $this->get_separator( 'description' );
239
240
$ishome = false;
241
$is_settings_page = $this->is_seo_settings_page();
@@ -243,199 +361,173 @@ class Admin_Init extends Init {
243
$is_term_edit = $this->is_term_edit();
244
$has_input = $is_settings_page || $is_post_edit || $is_term_edit;
245
246
- $post_type = $is_post_edit ? \get_post_type( $id ) : false;
247
- $_taxonomies = $post_type ? $this->get_hierarchical_taxonomies_as( 'objects', $post_type ) : array();
248
249
- $taxonomies = array();
250
-
251
- foreach ( $_taxonomies as $_t ) {
252
- $_i18n_name = strtolower( $_t->labels->singular_name );
253
- $taxonomies[ $_t->name ] = array(
254
- 'name' => $_t->name,
255
- 'i18n' => array(
256
- /* translators: %s = term name */
257
- 'makePrimary' => sprintf( \esc_html__( 'Make primary %s', 'autodescription' ), $_i18n_name ),
258
- /* translators: %s = term name */
259
- 'primary' => sprintf( \esc_html__( 'Primary %s', 'autodescription' ), $_i18n_name ),
260
- ),
261
- 'primary' => $this->get_primary_term_id( $id, $_t->name ) ?: 0,
262
- );
263
- }
264
265
- if ( isset( $this->page_base_file ) && $this->page_base_file ) {
266
// We're somewhere within default WordPress pages.
267
if ( $this->is_static_frontpage( $id ) ) {
268
- $default_title = $this->get_option( 'homepage_title' ) ?: $blog_name;
269
$title_location = $this->get_option( 'home_title_location' );
270
$ishome = true;
271
272
- if ( $use_additions ) {
273
- $additions = $home_tagline ?: $description;
274
- } else {
275
- $additions = '';
276
- }
277
} elseif ( $is_post_edit ) {
278
- //* We're on post.php
279
- $generated_doctitle_args = array(
280
- 'term_id' => $id,
281
- 'notagline' => true,
282
- 'get_custom_field' => false,
283
- );
284
-
285
- $default_title = $this->title( '', '', '', $generated_doctitle_args );
286
-
287
- if ( $title_add_additions ) {
288
- $additions = $blog_name;
289
- $use_additions = true;
290
- } else {
291
- $additions = '';
292
- $use_additions = false;
293
- }
294
} elseif ( $is_term_edit ) {
295
//* Category or Tag.
296
- if ( isset( $GLOBALS['current_screen']->taxonomy ) && $id ) {
297
- $default_title = $this->single_term_title( '', false, $this->fetch_the_term( $id ) );
298
- $additions = $title_add_additions ? $blog_name : '';
299
}
300
} else {
301
//* We're in a special place.
302
// Can't fetch title.
303
$default_title = '';
304
- $additions = $title_add_additions ? $blog_name : '';
305
- }
306
- } elseif ( $is_settings_page ) {
307
- // We're on our SEO settings pages.
308
- if ( $this->has_page_on_front() ) {
309
- // Home is a page.
310
- $id = \get_option( 'page_on_front' );
311
- $inpost_title = $this->get_custom_field( '_genesis_title', $id );
312
- } else {
313
- // Home is a blog.
314
- $inpost_title = '';
315
}
316
- $default_title = $inpost_title ?: $blog_name;
317
- $additions = $home_tagline ?: $description;
318
}
319
320
- $this->set_js_nonces( array(
321
/**
322
* Use $this->get_settings_capability() ?... might conflict with other nonces.
323
*/
324
// 'manage_options' => \current_user_can( 'manage_options' ) ? \wp_create_nonce( 'tsf-ajax-manage_options' ) : false,
325
'upload_files' => \current_user_can( 'upload_files' ) ? \wp_create_nonce( 'tsf-ajax-upload_files' ) : false,
326
- 'edit_posts' => \current_user_can( 'edit_posts' ) ? \wp_create_nonce( 'tsf-ajax-edit_posts' ) : false,
327
- ) );
328
329
$term_name = '';
330
$use_term_prefix = false;
331
if ( $is_term_edit ) {
332
- $_term = $this->fetch_the_term( $id );
333
- $term_name = $this->get_the_term_name( $_term, true, false );
334
- $use_term_prefix = $this->use_archive_prefix( $_term );
335
}
336
337
- $l10n = array(
338
'nonces' => $this->get_js_nonces(),
339
- 'states' => array(
340
- 'isRTL' => (bool) \is_rtl(),
341
- 'isHome' => $ishome,
342
- 'hasInput' => $has_input,
343
- 'counterType' => \absint( $counter_type ),
344
- 'useTagline' => $use_additions,
345
- 'useTermPrefix' => $use_term_prefix,
346
- 'isSettingsPage' => $is_settings_page,
347
- 'isPostEdit' => $is_post_edit,
348
- 'isTermEdit' => $is_term_edit,
349
- 'postType' => $post_type,
350
- 'taxonomies' => $taxonomies,
351
- 'isPrivate' => $has_input && $id && $this->is_private( $id ),
352
- 'isPasswordProtected' => $has_input && $id && $this->is_password_protected( $id ),
353
- 'debug' => $this->script_debug,
354
- ),
355
- 'i18n' => array(
356
- 'saveAlert' => \__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
357
- 'confirmReset' => \__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
358
- 'good' => \__( 'Good', 'autodescription' ),
359
- 'okay' => \__( 'Okay', 'autodescription' ),
360
- 'bad' => \__( 'Bad', 'autodescription' ),
361
- 'unknown' => \__( 'Unknown', 'autodescription' ),
362
- 'privateTitle' => $has_input && $id ? \__( 'Private:', 'autodescription' ) : '',
363
- 'protectedTitle' => $has_input && $id ? \__( 'Protected:', 'autodescription' ) : '',
364
/* translators: Pixel counter. 1: width, 2: guideline */
365
- 'pixelsUsed' => $has_input ? \__( '%1$d out of %2$d pixels are used.', 'autodescription' ) : '',
366
- ),
367
- 'params' => array(
368
- 'objectTitle' => $default_title,
369
- 'defaultTitle' => $default_title,
370
- 'titleAdditions' => $additions,
371
- 'blogDescription' => $description,
372
- 'termName' => $term_name,
373
- 'untitledTitle' => $this->untitled(),
374
- 'titleSeparator' => $title_separator,
375
'descriptionSeparator' => $description_separator,
376
- 'titleLocation' => $title_location,
377
- 'titlePixelGuideline' => 600,
378
- 'descPixelGuideline' => $is_post_edit ? ( $this->is_page() ? 1820 : 1720 ) : 1820,
379
- ),
380
- 'other' => $this->additional_js_l10n( null, array(), true ),
381
- );
382
383
- $decode = array( 'i18n', 'params' );
384
$flags = ENT_COMPAT;
385
- foreach ( $decode as $key ) {
386
- foreach ( $l10n[ $key ] as $k => $v ) {
387
- $l10n[ $key ][ $k ] = \esc_js( \html_entity_decode( $v, $flags, 'UTF-8' ) );
388
}
389
}
390
391
/**
392
- * Applies filters 'the_seo_framework_js_l10n'
393
- *
394
* @since 3.0.0
395
- * @param array $l10n
396
*/
397
return (array) \apply_filters( 'the_seo_framework_js_l10n', $l10n );
398
}
399
400
- /**
401
- * Maintains and Returns additional JS l10n.
402
- *
403
- * They are put under object 'tsfemL10n.other[ $key ] = $val'.
404
- *
405
- * @since 2.8.0
406
- * @staticvar object $strings The cached strings object.
407
- *
408
- * @param null|string $key The object key.
409
- * @param array $val The object val.
410
- * @param bool $get Whether to return the cached strings.
411
- * @param bool $escape Whether to escape the input.
412
- * @return object Early when $get is true
413
- */
414
- public function additional_js_l10n( $key = null, array $val = array(), $get = false, $escape = true ) {
415
-
416
- static $strings = null;
417
-
418
- if ( null === $strings )
419
- $strings = new \stdClass();
420
-
421
- if ( $get )
422
- return $strings;
423
-
424
- if ( $escape ) {
425
- $key = \esc_attr( $key );
426
- $val = \map_deep( $val, 'esc_attr' );
427
- }
428
-
429
- if ( $key )
430
- $strings->$key = $val;
431
- }
432
-
433
/**
434
* Sets up additional JS l10n values for nonces.
435
*
436
* They are put under object 'tsfemL10n.nonces[ $key ] = $val'.
437
*
438
* @since 2.9.0
439
*
440
* @param string|array $key Required. The object key or array of keys and values. Requires escape.
441
* @param mixed $val The object value if $key is string. Requires escape.
@@ -452,6 +544,7 @@ class Admin_Init extends Init {
452
* If $key is an array, $val is ignored and $key's values are used instead.
453
*
454
* @since 2.9.0
455
* @staticvar object $nonces The cached nonces object.
456
*
457
* @param string|array $key The object key or array of keys and values. Requires escape.
@@ -479,136 +572,146 @@ class Admin_Init extends Init {
479
}
480
481
/**
482
- * Checks ajax referred set by set_js_nonces based on capability.
483
- *
484
- * Performs die() on failure.
485
- *
486
- * @since 2.9.0
487
- * @access private
488
- * It uses an internally and manually created prefix.
489
- * @uses WP Core check_ajax_referer()
490
- * @see @link https://developer.wordpress.org/reference/functions/check_ajax_referer/
491
- *
492
- * @return false|int False if the nonce is invalid, 1 if the nonce is valid
493
- * and generated between 0-12 hours ago, 2 if the nonce is
494
- * valid and generated between 12-24 hours ago.
495
- */
496
- public function check_tsf_ajax_referer( $capability ) {
497
- return \check_ajax_referer( 'tsf-ajax-' . $capability, 'nonce', true );
498
- }
499
-
500
- /**
501
- * CSS for the AutoDescription Bar
502
*
503
- * @since 2.1.9
504
- * @since 3.0.0 Now also outputs colors.
505
*
506
- * @param $hook the current page
507
*/
508
- public function enqueue_admin_css( $hook ) {
509
-
510
/**
511
- * Put hook and js name in class vars.
512
- * @since 2.5.2.2
513
*/
514
- $this->page_base_file = $this->page_base_file ?: $hook;
515
-
516
- //* Register the script.
517
- $this->register_admin_css();
518
-
519
- if ( $this->is_seo_settings_page() ) {
520
- \wp_enqueue_style( 'wp-color-picker' );
521
- }
522
-
523
- \wp_enqueue_style( $this->css_name );
524
-
525
- $color_css = $this->get_admin_color_css()
526
- and \wp_add_inline_style( $this->css_name, $color_css );
527
}
528
529
/**
530
- * Registers Admin CSS.
531
*
532
- * @since 2.6.0
533
- * @staticvar bool $registered : Prevents Re-registering of the style.
534
- * @access private
535
*/
536
- protected function register_admin_css() {
537
-
538
- static $registered = null;
539
-
540
- if ( isset( $registered ) )
541
- return;
542
-
543
- $rtl = \is_rtl() ? '-rtl' : '';
544
- $suffix = $this->script_debug ? '' : '.min';
545
- $registered = true;
546
-
547
- \wp_register_style( $this->css_name, THE_SEO_FRAMEWORK_DIR_URL . "lib/css/{$this->css_name}{$rtl}{$suffix}.css", array(), THE_SEO_FRAMEWORK_VERSION, 'all' );
548
}
549
550
/**
551
- * Outputs additional CSS based on admin theme colors.
552
*
553
- * @since 3.0.0
554
*
555
- * @return string Additional admin CSS.
556
*/
557
- protected function get_admin_color_css() {
558
-
559
- //* @see wp_style_loader_src()
560
- $scheme = \get_user_option( 'admin_color' ) ?: 'fresh';
561
-
562
- $_colors = $GLOBALS['_wp_admin_css_colors'];
563
-
564
- if (
565
- ! isset( $_colors[ $scheme ]->colors )
566
- || ! is_array( $_colors[ $scheme ]->colors )
567
- || count( $_colors[ $scheme ]->colors ) < 4
568
- ) return '';
569
-
570
- $colors = $_colors[ $scheme ]->colors;
571
-
572
- $bg = $colors[0];
573
- $bg_accent = $colors[1];
574
- $color = $colors[2];
575
- $color_accent = $colors[3];
576
-
577
- // $bg_alt_font = '#' . $this->get_relative_fontcolor( $bg );
578
- $bg_accent_alt_font = '#' . $this->get_relative_fontcolor( $bg_accent );
579
-
580
- $css = array(
581
- '.tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked + .tsf-flex-nav-tab-label' => array(
582
- "box-shadow:0 -2px 0 0 $color_accent inset",
583
- ),
584
- '.tsf-tooltip-text-wrap' => array(
585
- "background-color:$bg_accent",
586
- "color:$bg_accent_alt_font",
587
- ),
588
- '.tsf-tooltip-arrow:after' => array(
589
- "border-top-color:$bg_accent",
590
- ),
591
- '.tsf-tooltip-down .tsf-tooltip-arrow:after' => array(
592
- "border-bottom-color:$bg_accent",
593
- ),
594
- );
595
-
596
- /**
597
- * Applies filters 'the_seo_framework_admin_color_css'
598
- *
599
- * @since 3.0.0
600
- * @since 3.0.4 Now passes $colors.
601
- * @param array $css The current styles. Empty it to disable conditional styling.
602
- * @param string $scheme The current admin scheme name.
603
- * @param array $colors The current admin scheme values.
604
- */
605
- $css = (array) \apply_filters( 'the_seo_framework_admin_color_css', $css, $scheme, $colors );
606
-
607
- $out = '';
608
- foreach ( $css as $attr => $style )
609
- $out .= $attr . '{' . implode( ';', $style ) . '}';
610
-
611
- return $out;
612
}
613
614
/**
@@ -619,13 +722,12 @@ class Admin_Init extends Init {
619
* @param array $removable_query_args
620
* @return array The adjusted removable query args.
621
*/
622
- public function add_removable_query_args( $removable_query_args = array() ) {
623
-
624
- if ( ! is_array( $removable_query_args ) )
625
- return $removable_query_args;
626
627
- $removable_query_args[] = 'tsf-settings-reset';
628
- $removable_query_args[] = 'tsf-settings-updated';
629
630
return $removable_query_args;
631
}
@@ -644,12 +746,12 @@ class Admin_Init extends Init {
644
* (key => value). Default is an empty array.
645
* @return null Return early if first argument is false.
646
*/
647
- public function admin_redirect( $page, array $query_args = array() ) {
648
649
if ( empty( $page ) )
650
return;
651
652
- $url = html_entity_decode( \menu_page_url( $page, false ) );
653
654
foreach ( $query_args as $key => $value ) {
655
if ( empty( $key ) || empty( $value ) )
@@ -657,7 +759,7 @@ class Admin_Init extends Init {
657
}
658
659
$target = \add_query_arg( $query_args, $url );
660
- $target = \esc_url_raw( $target, array( 'http', 'https' ) );
661
662
//* Predict white screen:
663
$headers_sent = headers_sent();
@@ -692,41 +794,36 @@ class Admin_Init extends Init {
692
return;
693
694
$headers_list = headers_list();
695
- $location = sprintf( 'Location: %s', \wp_sanitize_redirect( $target ) );
696
697
//* Test if WordPress' redirect header is sent. Bail if true.
698
if ( in_array( $location, $headers_list, true ) )
699
return;
700
701
- //* Output message:
702
printf( '<p><strong>%s</strong></p>',
703
- //* Markdown escapes.
704
$this->convert_markdown(
705
sprintf(
706
/* translators: %s = Redirect URL markdown */
707
\esc_html__( 'There has been an error redirecting. Refresh the page or follow [this link](%s).', 'autodescription' ),
708
$target
709
),
710
- array( 'a' ),
711
- array( 'a_internal' => true )
712
)
713
);
714
}
715
716
/**
717
- * Handles counter option update on AJAX request.
718
*
719
- * @since 2.6.0
720
- * @since 2.9.0 : 1. Changed capability from 'publish_posts' to 'edit_posts'.
721
- * 2. Added json header.
722
* @securitycheck 3.0.0 OK.
723
* @access private
724
*/
725
- public function wp_ajax_update_counter_type() {
726
727
if ( $this->is_admin() && $this->doing_ajax() ) :
728
-
729
- $this->check_tsf_ajax_referer( 'edit_posts' );
730
731
//* Remove output buffer.
732
$this->clean_response_header();
@@ -734,15 +831,17 @@ class Admin_Init extends Init {
734
//* If current user isn't allowed to edit posts, don't do anything and kill PHP.
735
if ( ! \current_user_can( 'edit_posts' ) ) {
736
//* Encode and echo results. Requires JSON decode within JS.
737
- echo json_encode( array( 'type' => 'failure', 'value' => '' ) );
738
- exit;
739
}
740
741
/**
742
* Count up, reset to 0 if needed. We have 4 options: 0, 1, 2, 3
743
* $_POST['val'] already contains updated number.
744
*/
745
- $value = isset( $_POST['val'] ) ? intval( $_POST['val'] ) : $this->get_user_option( 0, 'counter_type', 3 ) + 1;
746
$value = \absint( $value );
747
748
if ( $value > 3 )
@@ -751,16 +850,13 @@ class Admin_Init extends Init {
751
//* Update the option and get results of action.
752
$type = $this->update_user_option( 0, 'counter_type', $value ) ? 'success' : 'error';
753
754
- $results = array(
755
- 'type' => $type,
756
'value' => $value,
757
- );
758
759
//* Encode and echo results. Requires JSON decode within JS.
760
- echo json_encode( $results );
761
-
762
- //* Kill PHP.
763
- exit;
764
endif;
765
}
766
@@ -773,28 +869,27 @@ class Admin_Init extends Init {
773
* 3. It now only accepts context 'tsf-image'
774
* 4. It no longer accepts a default context.
775
*
776
- * @since 2.9.0
777
* @securitycheck 3.0.0 OK.
778
* @access private
779
*/
780
- public function wp_ajax_crop_image() {
781
782
- $this->check_tsf_ajax_referer( 'upload_files' );
783
- if ( ! \current_user_can( 'upload_files' ) )
784
\wp_send_json_error();
785
786
- $attachment_id = \absint( $_POST['id'] );
787
788
- $context = \sanitize_key( str_replace( '_', '-', $_POST['context'] ) );
789
- $data = array_map( 'absint', $_POST['cropDetails'] );
790
$cropped = \wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] );
791
792
if ( ! $cropped || \is_wp_error( $cropped ) )
793
- \wp_send_json_error( array( 'message' => \esc_js( \__( 'Image could not be processed.', 'autodescription' ) ) ) );
794
795
switch ( $context ) :
796
case 'tsf-image':
797
-
798
/**
799
* Fires before a cropped image is saved.
800
*
@@ -817,13 +912,13 @@ class Admin_Init extends Init {
817
$size = @getimagesize( $cropped );
818
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
819
820
- $object = array(
821
'post_title' => basename( $cropped ),
822
'post_content' => $url,
823
'post_mime_type' => $image_type,
824
'guid' => $url,
825
'context' => $context,
826
- );
827
828
$attachment_id = \wp_insert_attachment( $object, $cropped );
829
$metadata = \wp_generate_attachment_metadata( $attachment_id, $cropped );
@@ -850,8 +945,8 @@ class Admin_Init extends Init {
850
$attachment_id = \apply_filters( 'wp_ajax_cropped_attachment_id', $attachment_id, $context );
851
break;
852
853
- default :
854
- \wp_send_json_error( array( 'message' => \esc_js( \__( 'Image could not be processed.', 'autodescription' ) ) ) );
855
break;
856
endswitch;
857
4
*/
5
namespace The_SEO_Framework;
6
7
+ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
9
/**
10
* The SEO Framework plugin
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 Builde