The SEO Framework - Version 3.2.4

Version Description

In this minor update, we bring you the most advanced description generation yet. The generator is now context-sensitive, so you can expect the descriptions to be even more natural; a real time-saver!

Oh, we also fixed some bugs, and we've implemented some improvements in preparation for version 3.3.0.

Download this release

Release Info

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

Code changes from version 3.2.3 to 3.2.4

autodescription.php CHANGED
@@ -3,7 +3,7 @@
3
* Plugin Name: The SEO Framework
4
* Plugin URI: https://theseoframework.com/
5
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
6
- * Version: 3.2.3
7
* Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
@@ -53,7 +53,7 @@ defined( 'ABSPATH' ) or die;
53
*
54
* @since 2.3.5
55
*/
56
- define( 'THE_SEO_FRAMEWORK_VERSION', '3.2.3' );
57
58
/**
59
* The plugin Database version.
3
* Plugin Name: The SEO Framework
4
* Plugin URI: https://theseoframework.com/
5
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
6
+ * Version: 3.2.4
7
* Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
53
*
54
* @since 2.3.5
55
*/
56
+ define( 'THE_SEO_FRAMEWORK_VERSION', '3.2.4' );
57
58
/**
59
* The plugin Database version.
bootstrap/activation.php CHANGED
@@ -1,8 +1,9 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- */
5
- namespace The_SEO_Framework;
6
7
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
@@ -23,10 +24,14 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
23
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
*/
25
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.
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;
9
24
* along with this program. If not, see <http://www.gnu.org/licenses/>.
25
*/
26
27
+ /**
28
+ * @since 3.2.4 Applied namspacing to this file. All method names have changed.
29
+ */
30
+
31
//! @php7+ convert to IIFE
32
+ _activation_setup_sitemap();
33
+ _activation_set_options_autoload();
34
+ _activation_set_plugin_check_caches();
35
36
/**
37
* Nudges the plugin to check for conflicting SEO plugins.
bootstrap/deactivation.php CHANGED
@@ -1,8 +1,9 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework
4
- */
5
- namespace The_SEO_Framework;
6
7
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
8
@@ -23,9 +24,13 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
23
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
*/
25
26
//! @php7+ convert to IIFE
27
- \The_SEO_Framework\_deactivation_unset_options_autoload();
28
- \The_SEO_Framework\_deactivation_unset_sitemap();
29
30
/**
31
* Flush rewrite rules on plugin deactivation.
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;
9
24
* along with this program. If not, see <http://www.gnu.org/licenses/>.
25
*/
26
27
+ /**
28
+ * @since 3.2.4 Applied namspacing to this file. All method names have changed.
29
+ */
30
+
31
//! @php7+ convert to IIFE
32
+ _deactivation_unset_options_autoload();
33
+ _deactivation_unset_sitemap();
34
35
/**
36
* Flush rewrite rules on plugin deactivation.
bootstrap/define.php CHANGED
@@ -1,6 +1,8 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework/Bootstrap
4
*/
5
6
defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
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;
bootstrap/envtest.php CHANGED
@@ -1,6 +1,10 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework/Bootstrap
4
*/
5
6
defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
@@ -27,9 +31,6 @@ defined( 'THE_SEO_FRAMEWORK_DB_VERSION' ) or die;
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
*/
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;
31
* This file will only be called ONCE if the required version option is lower
32
* compared to The SEO Framework version constant.
33
*
34
* @since 3.1.0
35
* @access private
36
*/
bootstrap/load.php CHANGED
@@ -1,7 +1,10 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework/Bootstrap
4
- */
5
namespace The_SEO_Framework;
6
7
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
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;
bootstrap/upgrade.php CHANGED
@@ -1,7 +1,9 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework/Bootstrap
4
*/
5
6
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
7
@@ -31,6 +33,8 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
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
/**
@@ -41,12 +45,12 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
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
*
@@ -55,12 +59,12 @@ the_seo_framework_previous_db_version(); // sets 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
*
@@ -82,12 +86,14 @@ add_action( 'init', 'the_seo_framework_do_upgrade', 20 );
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() ); // phpcs:ignore -- self_admin_url() is safe.
91
exit;
92
}
93
@@ -98,61 +104,61 @@ function the_seo_framework_do_upgrade() {
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
*
@@ -163,20 +169,21 @@ add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_to_current'
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
*
@@ -185,29 +192,29 @@ add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_reinitializ
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
- * @since 3.2.2. No longer suggests when the user is new.
198
* @staticvar bool $run
199
*
200
* @return void Early when already enqueued
201
*/
202
- function the_seo_framework_prepare_extension_manager_suggestion() {
203
static $run = false;
204
if ( $run ) return;
205
206
- if ( is_admin() ) {
207
- add_action( 'admin_init', function() {
208
- if ( ! the_seo_framework_previous_db_version() ) return;
209
- require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'tsfem-suggestion.php';
210
- the_seo_framework_load_extension_manager_suggestion();
211
}, 20 );
212
}
213
@@ -224,7 +231,7 @@ function the_seo_framework_prepare_extension_manager_suggestion() {
224
* @param bool $get Whether to return the upgrade notices.
225
* @return array|void The notices when $get is true.
226
*/
227
- function the_seo_framework_add_upgrade_notice( $notice = '', $get = false ) {
228
229
static $cache = [];
230
@@ -234,21 +241,21 @@ function the_seo_framework_add_upgrade_notice( $notice = '', $get = false ) {
234
$cache[] = $notice;
235
}
236
237
- add_action( 'admin_notices', 'the_seo_framework_output_upgrade_notices' );
238
/**
239
* Outputs available upgrade notices.
240
*
241
* @since 2.9.0
242
* @since 3.0.0 Added prefix.
243
- * @uses the_seo_framework_add_upgrade_notice()
244
*/
245
- function the_seo_framework_output_upgrade_notices() {
246
247
- $notices = the_seo_framework_add_upgrade_notice( '', true );
248
249
foreach ( $notices as $notice ) {
250
//* @TODO rtl?
251
- the_seo_framework()->do_dismissible_notice( 'SEO: ' . $notice, 'updated' );
252
}
253
}
254
@@ -257,9 +264,9 @@ function the_seo_framework_output_upgrade_notices() {
257
*
258
* @since 3.1.0
259
*/
260
- function the_seo_framework_do_upgrade_1() {
261
- the_seo_framework()->register_settings();
262
- update_option( 'the_seo_framework_upgraded_db_version', '1' );
263
}
264
265
/**
@@ -269,20 +276,20 @@ function the_seo_framework_do_upgrade_1() {
269
* @since 3.1.0 No longer tries to set term meta for ID 0.
270
* `add_metadata()` already blocked this, this is defensive.
271
*/
272
- function the_seo_framework_do_upgrade_2701() {
273
274
- $term_meta = get_option( 'autodescription-term-meta' );
275
276
if ( $term_meta ) {
277
foreach ( (array) $term_meta as $term_id => $meta ) {
278
- add_term_meta( $term_id, THE_SEO_FRAMEWORK_TERM_OPTIONS, $meta, true );
279
}
280
281
//= Rudimentary test for remaining ~300 users of the past passed, set initial version to 2600.
282
- update_option( 'the_seo_framework_initial_db_version', '2600', 'no' );
283
}
284
285
- update_option( 'the_seo_framework_upgraded_db_version', '2701' );
286
}
287
288
/**
@@ -291,13 +298,13 @@ function the_seo_framework_do_upgrade_2701() {
291
*
292
* @since 2.8.0
293
*/
294
- function the_seo_framework_do_upgrade_2802() {
295
296
//* Delete old values from database. Removes backwards compatibility.
297
- if ( get_option( 'the_seo_framework_initial_db_version' ) < '2701' )
298
- delete_option( 'autodescription-term-meta' );
299
300
- update_option( 'the_seo_framework_upgraded_db_version', '2802' );
301
}
302
303
/**
@@ -306,25 +313,25 @@ function the_seo_framework_do_upgrade_2802() {
306
* @since 2.9.0
307
* @since 3.1.0 Now only sets new options when defaults exists.
308
*/
309
- function the_seo_framework_do_upgrade_2900() {
310
311
- if ( get_option( 'the_seo_framework_initial_db_version' ) < '2900' ) {
312
- $defaults = the_seo_framework_upgrade_default_site_options();
313
314
if ( isset( $defaults['twitter_card'] ) ) {
315
- $tsf = the_seo_framework();
316
317
- $card_type = trim( esc_attr( $tsf->get_option( 'twitter_card', false ) ) );
318
if ( 'photo' === $card_type ) {
319
$tsf->update_option( 'twitter_card', 'summary_large_image' );
320
- the_seo_framework_add_upgrade_notice(
321
- esc_html__( 'Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable.', 'autodescription' )
322
);
323
}
324
}
325
}
326
327
- update_option( 'the_seo_framework_upgraded_db_version', '2900' );
328
}
329
330
/**
@@ -335,20 +342,20 @@ function the_seo_framework_do_upgrade_2900() {
335
* @since 3.0.6 'display_character_counter' option now correctly defaults to 1.
336
* @since 3.1.0 Now only sets new options when defaults exist, and when it's an upgraded site.
337
*/
338
- function the_seo_framework_do_upgrade_3001() {
339
340
- if ( get_option( 'the_seo_framework_initial_db_version' ) < '3001' ) {
341
- $tsf = the_seo_framework();
342
343
- $defaults = the_seo_framework_upgrade_default_site_options();
344
345
if ( isset( $defaults['timestamps_format'] ) ) {
346
//= Only change if old option exists. Falls back to default upgrader otherwise.
347
$sitemap_timestamps = $tsf->get_option( 'sitemap_timestamps', false );
348
$tsf->update_option( 'timestamps_format', (string) (int) $sitemap_timestamps ?: $defaults['timestamps_format'] );
349
if ( '' !== $sitemap_timestamps ) {
350
- the_seo_framework_add_upgrade_notice(
351
- esc_html__( 'The previous sitemap timestamp settings have been converted into new global timestamp settings.', 'autodescription' )
352
);
353
}
354
}
@@ -360,7 +367,7 @@ function the_seo_framework_do_upgrade_3001() {
360
$tsf->update_option( 'display_pixel_counter', $defaults['display_pixel_counter'] );
361
}
362
363
- update_option( 'the_seo_framework_upgraded_db_version', '3001' );
364
}
365
366
/**
@@ -369,12 +376,12 @@ function the_seo_framework_do_upgrade_3001() {
369
*
370
* @since 3.0.6
371
*/
372
- function the_seo_framework_do_upgrade_3060() {
373
374
- if ( get_option( 'the_seo_framework_initial_db_version' ) < '3060' )
375
- the_seo_framework()->delete_cache( 'sitemap' );
376
377
- update_option( 'the_seo_framework_upgraded_db_version', '3060' );
378
}
379
380
/**
@@ -391,16 +398,16 @@ function the_seo_framework_do_upgrade_3060() {
391
*
392
* @since 3.1.0
393
*/
394
- function the_seo_framework_do_upgrade_3103() {
395
396
// Prevent database lookups when checking for cache.
397
- add_option( THE_SEO_FRAMEWORK_SITE_CACHE, [] );
398
399
// If it's an older installation, upgrade these options.
400
- if ( get_option( 'the_seo_framework_initial_db_version' ) < '3103' ) {
401
- $tsf = the_seo_framework();
402
403
- $defaults = the_seo_framework_upgrade_default_site_options();
404
405
// Transport title separator.
406
if ( isset( $defaults['title_separator'] ) )
@@ -433,5 +440,5 @@ function the_seo_framework_do_upgrade_3103() {
433
$tsf->update_option( 'sitemaps_priority', 1 );
434
}
435
436
- update_option( 'the_seo_framework_upgraded_db_version', '3103' );
437
}
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;
9
33
* @access private
34
* @TODO convert to class, see \TSF_Extension_Manager\Upgrader
35
* It's a generator/iterator, so we must wait to PHP>5.5 support.
36
+ *
37
+ * @since 3.2.4 Applied namspacing to this file. All method names have changed.
38
*/
39
40
/**
45
*
46
* @return array The default site options.
47
*/
48
+ function _upgrade_default_site_options() {
49
static $cache;
50
+ return isset( $cache ) ? $cache : $cache = \the_seo_framework()->get_default_site_options();
51
}
52
53
+ _previous_db_version(); // sets cache.
54
/**
55
* Returns the version set before upgrading began.
56
*
59
*
60
* @return string The prior-to-upgrade TSF db version.
61
*/
62
+ function _previous_db_version() {
63
static $cache;
64
+ return isset( $cache ) ? $cache : $cache = \get_option( 'the_seo_framework_upgraded_db_version', '0' );
65
}
66
67
+ \add_action( 'init', __NAMESPACE__ . '\\_do_upgrade', 20 );
68
/**
69
* Upgrade The SEO Framework to the latest version.
70
*
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
+
91
+ $tsf = \the_seo_framework();
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
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();
112
113
+ if ( ! \get_option( 'the_seo_framework_initial_db_version' ) ) {
114
//* Sets to previous if previous is known. This is a late addition.
115
+ \update_option( 'the_seo_framework_initial_db_version', $version ?: THE_SEO_FRAMEWORK_DB_VERSION, 'no' );
116
}
117
118
if ( $version >= THE_SEO_FRAMEWORK_DB_VERSION ) {
119
+ _upgrade_to_current();
120
return;
121
}
122
123
if ( ! $version ) {
124
+ _do_upgrade_1();
125
$version = '1';
126
}
127
if ( $version < '2701' ) {
128
+ _do_upgrade_2701();
129
$version = '2701';
130
}
131
if ( $version < '2802' ) {
132
+ _do_upgrade_2802();
133
$version = '2802';
134
}
135
if ( $version < '2900' ) {
136
+ _do_upgrade_2900();
137
$version = '2900';
138
}
139
if ( $version < '3001' ) {
140
+ _do_upgrade_3001();
141
$version = '3001';
142
}
143
if ( $version < '3060' ) {
144
+ _do_upgrade_3060();
145
$version = '3060';
146
}
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.
164
*
169
* @since 2.7.0
170
* @since 3.1.4 Now flushes the object cache after the setting's updated.
171
*/
172
+ function _upgrade_to_current() {
173
+
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
*
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 );
200
/**
201
* Enqueues and outputs an Extension Manager suggestion.
202
*
203
* @since 3.1.0
204
+ * @since 3.2.2 No longer suggests when the user is new.
205
+ * @since 3.2.4 Moved upgrade suggestion call to applicable file.
206
* @staticvar bool $run
207
*
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
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 ) {
235
236
static $cache = [];
237
241
$cache[] = $notice;
242
}
243
244
+ \add_action( 'admin_notices', __NAMESPACE__ . '\\_output_upgrade_notices' );
245
/**
246
* Outputs available upgrade notices.
247
*
248
* @since 2.9.0
249
* @since 3.0.0 Added prefix.
250
+ * @uses _add_upgrade_notice()
251
*/
252
+ function _output_upgrade_notices() {
253
254
+ $notices = _add_upgrade_notice( '', true );
255
256
foreach ( $notices as $notice ) {
257
//* @TODO rtl?
258
+ \the_seo_framework()->do_dismissible_notice( 'SEO: ' . $notice, 'updated' );
259
}
260
}
261
264
*
265
* @since 3.1.0
266
*/
267
+ function _do_upgrade_1() {
268
+ \the_seo_framework()->register_settings();
269
+ \update_option( 'the_seo_framework_upgraded_db_version', '1' );
270
}
271
272
/**
276
* @since 3.1.0 No longer tries to set term meta for ID 0.
277
* `add_metadata()` already blocked this, this is defensive.
278
*/
279
+ function _do_upgrade_2701() {
280
281
+ $term_meta = \get_option( 'autodescription-term-meta' );
282
283
if ( $term_meta ) {
284
foreach ( (array) $term_meta as $term_id => $meta ) {
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
292
+ \update_option( 'the_seo_framework_upgraded_db_version', '2701' );
293
}
294
295
/**
298
*
299
* @since 2.8.0
300
*/
301
+ function _do_upgrade_2802() {
302
303
//* Delete old values from database. Removes backwards compatibility.
304
+ if ( \get_option( 'the_seo_framework_initial_db_version' ) < '2701' )
305
+ \delete_option( 'autodescription-term-meta' );
306
307
+ \update_option( 'the_seo_framework_upgraded_db_version', '2802' );
308
}
309
310
/**
313
* @since 2.9.0
314
* @since 3.1.0 Now only sets new options when defaults exists.
315
*/
316
+ function _do_upgrade_2900() {
317
318
+ if ( \get_option( 'the_seo_framework_initial_db_version' ) < '2900' ) {
319
+ $defaults = _upgrade_default_site_options();
320
321
if ( isset( $defaults['twitter_card'] ) ) {
322
+ $tsf = \the_seo_framework();
323
324
+ $card_type = trim( \esc_attr( $tsf->get_option( 'twitter_card', false ) ) );
325
if ( 'photo' === $card_type ) {
326
$tsf->update_option( 'twitter_card', 'summary_large_image' );
327
+ _add_upgrade_notice(
328
+ \esc_html__( 'Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable.', 'autodescription' )
329
);
330
}
331
}
332
}
333
334
+ \update_option( 'the_seo_framework_upgraded_db_version', '2900' );
335
}
336
337
/**
342
* @since 3.0.6 'display_character_counter' option now correctly defaults to 1.
343
* @since 3.1.0 Now only sets new options when defaults exist, and when it's an upgraded site.
344
*/
345
+ function _do_upgrade_3001() {
346
347
+ if ( \get_option( 'the_seo_framework_initial_db_version' ) < '3001' ) {
348
+ $tsf = \the_seo_framework();
349
350
+ $defaults = _upgrade_default_site_options();
351
352
if ( isset( $defaults['timestamps_format'] ) ) {
353
//= Only change if old option exists. Falls back to default upgrader otherwise.
354
$sitemap_timestamps = $tsf->get_option( 'sitemap_timestamps', false );
355
$tsf->update_option( 'timestamps_format', (string) (int) $sitemap_timestamps ?: $defaults['timestamps_format'] );
356
if ( '' !== $sitemap_timestamps ) {
357
+ _add_upgrade_notice(
358
+ \esc_html__( 'The previous sitemap timestamp settings have been converted into new global timestamp settings.', 'autodescription' )
359
);
360
}
361
}
367
$tsf->update_option( 'display_pixel_counter', $defaults['display_pixel_counter'] );
368
}
369
370
+ \update_option( 'the_seo_framework_upgraded_db_version', '3001' );
371
}
372
373
/**
376
*
377
* @since 3.0.6
378
*/
379
+ function _do_upgrade_3060() {
380
381
+ if ( \get_option( 'the_seo_framework_initial_db_version' ) < '3060' )
382
+ \the_seo_framework()->delete_cache( 'sitemap' );
383
384
+ \update_option( 'the_seo_framework_upgraded_db_version', '3060' );
385
}
386
387
/**
398
*
399
* @since 3.1.0
400
*/
401
+ function _do_upgrade_3103() {
402
403
// Prevent database lookups when checking for cache.
404
+ \add_option( THE_SEO_FRAMEWORK_SITE_CACHE, [] );
405
406
// If it's an older installation, upgrade these options.
407
+ if ( \get_option( 'the_seo_framework_initial_db_version' ) < '3103' ) {
408
+ $tsf = \the_seo_framework();
409
410
+ $defaults = _upgrade_default_site_options();
411
412
// Transport title separator.
413
if ( isset( $defaults['title_separator'] ) )
440
$tsf->update_option( 'sitemaps_priority', 1 );
441
}
442
443
+ \update_option( 'the_seo_framework_upgraded_db_version', '3103' );
444
}
inc/classes/admin-pages.class.php CHANGED
@@ -184,7 +184,7 @@ class Admin_Pages extends Inpost {
184
* @see $this->title_metabox() Callback for Title Settings box.
185
* @see $this->description_metabox() Callback for Description Settings box.
186
* @see $this->robots_metabox() Callback for Robots Settings box.
187
- * @see $this->homepage_metabox() Callback for Home Page Settings box.
188
* @see $this->social_metabox() Callback for Social Settings box.
189
* @see $this->schema_metabox() Callback for Schema Settings box.
190
* @see $this->webmaster_metabox() Callback for Webmaster Settings box.
@@ -244,11 +244,11 @@ class Admin_Pages extends Inpost {
244
[]
245
);
246
247
- //* Home Page Meta Box
248
if ( $home )
249
\add_meta_box(
250
'autodescription-homepage-settings',
251
- \esc_html__( 'Home Page Settings', 'autodescription' ),
252
[ $this, 'homepage_metabox' ],
253
$this->seo_settings_page_hook,
254
'main',
184
* @see $this->title_metabox() Callback for Title Settings box.
185
* @see $this->description_metabox() Callback for Description Settings box.
186
* @see $this->robots_metabox() Callback for Robots Settings box.
187
+ * @see $this->homepage_metabox() Callback for Homepage Settings box.
188
* @see $this->social_metabox() Callback for Social Settings box.
189
* @see $this->schema_metabox() Callback for Schema Settings box.
190
* @see $this->webmaster_metabox() Callback for Webmaster Settings box.
244
[]
245
);
246
247
+ //* Homepage Meta Box
248
if ( $home )
249
\add_meta_box(
250
'autodescription-homepage-settings',
251
+ \esc_html__( 'Homepage Settings', 'autodescription' ),
252
[ $this, 'homepage_metabox' ],
253
$this->seo_settings_page_hook,
254
'main',
inc/classes/builders/scripts.class.php CHANGED
@@ -530,6 +530,7 @@ final class Scripts {
530
* @see static::verify( $secret )
531
*
532
* @since 3.1.0
533
* @uses static::$include_secret
534
*
535
* @param string $file The file location.
@@ -542,7 +543,7 @@ final class Scripts {
542
unset( $_key, $_val, $args );
543
544
//= Prevent private includes hijacking.
545
- static::$include_secret = $_secret = mt_rand() . uniqid();
546
include $file;
547
static::$include_secret = null;
548
}
530
* @see static::verify( $secret )
531
*
532
* @since 3.1.0
533
+ * @since 3.2.4 Enabled entropy to prevent system sleep.
534
* @uses static::$include_secret
535
*
536
* @param string $file The file location.
543
unset( $_key, $_val, $args );
544
545
//= Prevent private includes hijacking.
546
+ static::$include_secret = $_secret = mt_rand() . uniqid( '', true );
547
include $file;
548
static::$include_secret = null;
549
}
inc/classes/core.class.php CHANGED
@@ -222,8 +222,6 @@ class Core {
222
*/
223
public function _add_plugin_action_links( $links = [] ) {
224
225
- $tsf_links = [];
226
-
227
if ( $this->load_options )
228
$tsf_links['settings'] = sprintf(
229
'<a href="%s">%s</a>',
@@ -232,7 +230,7 @@ class Core {
232
);
233
234
$tsf_links['about'] = sprintf(
235
- '<a href="https://theseoframework.com/" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
236
\esc_html__( 'About', 'autodescription' )
237
);
238
$tsf_links['tsfem'] = sprintf(
@@ -241,7 +239,49 @@ class Core {
241
\esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
242
);
243
244
- return array_merge( $links, $tsf_links );
245
}
246
247
/**
222
*/
223
public function _add_plugin_action_links( $links = [] ) {
224
225
if ( $this->load_options )
226
$tsf_links['settings'] = sprintf(
227
'<a href="%s">%s</a>',
230
);
231
232
$tsf_links['about'] = sprintf(
233
+ '<a href="https://theseoframework.com/about-us/" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
234
\esc_html__( 'About', 'autodescription' )
235
);
236
$tsf_links['tsfem'] = sprintf(
239
\esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
240
);
241
242
+ return array_merge( $tsf_links, $links );
243
+ }
244
+
245
+ /**
246
+ * Adds more row meta on the plugin screen.
247
+ *
248
+ * @since 3.2.4
249
+ * @access private
250
+ *
251
+ * @param string[] $plugin_meta An array of the plugin's metadata,
252
+ * including the version, author,
253
+ * author URI, and plugin URI.
254
+ * @param string $plugin_file Path to the plugin file relative to the plugins directory.
255
+ * @return array $plugin_meta
256
+ */
257
+ public function _add_plugin_row_meta( $plugin_meta, $plugin_file ) {
258
+
259
+ if ( THE_SEO_FRAMEWORK_PLUGIN_BASENAME !== $plugin_file )
260
+ return $plugin_meta;
261
+
262
+ return array_merge( $plugin_meta, [
263
+ 'docs' => vsprintf(
264
+ '<a href="%s" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
265
+ [
266
+ 'https://theseoframework.com/?p=80',
267
+ \esc_html__( 'View documentation', 'autodescription' ),
268
+ ]
269
+ ),
270
+ 'API' => vsprintf(
271
+ '<a href="%s" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
272
+ [
273
+ 'https://theseoframework.com/?p=82',
274
+ \esc_html__( 'View API docs', 'autodescription' ),
275
+ ]
276
+ ),
277
+ 'EM' => vsprintf(
278
+ '<a href="%s" rel="noreferrer noopener nofollow" target="_blank">%s</a>',
279
+ [
280
+ 'https://theseoframework.com/?p=2760',
281
+ \esc_html_x( 'Get the Extension Manager', 'Extension Manager is a product name; do not translate', 'autodescription' ),
282
+ ]
283
+ ),
284
+ ] );
285
}
286
287
/**
inc/classes/deprecated.class.php CHANGED
@@ -1,6 +1,7 @@
1
<?php
2
/**
3
- * @package The_SEO_Framework\Classes\Deprecated
4
*/
5
namespace The_SEO_Framework;
6
1
<?php
2
/**
3
+ * @package The_SEO_Framework\Classes
4
+ * @subpackage Classes\Deprecated
5
*/
6
namespace The_SEO_Framework;
7
inc/classes/detect.class.php CHANGED
@@ -288,7 +288,7 @@ class Detect extends Render {
288
* @since 2.5.2
289
*
290
* @param array $plugins Array of array for constants, classes and / or functions to check for plugin existence.
291
- * @return boolean True if ALL functions classes and constants exists or false if plugin constant, class or function not detected.
292
*/
293
public function detect_plugin_multi( array $plugins ) {
294
288
* @since 2.5.2
289
*
290
* @param array $plugins Array of array for constants, classes and / or functions to check for plugin existence.
291
+ * @return bool True if ALL functions classes and constants exists or false if plugin constant, class or function not detected.
292
*/
293
public function detect_plugin_multi( array $plugins ) {
294
inc/classes/doing-it-right.class.php CHANGED
@@ -571,10 +571,11 @@ class Doing_It_Right extends Generate_Ldjson {
571
[
572
$args['width'],
573
vsprintf(
574
- '<span class="tsf-seo-bar-item tsf-tooltip-item %1$s" aria-label="%2$s" data-desc="%2$s">%3$s</span>',
575
[
576
$args['class'],
577
$args['notice'],
578
$args['indicator'],
579
]
580
),
571
[
572
$args['width'],
573
vsprintf(
574
+ '<span class="tsf-seo-bar-item tsf-tooltip-item %s" data-desc="%s" aria-label="%s">%s</span>',
575
[
576
$args['class'],
577
$args['notice'],
578
+ $this->strip_tags_cs( $args['notice'], [ 'clear' => 'br' ] ),
579
$args['indicator'],
580
]
581
),
inc/classes/generate-description.class.php CHANGED
@@ -104,7 +104,7 @@ class Generate_Description extends Generate {
104
* Falls back to meta description.
105
*
106
* @since 3.1.0
107
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
108
* @see $this->get_open_graph_description()
109
* @see $this->get_open_graph_description_from_custom_field()
110
*
@@ -138,7 +138,7 @@ class Generate_Description extends Generate {
138
* Falls back to meta description.
139
*
140
* @since 3.1.0
141
- * @since 3.2.2: 1. Now tests for the home page as page prior getting custom field data.
142
* 2. Now obtains custom field data for terms.
143
* @see $this->get_open_graph_description()
144
* @see $this->get_open_graph_description_from_custom_field()
@@ -221,7 +221,7 @@ class Generate_Description extends Generate {
221
* Falls back to Open Graph description.
222
*
223
* @since 3.1.0
224
- * @since 3.2.2: 1. Now tests for the home page as page prior getting custom field data.
225
* 2. Now obtains custom field data for terms.
226
* @see $this->get_twitter_description()
227
* @see $this->get_twitter_description_from_custom_field()
@@ -260,7 +260,7 @@ class Generate_Description extends Generate {
260
* Falls back to Open Graph description.
261
*
262
* @since 3.1.0
263
- * @since 3.2.2: 1. Now tests for the home page as page prior getting custom field data.
264
* 2. Now obtains custom field data for terms.
265
* @see $this->get_twitter_description()
266
* @see $this->get_twitter_description_from_custom_field()
@@ -338,7 +338,7 @@ class Generate_Description extends Generate {
338
* Gets a custom description, based on expected or current query, without escaping.
339
*
340
* @since 3.1.0
341
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
342
* @internal
343
* @see $this->get_description_from_custom_field()
344
*
@@ -370,7 +370,7 @@ class Generate_Description extends Generate {
370
* Gets a custom description, based on input arguments query, without escaping.
371
*
372
* @since 3.1.0
373
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
374
* @internal
375
* @see $this->get_description_from_custom_field()
376
*
@@ -411,7 +411,6 @@ class Generate_Description extends Generate {
411
* 2. Now no longer converts additions into excerpt when no excerpt is found.
412
* @since 3.2.2 Now converts HTML characters prior trimming.
413
* @uses $this->generate_description()
414
- * @staticvar array $cache
415
*
416
* @param array|null $args An array of 'id' and 'taxonomy' values.
417
* Accepts int values for backward compatibility.
@@ -653,7 +652,7 @@ class Generate_Description extends Generate {
653
* @since 3.1.0
654
* @since 3.2.0 : 1. Now no longer listens to options.
655
* 2. Now only works for the front and blog pages.
656
- * @since 3.2.2 Now works for home pages from external requests.
657
* @see $this->get_generated_description()
658
*
659
* @param array|null $args An array of 'id' and 'taxonomy' values.
104
* Falls back to meta description.
105
*
106
* @since 3.1.0
107
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
108
* @see $this->get_open_graph_description()
109
* @see $this->get_open_graph_description_from_custom_field()
110
*
138
* Falls back to meta description.
139
*
140
* @since 3.1.0
141
+ * @since 3.2.2: 1. Now tests for the homepage as page prior getting custom field data.
142
* 2. Now obtains custom field data for terms.
143
* @see $this->get_open_graph_description()
144
* @see $this->get_open_graph_description_from_custom_field()
221
* Falls back to Open Graph description.
222
*
223
* @since 3.1.0
224
+ * @since 3.2.2: 1. Now tests for the homepage as page prior getting custom field data.
225
* 2. Now obtains custom field data for terms.
226
* @see $this->get_twitter_description()
227
* @see $this->get_twitter_description_from_custom_field()
260
* Falls back to Open Graph description.
261
*
262
* @since 3.1.0
263
+ * @since 3.2.2: 1. Now tests for the homepage as page prior getting custom field data.
264
* 2. Now obtains custom field data for terms.
265
* @see $this->get_twitter_description()
266
* @see $this->get_twitter_description_from_custom_field()
338
* Gets a custom description, based on expected or current query, without escaping.
339
*
340
* @since 3.1.0
341
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
342
* @internal
343
* @see $this->get_description_from_custom_field()
344
*
370
* Gets a custom description, based on input arguments query, without escaping.
371
*
372
* @since 3.1.0
373
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
374
* @internal
375
* @see $this->get_description_from_custom_field()
376
*
411
* 2. Now no longer converts additions into excerpt when no excerpt is found.
412
* @since 3.2.2 Now converts HTML characters prior trimming.
413
* @uses $this->generate_description()
414
*
415
* @param array|null $args An array of 'id' and 'taxonomy' values.
416
* Accepts int values for backward compatibility.
652
* @since 3.1.0
653
* @since 3.2.0 : 1. Now no longer listens to options.
654
* 2. Now only works for the front and blog pages.
655
+ * @since 3.2.2 Now works for homepages from external requests.
656
* @see $this->get_generated_description()
657
*
658
* @param array|null $args An array of 'id' and 'taxonomy' values.
inc/classes/generate-ldjson.class.php CHANGED
@@ -150,7 +150,7 @@ class Generate_Ldjson extends Generate_Image {
150
$output = $transient_name ? $this->get_transient( $transient_name ) : false;
151
if ( false === $output ) :
152
if ( $this->is_real_front_page() ) {
153
- //= Home page Schema.
154
$output = '';
155
156
$output .= $this->get_ld_json_website() ?: '';
@@ -364,7 +364,7 @@ class Generate_Ldjson extends Generate_Image {
364
$items = [];
365
$parents = array_reverse( \get_post_ancestors( $this->get_the_real_ID() ) );
366
367
- $position = 1; // 0 is the home page.
368
foreach ( $parents as $parent_id ) {
369
370
++$position;
@@ -647,8 +647,8 @@ class Generate_Ldjson extends Generate_Image {
647
* Generates homepage LD+JSON breadcrumb.
648
*
649
* @since 2.9.3
650
- * @since 3.2.2: 1. The title now works for the home page as blog.
651
- * 2. The image has been disabled for the home page as blog.
652
* - I couldn't fix it without evading the API, which is bad.
653
* @staticvar array $crumb
654
*
150
$output = $transient_name ? $this->get_transient( $transient_name ) : false;
151
if ( false === $output ) :
152
if ( $this->is_real_front_page() ) {
153
+ //= Homepage Schema.
154
$output = '';
155
156
$output .= $this->get_ld_json_website() ?: '';
364
$items = [];
365
$parents = array_reverse( \get_post_ancestors( $this->get_the_real_ID() ) );
366
367
+ $position = 1; // 0 is the homepage.
368
foreach ( $parents as $parent_id ) {
369
370
++$position;
647
* Generates homepage LD+JSON breadcrumb.
648
*
649
* @since 2.9.3
650
+ * @since 3.2.2: 1. The title now works for the homepage as blog.
651
+ * 2. The image has been disabled for the homepage as blog.
652
* - I couldn't fix it without evading the API, which is bad.
653
* @staticvar array $crumb
654
*
inc/classes/generate-title.class.php CHANGED
@@ -28,6 +28,9 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
28
*
29
* Generates title SEO data based on content.
30
*
31
* @since 2.8.0
32
*/
33
class Generate_Title extends Generate_Description {
@@ -98,6 +101,8 @@ class Generate_Title extends Generate_Description {
98
* Returns the autogenerated meta title.
99
*
100
* @since 3.1.0
101
* @uses $this->s_title_raw() : This is the same method used to prepare custom title on save.
102
* @uses $this->build_generated_title()
103
*
@@ -112,7 +117,7 @@ class Generate_Title extends Generate_Description {
112
* Filters the title from query.
113
*
114
* @NOTE: This filter doesn't consistently run on the SEO Settings page.
115
- * You might want to avoid this filter on the home page.
116
* @since 3.1.0
117
* @param string $title The title.
118
* @param array $args The title arguments.
@@ -122,16 +127,14 @@ class Generate_Title extends Generate_Description {
122
$args,
123
] );
124
125
- $this->merge_title_protection( $title, $args );
126
- //? Only add protection if the query is autodetermined, and on a real page.
127
- if ( null === $args
128
- && ! ( $this->is_404() || $this->is_admin() ) ) {
129
$this->merge_title_pagination( $title );
130
- }
131
132
- if ( $this->use_title_branding( $args ) ) {
133
$this->merge_title_branding( $title, $args );
134
- }
135
136
$title = $this->s_title_raw( $title );
137
@@ -187,7 +190,7 @@ class Generate_Title extends Generate_Description {
187
* Falls back to Open Graph title.
188
*
189
* @since 3.1.0
190
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
191
* @see $this->get_twitter_title()
192
* @see $this->get_twitter_title_from_custom_field()
193
*
@@ -223,7 +226,7 @@ class Generate_Title extends Generate_Description {
223
* Falls back to Open Graph title.
224
*
225
* @since 3.1.0
226
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
227
* @see $this->get_twitter_title()
228
* @see $this->get_twitter_title_from_custom_field()
229
*
@@ -324,7 +327,7 @@ class Generate_Title extends Generate_Description {
324
* Falls back to meta title.
325
*
326
* @since 3.1.0
327
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
328
* @see $this->get_open_graph_title()
329
* @see $this->get_open_graph_title_from_custom_field()
330
*
@@ -354,7 +357,7 @@ class Generate_Title extends Generate_Description {
354
* Falls back to meta title.
355
*
356
* @since 3.1.0
357
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
358
* @see $this->get_open_graph_title()
359
* @see $this->get_open_graph_title_from_custom_field()
360
*
@@ -430,7 +433,7 @@ class Generate_Title extends Generate_Description {
430
* Gets a custom title, based on current query, without additions or prefixes.
431
*
432
* @since 3.1.0
433
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
434
* @internal
435
* @see $this->get_raw_custom_field_title()
436
*
@@ -463,7 +466,7 @@ class Generate_Title extends Generate_Description {
463
*
464
* @since 3.1.0
465
* @since 3.1.4 Now uses the 'id' to get custom singular title.
466
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
467
* @internal
468
* @see $this->get_raw_custom_field_title()
469
*
@@ -1005,7 +1008,6 @@ class Generate_Title extends Generate_Description {
1005
return compact( 'addition', 'seplocation' );
1006
}
1007
1008
-
1009
/**
1010
* Returns the addition and seplocation from arguments.
1011
*
@@ -1163,6 +1165,60 @@ class Generate_Title extends Generate_Description {
1163
return $this->get_title_seplocation( true );
1164
}
1165
1166
/**
1167
* Determines whether to add or remove title branding additions.
1168
*
@@ -1254,7 +1310,7 @@ class Generate_Title extends Generate_Description {
1254
}
1255
1256
/**
1257
- * Determines whether to add home page tagline.
1258
*
1259
* @since 2.6.0
1260
* @since 3.0.4 Now checks for custom tagline or blogname existence.
@@ -1278,7 +1334,7 @@ class Generate_Title extends Generate_Description {
1278
}
1279
1280
/**
1281
- * Returns the home page tagline from option or bloginfo, when set.
1282
*
1283
* @since 3.0.4
1284
* @uses $this->get_blogdescription(), this method already trims.
28
*
29
* Generates title SEO data based on content.
30
*
31
+ * NOTE: Don't supply $args in any of the methods for non-term taxomies, like author archives.
32
+ * ID collision isn't accounted for in these scenarios.
33
+ *
34
* @since 2.8.0
35
*/
36
class Generate_Title extends Generate_Description {
101
* Returns the autogenerated meta title.
102
*
103
* @since 3.1.0
104
+ * @since 3.x.x 1. Added check for title protection.
105
+ * 2. Moved check for title pagination.
106
* @uses $this->s_title_raw() : This is the same method used to prepare custom title on save.
107
* @uses $this->build_generated_title()
108
*
117
* Filters the title from query.
118
*
119
* @NOTE: This filter doesn't consistently run on the SEO Settings page.
120
+ * You might want to avoid this filter on the homepage.
121
* @since 3.1.0
122
* @param string $title The title.
123
* @param array $args The title arguments.
127
$args,
128
] );
129
130
+ if ( $this->use_title_protection( $args ) )
131
+ $this->merge_title_protection( $title, $args );
132
+
133
+ if ( $this->use_title_pagination( $args ) )
134
$this->merge_title_pagination( $title );
135
136
+ if ( $this->use_title_branding( $args ) )
137
$this->merge_title_branding( $title, $args );
138
139
$title = $this->s_title_raw( $title );
140
190
* Falls back to Open Graph title.
191
*
192
* @since 3.1.0
193
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
194
* @see $this->get_twitter_title()
195
* @see $this->get_twitter_title_from_custom_field()
196
*
226
* Falls back to Open Graph title.
227
*
228
* @since 3.1.0
229
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
230
* @see $this->get_twitter_title()
231
* @see $this->get_twitter_title_from_custom_field()
232
*
327
* Falls back to meta title.
328
*
329
* @since 3.1.0
330
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
331
* @see $this->get_open_graph_title()
332
* @see $this->get_open_graph_title_from_custom_field()
333
*
357
* Falls back to meta title.
358
*
359
* @since 3.1.0
360
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
361
* @see $this->get_open_graph_title()
362
* @see $this->get_open_graph_title_from_custom_field()
363
*
433
* Gets a custom title, based on current query, without additions or prefixes.
434
*
435
* @since 3.1.0
436
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
437
* @internal
438
* @see $this->get_raw_custom_field_title()
439
*
466
*
467
* @since 3.1.0
468
* @since 3.1.4 Now uses the 'id' to get custom singular title.
469
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
470
* @internal
471
* @see $this->get_raw_custom_field_title()
472
*
1008
return compact( 'addition', 'seplocation' );
1009
}
1010
1011
/**
1012
* Returns the addition and seplocation from arguments.
1013
*
1165
return $this->get_title_seplocation( true );
1166
}
1167
1168
+ /**
1169
+ * Determines whether to add or remove title protection prefixes.
1170
+ *
1171
+ * NOTE: This does not guarantee that protection is to be added.
1172
+ *
1173
+ * @since 3.x.x
1174
+ * @see $this->merge_title_protection()
1175
+ *
1176
+ * @param array|null $args The query arguments. Accepts 'id' and 'taxonomy'.
1177
+ * Leave null to autodetermine query.
1178
+ * @return bool True when prefixes are allowed.
1179
+ */
1180
+ public function use_title_protection( $args = null ) {
1181
+
1182
+ if ( null === $args ) {
1183
+ $use = $this->is_singular();
1184
+ } else {
1185
+ $this->fix_generation_args( $args );
1186
+ $use = $args && ! $args['taxonomy'];
1187
+ }
1188
+
1189
+ return $use;
1190
+ }
1191
+
1192
+ /**
1193
+ * Determines whether to add or remove title pagination additions.
1194
+ *
1195
+ * NOTE: This does not guarantee that pagination is to be added.
1196
+ * @see $this->paged()
1197
+ * @see $this->page()
1198
+ *
1199
+ * @since 3.x.x
1200
+ * @see $this->merge_title_pagination()
1201
+ *
1202
+ * @param array|null $args The query arguments. Accepts 'id' and 'taxonomy'.
1203
+ * Leave null to autodetermine query.
1204
+ * @return bool True when additions are allowed.
1205
+ */
1206
+ public function use_title_pagination( $args = null ) {
1207
+
1208
+ //? Only add pagination if the query is autodetermined, and on a real page.
1209
+ if ( null === $args ) {
1210
+ if ( $this->is_404() || $this->is_admin() ) {
1211
+ $use = false;
1212
+ } else {
1213
+ $use = true;
1214
+ }
1215
+ } else {
1216
+ $use = false;
1217
+ }
1218
+
1219
+ return $use;
1220
+ }
1221
+
1222
/**
1223
* Determines whether to add or remove title branding additions.
1224
*
1310
}
1311
1312
/**
1313
+ * Determines whether to add homepage tagline.
1314
*
1315
* @since 2.6.0
1316
* @since 3.0.4 Now checks for custom tagline or blogname existence.
1334
}
1335
1336
/**
1337
+ * Returns the homepage tagline from option or bloginfo, when set.
1338
*
1339
* @since 3.0.4
1340
* @uses $this->get_blogdescription(), this method already trims.
inc/classes/generate-url.class.php CHANGED
@@ -32,6 +32,37 @@ defined( 'THE_SEO_FRAMEWORK_PRESENT' ) or die;
32
*/
33
class Generate_Url extends Generate_Title {
34
35
/**
36
* Caches and returns the current URL.
37
*
@@ -49,6 +80,8 @@ class Generate_Url extends Generate_Title {
49
* Caches and returns the current permalink.
50
* This link excludes any pagination. Great for structured data.
51
*
52
* @since 3.0.0
53
* @since 3.1.0 Now properly generates taxonomical URLs.
54
* @staticvar string $cache
@@ -106,6 +139,7 @@ class Generate_Url extends Generate_Title {
106
107
/**
108
* Returns the current canonical URL.
109
*
110
* @since 3.0.0
111
* @see $this->create_canonical_url()
@@ -142,7 +176,7 @@ class Generate_Url extends Generate_Title {
142
* Builds canonical URL from input arguments.
143
*
144
* @since 3.0.0
145
- * @since 3.2.2 Now tests for the home page as page prior getting custom field data.
146
* @see $this->create_canonical_url()
147
*
148
* @param array $args. Use $this->create_canonical_url().
@@ -196,7 +230,6 @@ class Generate_Url extends Generate_Title {
196
$url = $this->get_home_canonical_url();
197
} elseif ( $this->is_singular() ) {
198
$url = $this->get_singular_custom_canonical_url( $id );
199
-
200
if ( ! $url )
201
$url = $this->get_singular_canonical_url( $id );
202
} elseif ( $this->is_archive() ) {
@@ -248,6 +281,9 @@ class Generate_Url extends Generate_Title {
248
* Automatically adds pagination if the ID matches the query.
249
*
250
* @since 3.0.0
251
*
252
* @return string The home canonical URL.
253
*/
@@ -256,15 +292,31 @@ class Generate_Url extends Generate_Title {
256
//= Prevent admin bias by passing preferred scheme.
257
$url = \get_home_url( null, '', $this->get_preferred_scheme() );
258
259
- if ( $url ) {
260
- if ( $this->get_the_real_ID() === (int) \get_option( 'page_for_posts' ) ) {
261
- $url = $this->add_url_pagination( $url, $this->paged(), true );
262
}
263
264
- return \user_trailingslashit( $url );
265
}
266
267
- return '';
268
}
269
270
/**
@@ -281,34 +333,30 @@ class Generate_Url extends Generate_Title {
281
282
/**
283
* Returns singular canonical URL.
284
- * Automatically adds pagination if the ID matches the query.
285
- *
286
- * Prevents SEO attacks regarding pagination.
287
*
288
* @since 3.0.0
289
* @since 3.1.0 Added WC Shop and WP Blog (as page) pagination integration via $this->paged().
290
*
291
* @param int|null $id The page ID.
292
* @return string The custom canonical URL, if any.
293
*/
294
public function get_singular_canonical_url( $id = null ) {
295
296
- $canonical_url = \wp_get_canonical_url( $id );
297
298
- if ( ! $canonical_url )
299
- return '';
300
-
301
- //* @link https://core.trac.wordpress.org/ticket/37505
302
- $_page = \get_query_var( 'page', 0 );
303
- if ( $_page !== $this->page() ) {
304
- $canonical_url = $this->remove_pagination_from_url( $canonical_url, $_page );
305
}
306
- $_paged = \get_query_var( 'paged', 0 );
307
- if ( $_paged === $this->paged() ) {
308
- $canonical_url = $this->add_url_pagination( $canonical_url, $_paged, true );
309
}
310
311
- return $canonical_url;
312
}
313
314
/**
@@ -461,7 +509,7 @@ class Generate_Url extends Generate_Title {
461
$_paginate = false;
462
463
if ( ! isset( $query ) ) {
464
- $query = \get_search_query( false );
465
$_paginate = true;
466
}
467
@@ -572,31 +620,50 @@ class Generate_Url extends Generate_Title {
572
* Adds pagination to input URL.
573
*
574
* @since 3.0.0
575
*
576
* @param string $url The fully qualified URL.
577
* @param int $page The page number. Should be bigger than 1 to paginate.
578
- * @param bool $use_base Whether to use pagination base. True on archives, false on pages.
579
* @return string The fully qualified URL with pagination.
580
*/
581
- public function add_url_pagination( $url, $page, $use_base ) {
582
583
- if ( $page < 2 )
584
return $url;
585
586
if ( $this->pretty_permalinks ) {
587
- if ( $use_base ) {
588
- static $base;
589
- $base = $base ?: $GLOBALS['wp_rewrite']->pagination_base;
590
591
- $url = \user_trailingslashit( \trailingslashit( $url ) . $base . '/' . $page, 'single_paged' );
592
} else {
593
- $url = \user_trailingslashit( \trailingslashit( $url ) . $page, 'single_paged' );
594
}
595
} else {
596
- if ( $use_base ) {
597
- $url = \add_query_arg( 'paged', $page, $url );
598
} else {
599
- $url = \add_query_arg( 'page', $page, $url );
600
}
601
}
602
@@ -605,44 +672,59 @@ class Generate_Url extends Generate_Title {
605
606
/**
607
* Removes pagination from input URL.
608
- * The URL must match this query.
609
*
610
* @since 3.0.0
611
- *
612
- * @param string $url The fully qualified URL to remove pagination from.
613
- * @param int $page The page number to remove. If empty, it will get query.
614
- * @param int $paged The page number to remove. If empty, it will get query.
615
* @return string $url The fully qualified URL without pagination.
616
*/
617
- protected function remove_pagination_from_url( $url, $page = 0, $paged = 0 ) {
618
619
if ( $this->pretty_permalinks ) {
620
//* Defensive programming...
621
- static $user_slash;
622
$user_slash = isset( $user_slash ) ? $user_slash :
623
( $GLOBALS['wp_rewrite']->use_trailing_slashes ? '/' : '' );
624
625
- $paged = $paged ?: $this->paged();
626
- $page = $page ?: $this->page();
627
628
- $find = '';
629
630
- if ( $paged > 1 ) {
631
- static $base;
632
- $base = $base ?: $GLOBALS['wp_rewrite']->pagination_base;
633
634
- $find = '/' . $base . '/' . $paged . $user_slash;
635
- } elseif ( $page > 1 ) {
636
- $find = '/' . $page . $user_slash;
637
- }
638
639
- if ( $find ) {
640
$pos = strrpos( $url, $find );
641
- //* Defensive programming...
642
$continue = $pos && $pos + strlen( $find ) === strlen( $url );
643
if ( $continue ) {
644
$url = substr( $url, 0, $pos );
645
$url = \user_trailingslashit( $url );
646
}
647
}
648
} else {
@@ -656,6 +738,7 @@ class Generate_Url extends Generate_Title {
656
* Adjusts category post link.
657
*
658
* @since 3.0.0
659
*
660
* @param \WP_Term $term The category to use in the permalink.
661
* @param array $terms Array of all categories (WP_Term objects) associated with the post.
@@ -764,20 +847,25 @@ class Generate_Url extends Generate_Title {
764
* Generates Previous and Next links.
765
*
766
* @since 3.1.0
767
- * @staticvar array $ret
768
*
769
- * @param string $prev_next Whether to get the previous or next page link.
770
- * Accepts 'prev' and 'next'.
771
- * @return array Escaped site Pagination URL
772
*/
773
public function get_paged_urls() {
774
775
- static $ret;
776
- if ( isset( $ret ) ) return $ret;
777
778
$prev = $next = '';
779
$_run = false;
780
781
if ( $this->is_singular() && ! $this->is_singular_archive() && $this->is_multipage() ) {
782
$_run = $this->is_real_front_page()
783
? $this->get_option( 'prev_next_frontpage' )
@@ -785,7 +873,6 @@ class Generate_Url extends Generate_Title {
785
786
if ( ! $_run ) goto end;
787
788
- $archive = false;
789
$page = $this->page();
790
$_numpages = $this->numpages();
791
} elseif ( $this->is_real_front_page() || $this->is_archive() || $this->is_singular_archive() || $this->is_search() ) {
@@ -795,27 +882,26 @@ class Generate_Url extends Generate_Title {
795
796
if ( ! $_run ) goto end;
797
798
- $archive = true;
799
$page = $this->paged();
800
$_numpages = $this->numpages();
801
}
802
803
- if ( ! $_run ) goto end;
804
-
805
$canonical = $this->remove_pagination_from_url( $this->get_current_canonical_url() );
806
807
// If this page is not the last, create a next-URL.
808
if ( $page + 1 <= $_numpages ) {
809
- $next = $this->add_url_pagination( $canonical, $page + 1, $archive );
810
}
811
// If this page is not the first, create a prev-URL.
812
if ( $page > 1 ) {
813
- $prev = $this->add_url_pagination( $canonical, $page - 1, $archive );
814
}
815
816
end:;
817
818
- return $ret = compact( 'next', 'prev' );
819
}
820
821
/**
32
*/
33
class Generate_Url extends Generate_Title {
34
35
+ /**
36
+ * Determines if the given page has a custom canonical URL.
37
+ *
38
+ * @since 3.2.4
39
+ *
40
+ * @param null|array $args The canonical URL arguments, leave null to autodetermine query : {
41
+ * int $id The Post, Page or Term ID to generate the URL for.
42
+ * string $taxonomy The taxonomy.
43
+ * }
44
+ * @return bool
45
+ */
46
+ public function has_custom_canonical_url( $args = null ) {
47
+
48
+ if ( ! $args ) {
49
+ if ( $this->is_singular() ) {
50
+ $has = $this->get_singular_custom_canonical_url( $this->get_the_real_ID() );
51
+ } else {
52
+ $has = false;
53
+ }
54
+ } else {
55
+ $this->fix_generation_args( $args );
56
+ if ( ! $args || $args['taxonomy'] ) {
57
+ $has = false;
58
+ } else {
59
+ $has = $this->get_singular_custom_canonical_url( $args['id'] );
60
+ }
61
+ }
62
+
63
+ return (bool) $has;
64
+ }
65
+
66
/**
67
* Caches and returns the current URL.
68
*
80
* Caches and returns the current permalink.
81
* This link excludes any pagination. Great for structured data.
82
*
83
+ * Does not work for unregistered pages, like search, 404, date, author, and CPTA.
84
+ *
85
* @since 3.0.0
86
* @since 3.1.0 Now properly generates taxonomical URLs.
87
* @staticvar string $cache
139
140
/**
141
* Returns the current canonical URL.
142
+ * Removes pagination if the URL isn't obtained via the query.
143
*
144
* @since 3.0.0
145
* @see $this->create_canonical_url()
176
* Builds canonical URL from input arguments.
177
*
178
* @since 3.0.0
179
+ * @since 3.2.2 Now tests for the homepage as page prior getting custom field data.
180
* @see $this->create_canonical_url()
181
*
182
* @param array $args. Use $this->create_canonical_url().
230
$url = $this->get_home_canonical_url();
231
} elseif ( $this->is_singular() ) {
232
$url = $this->get_singular_custom_canonical_url( $id );
233
if ( ! $url )
234
$url = $this->get_singular_canonical_url( $id );
235
} elseif ( $this->is_archive() ) {
281
* Automatically adds pagination if the ID matches the query.
282
*
283
* @since 3.0.0
284
+ * @since 3.2.4 1. Now adds a slash to the home URL when it's a root URL.
285
+ * 2. Now skips slashing when queries have been appended to the URL.
286
+ * 3. Home-as-page pagination is now supported.
287
*
288
* @return string The home canonical URL.
289
*/
292
//= Prevent admin bias by passing preferred scheme.
293
$url = \get_home_url( null, '', $this->get_preferred_scheme() );
294
295
+ if ( ! $url ) return '';
296
+
297
+ $query_id = $this->get_the_real_ID();
298
+
299
+ if ( $this->has_page_on_front() ) {
300
+ if ( $this->is_static_frontpage( $query_id ) ) {
301
+ // Yes, use the pagination base for the homepage-as-page!
302
+ $url = $this->add_url_pagination( $url, $this->page(), true );
303
}
304
+ } elseif ( (int) \get_option( 'page_for_posts' ) === $query_id ) {
305
+ $url = $this->add_url_pagination( $url, $this->paged(), true );
306
+ }
307
308
+ $parsed = parse_url( $url );
309
+
310
+ // Don't slash the home URL if it's been modified by a (translation) plugin.
311
+ if ( ! isset( $parsed['query'] ) ) {
312
+ if ( isset( $parsed['path'] ) && '/' !== $parsed['path'] ) {
313
+ $url = \user_trailingslashit( $url, 'home' );
314
+ } else {
315
+ $url = \trailingslashit( $url );
316
+ }
317
}
318
319
+ return $url;
320
}
321
322
/**
333
334
/**
335
* Returns singular canonical URL.
336
*
337
* @since 3.0.0
338
* @since 3.1.0 Added WC Shop and WP Blog (as page) pagination integration via $this->paged().
339
+ * @since 3.2.4 Removed pagination support for singular posts, as the SEO attack is now mitigated via WordPress.
340
*
341
* @param int|null $id The page ID.
342
* @return string The custom canonical URL, if any.
343
*/
344
public function get_singular_canonical_url( $id = null ) {
345
346
+ $url = \wp_get_canonical_url( $id ) ?: '';
347
348
+ $_page = \get_query_var( 'page', 1 ) ?: 1; // WP_Query tests isset, not empty.
349
+ if ( $url && $_page !== $this->page() ) {
350
+ /** @link https://core.trac.wordpress.org/ticket/37505 */
351
+ $url = $this->remove_pagination_from_url( $url, $_page, false );
352
}
353
+
354
+ if ( $url && $this->is_singular_archive() ) {
355
+ // Singular archives, like blog pages and shop pages, use the pagination base with paged.
356
+ $url = $this->add_url_pagination( $url, $this->paged(), true );
357
}
358
359
+ return $url;
360
}
361
362
/**
509
$_paginate = false;
510
511
if ( ! isset( $query ) ) {
512
+ $query = \get_search_query( false );
513
$_paginate = true;
514
}
515
620
* Adds pagination to input URL.
621
*
622
* @since 3.0.0
623
+ * @since 3.2.4 1. Now considers query arguments when using pretty permalinks.
624
+ * 2. The second and third parameters are now optional.
625
*
626
* @param string $url The fully qualified URL.
627
* @param int $page The page number. Should be bigger than 1 to paginate.
628
+ * @param bool $use_base Whether to use pagination base.
629
+ * If null, it will autodetermine.
630
+ * Should be true on archives and the homepage (blog and static!).
631
+ * False on singular post types.
632
* @return string The fully qualified URL with pagination.
633
*/
634
+ public function add_url_pagination( $url, $page = null, $use_base = null ) {
635
+
636
+ $_page = isset( $page ) ? $page : max( $this->paged(), $this->page() );
637
638
+ if ( $_page < 2 )
639
return $url;
640
641
+ $_use_base = isset( $use_base ) ? $use_base :
642
+ $this->is_archive() || $this->is_real_front_page() || $this->is_singular_archive();
643
+
644
if ( $this->pretty_permalinks ) {
645
646
+ $_query = parse_url( $url, PHP_URL_QUERY );
647
+ // Remove queries, add them back later.
648
+ if ( $_query )
649
+ $url = $this->s_url( $url );
650
+
651
+ static $base;
652
+ $base = $base ?: $GLOBALS['wp_rewrite']->pagination_base;
653
+
654
+ if ( $_use_base ) {
655
+ $url = \user_trailingslashit( \trailingslashit( $url ) . $base . '/' . $_page, 'paged' );
656
} else {
657
+ $url = \user_trailingslashit( \trailingslashit( $url ) . $_page, 'single_paged' );
658
}
659
+
660
+ if ( $_query )
661
+ $url = $this->append_php_query( $url, $_query );
662
} else {
663
+ if ( $_use_base ) {
664
+ $url = \add_query_arg( 'paged', $_page, $url );
665
} else {
666
+ $url = \add_query_arg( 'page', $_page, $url );
667
}
668
}
669
672
673
/**
674
* Removes pagination from input URL.
675
+ * The URL must match this query if no second parameter is provided.
676
*
677
* @since 3.0.0
678
+ * @since 3.2.4 1. Now correctly removes the pagination base on singular post types.
679
+ * 2. The second parameter now accepts null or a value.
680
+ * 3. The third parameter is now changed to $use_base, from the archive pagination number.
681
+ * 4. Now supports pretty permalinks with query parameters.
682
+ * 5. Is now public.
683
+ *
684
+ * @param string $url The fully qualified URL to remove pagination from.
685
+ * @param int|null $page The page number to remove. If null, it will get number from query.
686
+ * @param bool|null $use_base Whether to remove the pagination base.
687
+ * If null, it will autodetermine.
688
+ * Should be true on archives and the homepage (blog and static!).
689
+ * False on singular post types.
690
* @return string $url The fully qualified URL without pagination.
691
*/
692
+ public function remove_pagination_from_url( $url, $page = null, $use_base = null ) {
693
694
if ( $this->pretty_permalinks ) {
695
//* Defensive programming...
696
+ static $user_slash, $base;
697
$user_slash = isset( $user_slash ) ? $user_slash :
698
( $GLOBALS['wp_rewrite']->use_trailing_slashes ? '/' : '' );
699
+ $base = isset( $base ) ? $base : $GLOBALS['wp_rewrite']->pagination_base;
700
701
+ $_page = isset( $page ) ? $page : max( $this->paged(), $this->page() );
702
703
+ if ( $_page > 1 ) {
704
+ $_use_base = isset( $use_base ) ? $use_base
705
+ : $this->is_archive() || $this->is_real_front_page() || $this->is_singular_archive();
706
707
+ if ( $_use_base ) {
708
+ $find = '/' . $base . '/' . $_page . $user_slash;
709
+ } else {
710
+ $find = '/' . $_page . $user_slash;
711
+ }
712
713
+ $_query = parse_url( $url, PHP_URL_QUERY );
714
+ // Remove queries, add them back later.
715
+ if ( $_query )
716
+ $url = $this->s_url( $url );
717
718
$pos = strrpos( $url, $find );
719
+ //* Defensive programming, only remove if $find matches the stack length, without query arguments.
720
$continue = $pos && $pos + strlen( $find ) === strlen( $url );
721
+
722
if ( $continue ) {
723
$url = substr( $url, 0, $pos );
724
$url = \user_trailingslashit( $url );
725
+
726
+ if ( $_query )
727
+ $url = $this->append_php_query( $url, $_query );
728
}
729
}
730
} else {
738
* Adjusts category post link.
739
*
740
* @since 3.0.0
741
+ * @access private
742
*
743
* @param \WP_Term $term The category to use in the permalink.
744
* @param array $terms Array of all categories (WP_Term objects) associated with the post.
847
* Generates Previous and Next links.
848
*
849
* @since 3.1.0
850
+ * @since 3.2.4 1. Now correctly removes the pagination base from singular URLs.
851
+ * 2. Now returns no URLs when a custom canonical URL is set.
852
+ * @staticvar array $cache
853
*
854
+ * @return array Escaped site Pagination URLs: {
855
+ * string 'prev'
856
+ * string 'next'
857
+ * }
858
*/
859
public function get_paged_urls() {
860
861
+ static $cache;
862
+ if ( isset( $cache ) ) return $cache;
863
864
$prev = $next = '';
865
$_run = false;
866
867
+ if ( $this->has_custom_canonical_url() ) goto end;
868
+
869
if ( $this->is_singular() && ! $this->is_singular_archive() && $this->is_multipage() ) {
870
$_run = $this->is_real_front_page()
871
? $this->get_option( 'prev_next_frontpage' )
873
874
if ( ! $_run ) goto end;
875
876
$page = $this->page();
877
$_numpages = $this->numpages();
878
} elseif ( $this->is_real_front_page() || $this->is_archive() || $this->is_singular_archive() || $this->is_search() ) {
882
883
if ( ! $_run ) goto end;
884
885
$page = $this->paged();
886
$_numpages = $this->numpages();
887
+ } else {
888
+ goto end;
889
}
890
891
$canonical = $this->remove_pagination_from_url( $this->get_current_canonical_url() );
892
893
// If this page is not the last, create a next-URL.
894
if ( $page + 1 <= $_numpages ) {
895
+ $next = $this->add_url_pagination( $canonical, $page + 1 );
896
}
897
// If this page is not the first, create a prev-URL.
898
if ( $page > 1 ) {
899
+ $prev = $this->add_url_pagination( $canonical, $page - 1 );
900
}
901
902
end:;
903
904
+ return $cache = compact( 'next', 'prev' );
905
}
906
907
/**
inc/classes/generate.class.php CHANGED
@@ -81,7 +81,7 @@ class Generate extends User_Data {
81
'noarchive' => $this->get_option( 'site_noarchive' ) ? 'noarchive' : '',
82
];
83
84
- //* Check home page SEO settings, set noindex, nofollow and noarchive
85
if ( $this->is_real_front_page() ) {
86
$meta['noindex'] = $this->get_option( 'homepage_noindex' ) ? 'noindex' : $meta['noindex'];
87
$meta['nofollow'] = $this->get_option( 'homepage_nofollow' ) ? 'nofollow' : $meta['nofollow'];
@@ -95,7 +95,7 @@ class Generate extends User_Data {
95
96
/**
97
* Check for 404, or if archive is empty: set noindex for those.
98
- * Don't check this on the home page. The home page is sacred in this regard,
99
* because page builders and templates likely take over.
100
* @since 2.2.8
101
*
81
'noarchive' => $this->get_option( 'site_noarchive' ) ? 'noarchive' : '',
82
];
83
84
+ //* Check homepage SEO settings, set noindex, nofollow and noarchive
85
if ( $this->is_real_front_page() ) {
86
$meta['noindex'] = $this->get_option( 'homepage_noindex' ) ? 'noindex' : $meta['noindex'];
87
$meta['nofollow'] = $this->get_option( 'homepage_nofollow' ) ? 'nofollow' : $meta['nofollow'];
95
96
/**
97
* Check for 404, or if archive is empty: set noindex for those.
98
+ * Don't check this on the homepage. The homepage is sacred in this regard,
99
* because page builders and templates likely take over.
100
* @since 2.2.8
101
*
inc/classes/init.class.php CHANGED
@@ -160,6 +160,7 @@ class Init extends Query {
160
161
//* Add plugin links to the plugin activation page.
162
\add_filter( 'plugin_action_links_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, [ $this, '_add_plugin_action_links' ], 10, 2 );
163
164
//* Initialize post states.
165
\add_action( 'current_screen', [ $this, 'post_state' ] );
160
161
//* Add plugin links to the plugin activation page.
162
\add_filter( 'plugin_action_links_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, [ $this, '_add_plugin_action_links' ], 10, 2 );
163
+ \add_filter( 'plugin_row_meta', [ $this, '_add_plugin_row_meta' ], 10, 2 );
164
165
//* Initialize post states.
166
\add_action( 'current_screen', [ $this, 'post_state' ] );
inc/classes/metaboxes.class.php CHANGED
@@ -360,7 +360,7 @@ class Metaboxes extends Site_Options {
360
}
361
362
/**
363
- * Home Page meta box on the Site SEO Settings page.
364
*
365
* @since 2.2.2
366
*
@@ -380,44 +380,44 @@ class Metaboxes extends Site_Options {
380
}
381
382
/**
383
- * HomePage Metabox General Tab Output.
384
*
385
* @since 2.7.0
386
* @since 3.1.0 Is now protected.
387
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
388
*/
389
protected function homepage_metabox_general_tab() {
390
$this->get_view( 'metaboxes/homepage-metabox', [], 'general' );
391
}
392
393
/**
394
- * HomePage Metabox Additions Tab Output.
395
*
396
* @since 2.7.0
397
* @since 3.1.0 Is now protected.
398
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
399
*/
400
protected function homepage_metabox_additions_tab() {
401
$this->get_view( 'metaboxes/homepage-metabox', [], 'additions' );
402
}
403
404
/**
405
- * HomePage Metabox Robots Tab Output
406
*
407
* @since 2.7.0
408
* @since 3.1.0 Is now protected.
409
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
410
*/
411
protected function homepage_metabox_robots_tab() {
412
$this->get_view( 'metaboxes/homepage-metabox', [], 'robots' );
413
}
414
415
/**
416
- * HomePage Metabox Social Tab Output
417
*
418
* @since 2.9.0
419
* @since 3.1.0 Is now protected.
420
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
421
*/
422
protected function homepage_metabox_social_tab() {
423
$this->get_view( 'metaboxes/homepage-metabox', [], 'social' );
360
}
361
362
/**
363
+ * Outputs the Homepage meta box on the Site SEO Settings page.
364
*
365
* @since 2.2.2
366
*
380
}
381
382
/**
383
+ * Homepage Metabox General Tab Output.
384
*
385
* @since 2.7.0
386
* @since 3.1.0 Is now protected.
387
+ * @see $this->homepage_metabox() Callback for Homepage Settings box.
388
*/
389
protected function homepage_metabox_general_tab() {
390
$this->get_view( 'metaboxes/homepage-metabox', [], 'general' );
391
}
392
393
/**
394
+ * Homepage Metabox Additions Tab Output.
395
*
396
* @since 2.7.0
397
* @since 3.1.0 Is now protected.
398
+ * @see $this->homepage_metabox() Callback for Homepage Settings box.
399
*/
400
protected function homepage_metabox_additions_tab() {
401
$this->get_view( 'metaboxes/homepage-metabox', [], 'additions' );
402
}
403
404
/**
405
+ * Homepage Metabox Robots Tab Output
406
*
407
* @since 2.7.0
408
* @since 3.1.0 Is now protected.
409
+ * @see $this->homepage_metabox() Callback for Homepage Settings box.
410
*/
411
protected function homepage_metabox_robots_tab() {
412
$this->get_view( 'metaboxes/homepage-metabox', [], 'robots' );
413
}
414
415
/**
416
+ * Homepage Metabox Social Tab Output
417
*
418
* @since 2.9.0
419
* @since 3.1.0 Is now protected.
420
+ * @see $this->homepage_metabox() Callback for Homepage Settings box.
421
*/
422
protected function homepage_metabox_social_tab() {
423
$this->get_view( 'metaboxes/homepage-metabox', [], 'social' );
inc/classes/query.class.php CHANGED
@@ -629,16 +629,16 @@ class Query extends Compat {
629
/**
630
* Checks for front page by input ID.
631
*
632
- * Doesn't always return true when the ID is 0, although the home page might be.
633
* This is because it checks for the query, to prevent conflicts.
634
* @see $this->is_real_front_page_by_id().
635
*
636
* @since 2.9.0
637
- * @since 2.9.3 Now tests for archive and 404 before testing home page as blog.
638
* @since 3.2.2: Removed SEO settings page check. This now returns false on that page.
639
*
640
* @param int The page ID, required. Can be 0.
641
- * @return bool True if ID if for the home page.
642
*/
643
public function is_front_page_by_id( $id ) {
644
@@ -681,7 +681,7 @@ class Query extends Compat {
681
}
682
683
/**
684
- * Detects home page.
685
*
686
* @since 2.6.0
687
* @staticvar bool $cache
@@ -1123,6 +1123,8 @@ class Query extends Compat {
1123
* Fetches global $page through Query Var to prevent conflicts.
1124
*
1125
* @since 2.6.0
1126
*
1127
* @return int (R>0) $page Always a positive number.
1128
*/
@@ -1131,11 +1133,20 @@ class Query extends Compat {
1131
if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
1132
return $cache;
1133
1134
- $page = $this->is_multipage() ? \get_query_var( 'page' ) : 1;
1135
1136
$this->set_query_cache(
1137
__METHOD__,
1138
- $page = $page ? (int) $page : 1
1139
);
1140
1141
return $page;
@@ -1146,6 +1157,8 @@ class Query extends Compat {
1146
* Fetches global $paged through Query var to prevent conflicts.
1147
*
1148
* @since 2.6.0
1149
*
1150
* @return int (R>0) $paged Always a positive number.
1151
*/
@@ -1154,11 +1167,21 @@ class Query extends Compat {
1154
if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
1155
return $cache;
1156
1157
- $paged = $this->is_multipage() ? \get_query_var( 'paged' ) : 1;
1158
1159
$this->set_query_cache(
1160
__METHOD__,
1161
- $paged = $paged ? (int) $paged : 1
1162
);
1163
1164
return $paged;
@@ -1171,6 +1194,7 @@ class Query extends Compat {
1171
* we need is set up in the loop, not in the header; where TSF is active.
1172
*
1173
* @since 3.1.0
1174
* @global \WP_Query $wp_query
1175
*
1176
* @return int
@@ -1180,6 +1204,8 @@ class Query extends Compat {
1180
if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
1181
return $cache;
1182
1183
global $wp_query;
1184
1185
$post = null;
@@ -1230,6 +1256,7 @@ class Query extends Compat {
1230
* @since 2.7.0
1231
* @since 3.1.0 1. Now also works on archives.
1232
* 2. Now is public.
1233
*
1234
* @return bool True if multipage.
1235
*/
629
/**
630
* Checks for front page by input ID.
631
*
632
+ * Doesn't always return true when the ID is 0, although the homepage might be.
633
* This is because it checks for the query, to prevent conflicts.
634
* @see $this->is_real_front_page_by_id().
635
*
636
* @since 2.9.0
637
+ * @since 2.9.3 Now tests for archive and 404 before testing homepage as blog.
638
* @since 3.2.2: Removed SEO settings page check. This now returns false on that page.
639
*
640
* @param int The page ID, required. Can be 0.
641
+ * @return bool True if ID if for the homepage.
642
*/
643
public function is_front_page_by_id( $id ) {
644
681
}
682
683
/**
684
+ * Determines whether the query is for the blog page.
685
*
686
* @since 2.6.0
687
* @staticvar bool $cache
1123
* Fetches global $page through Query Var to prevent conflicts.
1124
*
1125
* @since 2.6.0
1126
+ * @since 3.2.4 1. Added overflow protection.
1127
+ * 2. Now always returns 1 on the admin screens.
1128
*
1129
* @return int (R>0) $page Always a positive number.
1130
*/
1133
if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
1134
return $cache;
1135
1136
+ if ( $this->is_multipage() ) {
1137
+ $page = (int) \get_query_var( 'page' );
1138
+
1139
+ if ( $page > $this->numpages() ) {
1140
+ // On overflow, WP returns the first page.
1141
+ $page = 1;
1142
+ }
1143
+ } else {
1144
+ $page = 1;
1145
+ }
1146
1147
$this->set_query_cache(
1148
__METHOD__,
1149
+ $page = $page ?: 1
1150
);
1151
1152
return $page;
1157
* Fetches global $paged through Query var to prevent conflicts.
1158
*
1159
* @since 2.6.0
1160
+ * @since 3.2.4 1. Added overflow protection.
1161
+ * 2. Now always returns 1 on the admin screens.
1162
*
1163
* @return int (R>0) $paged Always a positive number.
1164
*/
1167
if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
1168
return $cache;
1169
1170
+ if ( $this->is_multipage() ) {
1171
+ $paged = (int) \get_query_var( 'paged' );
1172
+ $max = $this->numpages();
1173
+
1174
+ if ( $paged > $max ) {
1175
+ // On overflow, WP returns the last page.
1176
+ $paged = $max;
1177
+ }
1178
+ } else {
1179
+ $paged = 1;
1180
+ }
1181
1182
$this->set_query_cache(
1183
__METHOD__,
1184
+ $paged = $paged ?: 1
1185
);
1186
1187
return $paged;
1194
* we need is set up in the loop, not in the header; where TSF is active.
1195
*
1196
* @since 3.1.0
1197
+ * @since 3.2.4 Now only returns "1" in the admin.
1198
* @global \WP_Query $wp_query
1199
*
1200
* @return int
1204
if ( null !== $cache = $this->get_query_cache( __METHOD__ ) )
1205
return $cache;
1206
1207
+ if ( $this->is_admin() ) return 1;
1208
+
1209
global $wp_query;
1210
1211
$post = null;
1256
* @since 2.7.0
1257
* @since 3.1.0 1. Now also works on archives.
1258
* 2. Now is public.
1259
+ * @since 3.2.4 Now always returns false on the admin pages.
1260
*
1261
* @return bool True if multipage.
1262
*/
inc/classes/render.class.php CHANGED
@@ -851,12 +851,15 @@ class Render extends Admin_Init {
851
*
852
* @since 2.0.6
853
* @since 3.0.0 Deleted filter `the_seo_framework_output_canonical`.
854
* @uses $this->get_current_canonical_url()
855
*
856
* @return string The Canonical URL meta tag.
857
*/
858
public function canonical() {
859
860
/**
861
* @since 2.6.5
862
* @param string $url The canonical URL. Must be escaped.
@@ -865,14 +868,20 @@ class Render extends Admin_Init {
865
$url = (string) \apply_filters_ref_array(
866
'the_seo_framework_rel_canonical_output',
867
[
868
- $this->get_current_canonical_url(),
869
$this->get_the_real_ID(),
870
]
871
);
872
873
- /**
874
- * @since 2.7.0 Listens to the second filter.
875
- */
876
if ( $url )
877
return '<link rel="canonical" href="' . $url . '" />' . PHP_EOL;
878
@@ -1031,30 +1040,43 @@ class Render extends Admin_Init {
1031
if ( false === $this->is_blog_public() )
1032
return '';
1033
1034
/**
1035
* @since 2.6.0
1036
* @param array $meta The robots meta.
1037
* @param int $id The current post or term ID.
1038
*/
1039
- $meta = (array) \apply_filters_ref_array(
1040
'the_seo_framework_robots_meta',
1041
[
1042
$this->robots_meta(),
1043
$this->get_the_real_ID(),
1044
]
1045
);
1046
-
1047
- if ( empty( $meta ) )
1048
- return '';
1049
-
1050
- return sprintf( '<meta name="robots" content="%s" />' . PHP_EOL, implode( ',', $meta ) );
1051
}
1052
1053
/**
1054
* Renders Shortlink meta tag
1055
*
1056
* @since 2.2.2
1057
- * @since 2.9.3 : Now work when home page is a blog.
1058
* @uses $this->get_shortlink()
1059
*
1060
* @return string The Shortlink meta tag.
851
*
852
* @since 2.0.6
853
* @since 3.0.0 Deleted filter `the_seo_framework_output_canonical`.
854
+ * @since 3.2.4 Now no longer returns a value when the post is not indexed with a non-custom URL.
855
* @uses $this->get_current_canonical_url()
856
*
857
* @return string The Canonical URL meta tag.
858
*/
859
public function canonical() {
860
861
+ $_url = $this->get_current_canonical_url();
862
+
863
/**
864
* @since 2.6.5
865
* @param string $url The canonical URL. Must be escaped.
868
$url = (string) \apply_filters_ref_array(
869
'the_seo_framework_rel_canonical_output',
870
[
871
+ $_url,
872
$this->get_the_real_ID(),
873
]
874
);
875
876
+ // If the page should not be indexed, consider removing the canonical URL.
877
+ if ( in_array( 'noindex', $this->get_robots_meta(), true ) ) {
878
+ // If the URL is filtered, don't empty it.
879
+ // If a custom canonical URL is set, don't empty it.
880
+ if ( $url === $_url && ! $this->has_custom_canonical_url() ) {
881
+ $url = '';
882
+ }
883
+ }
884
+
885
if ( $url )
886
return '<link rel="canonical" href="' . $url . '" />' . PHP_EOL;
887
1040
if ( false === $this->is_blog_public() )
1041
return '';
1042
1043
+ $meta = $this->get_robots_meta();
1044
+
1045
+ if ( empty( $meta ) )
1046
+ return '';
1047
+
1048
+ return sprintf( '<meta name="robots" content="%s" />' . PHP_EOL, implode( ',', $meta ) );
1049
+ }
1050
+
1051
+ /**
1052
+ * Returns the robots meta array.
1053
+ *
1054
+ * @since 3.2.4
1055
+ * @staticvar array|null $cache
1056
+ *
1057
+ * @return array
1058
+ */
1059
+ public function get_robots_meta() {
1060
+ static $cache = null;
1061
/**
1062
* @since 2.6.0
1063
* @param array $meta The robots meta.
1064
* @param int $id The current post or term ID.
1065
*/
1066
+ return isset( $cache ) ? $cache : $cache = (array) \apply_filters_ref_array(
1067
'the_seo_framework_robots_meta',
1068
[
1069
$this->robots_meta(),
1070
$this->get_the_real_ID(),
1071
]
1072
);
1073
}
1074
1075
/**
1076
* Renders Shortlink meta tag
1077
*
1078
* @since 2.2.2
1079
+ * @since 2.9.3 Now work when homepage is a blog.
1080
* @uses $this->get_shortlink()
1081
*
1082
* @return string The Shortlink meta tag.
inc/classes/sanitize.class.php CHANGED
@@ -94,6 +94,7 @@ class Sanitize extends Admin_Pages {
94
\add_action( "update_option_{$this->settings_field}", [ $this, 'delete_main_cache' ] );
95
\add_action( "update_option_{$this->settings_field}", [ $this, 'reinitialize_rewrite' ], 11 );
96
\add_action( "update_option_{$this->settings_field}", [ $this, 'update_db_version' ], 12 );
97
\add_action( "update_option_{$this->settings_field}", [ $this, '_set_backward_compatibility' ], 13 );
98
}
99
@@ -780,14 +781,21 @@ class Sanitize extends Admin_Pages {
780
//* No need to parse an empty excerpt.
781
if ( '' === $excerpt ) return '';
782
783
/**
784
* @since 2.6.6.1
785
* @param bool $allow_shortcodes Whether to allow shortcodes.
786
*/
787
if ( $allow_shortcodes && \apply_filters( 'the_seo_framework_allow_excerpt_shortcode_tags', false ) ) {
788
- $excerpt = \wp_strip_all_tags( $excerpt );
789
} else {
790
- $excerpt = \wp_strip_all_tags( \strip_shortcodes( $excerpt ) );
791
}
792
793
if ( $escape )
@@ -1462,4 +1470,64 @@ class Sanitize extends Admin_Pages {
1462
public function strip_paragraph_urls( $content ) {
1463
return preg_replace( '/(<p(?: [^>]*)?>\s*)(https?:\/\/[^\s<>"]+)(\s*<\/p>)/i', '', $content );
1464
}
1465
}
94
\add_action( "update_option_{$this->settings_field}", [ $this, 'delete_main_cache' ] );
95
\add_action( "update_option_{$this->settings_field}", [ $this, 'reinitialize_rewrite' ], 11 );
96
\add_action( "update_option_{$this->settings_field}", [ $this, 'update_db_version' ], 12 );
97
+ //* TEMP: Set backward compatibility
98
\add_action( "update_option_{$this->settings_field}", [ $this, '_set_backward_compatibility' ], 13 );
99
}
100
781
//* No need to parse an empty excerpt.
782
if ( '' === $excerpt ) return '';
783
784
+ $strip_args = [
785
+ 'space' =>
786
+ [ 'article', 'aside', 'blockquote', 'dd', 'div', 'dl', 'dt', 'figcaption', 'figure', 'footer', 'li', 'main', 'ol', 'p', 'section', 'tfoot', 'ul' ],
787
+ 'clear' =>
788
+ [ 'address', 'bdo', 'br', 'button', 'canvas', 'code', 'fieldset', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'input', 'label', 'link', 'meta', 'nav', 'noscript', 'option', 'pre', 'samp', 'script', 'select', 'style', 'svg', 'table', 'textarea', 'var', 'video' ],
789
+ ];
790
+
791
/**
792
* @since 2.6.6.1
793
* @param bool $allow_shortcodes Whether to allow shortcodes.
794
*/
795
if ( $allow_shortcodes && \apply_filters( 'the_seo_framework_allow_excerpt_shortcode_tags', false ) ) {
796
+ $excerpt = $this->strip_tags_cs( $excerpt, $strip_args );
797
} else {
798
+ $excerpt = $this->strip_tags_cs( \strip_shortcodes( $excerpt ), $strip_args );
799
}
800
801
if ( $escape )
1470
public function strip_paragraph_urls( $content ) {
1471
return preg_replace( '/(<p(?: [^>]*)?>\s*)(https?:\/\/[^\s<>"]+)(\s*<\/p>)/i', '', $content );
1472
}
1473
+
1474
+ /**
1475
+ * Strips tags with HTML Context-Sensitivity and ouputs its breakdown.
1476
+ *
1477
+ * It essentially strips all tags, and replaces block-type tags' endings with spaces.
1478
+ * When done, it performs a sanity-cleanup via `strip_tags()`.
1479
+ *
1480
+ * Tip: You might want to use method `s_dupe_space()` to clear up the duplicated spaces afterward.
1481
+ *
1482
+ * @since 3.2.4
1483
+ * @link: https://www.w3schools.com/html/html_blocks.asp
1484
+ *
1485
+ * @param string $input The input text that needs its tags stripped.
1486
+ * @param array $args The input arguments: {
1487
+ * 'space' : @param array|null HTML elements that should have a space added.
1488
+ * If not set or null, skip check.
1489
+ * If empty array, use default; otherwise, use array.
1490
+ * 'clear' : @param array|null HTML elements that should be emptied and replaced with a space.
1491
+ * If not set or null, skip check.
1492
+ * If empty array, use default; otherwise, use array.
1493
+ * }
1494
+ * NOTE: WARNING The array values are forwarded to a regex without sanitization.
1495
+ * NOTE: Unlisted, script, and style tags will be stripped via PHP's `strip_tags()`.
1496
+ * @return string The output string without tags.
1497
+ */
1498
+ public function strip_tags_cs( $input, $args = [] ) {
1499
+
1500
+ $default_args = [
1501
+ 'space' =>
1502
+ [ 'address', 'article', 'aside', 'blockquote', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'li', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'tfoot', 'ul' ],
1503
+ 'clear' =>
1504
+ [ 'bdo', 'br', 'button', 'canvas', 'code', 'hr', 'input', 'label', 'link', 'noscript', 'meta', 'option', 'samp', 'script', 'select', 'style', 'svg', 'textarea', 'var', 'video' ],
1505
+ ];
1506
+
1507
+ if ( ! $args ) {
1508
+ $args = $default_args;
1509
+ } else {
1510
+ foreach ( [ 'space', 'clear' ] as $type ) {
1511
+ if ( isset( $args[ $type ] ) ) {
1512
+ if ( ! $args[ $type ] ) {
1513
+ $args[ $type ] = $default_args[ $type ];
1514
+ } else {
1515
+ $args[ $type ] = (array) $args[ $type ];
1516
+ }
1517
+ }
1518
+ }
1519
+ }
1520
+
1521
+ // Clear first, so there's less to process; then add spaces.
1522
+ foreach ( [ 'clear', 'space' ] as $type ) {
1523
+ if ( empty( $args[ $type ] ) ) continue;
1524
+
1525
+ $_regex = sprintf( '<(%s)[^>]*?>((.*?)(<\/\1>))?', implode( $args[ $type ], '|' ) );
1526
+ $_replace = 'space' === $type ? ' $2 ' : ' ';
1527
+
1528
+ $input = preg_replace( "/$_regex/si", $_replace, $input );
1529
+ }
1530
+
1531
+ return strip_tags( $input );
1532
+ }
1533
}
inc/classes/site-options.class.php CHANGED
@@ -158,15 +158,15 @@ class Site_Options extends Sanitize {
158
'home_paged_noindex' => 0, // Every second or later homepage noindex
159
160
// Robots home.
161
- 'homepage_noindex' => 0, // Home Page robots noindex
162
- 'homepage_nofollow' => 0, // Home Page robots noarchive
163
- 'homepage_noarchive' => 0, // Home Page robots nofollow
164
165
// Home meta.
166
- 'homepage_title' => '', // Home Page Title string
167
- 'homepage_tagline' => 1, // Home Page add blog Tagline
168
- 'homepage_description' => '', // Home Page Description string
169
- 'homepage_title_tagline' => '', // Home Page Tagline string
170
'home_title_location' => $h_titleloc, // Title separation location
171
172
// Homepage Social
@@ -294,8 +294,8 @@ class Site_Options extends Sanitize {
294
'title_rem_additions' => 1, // Title remove additions.
295
'site_noindex' => 1, // Site Page robots noindex
296
'site_nofollow' => 1, // Site Page robots nofollow
297
- 'homepage_noindex' => 1, // Home Page robots noindex
298
- 'homepage_nofollow' => 1, // Home Page robots noarchive
299
]
300
);
301
}
158
'home_paged_noindex' => 0, // Every second or later homepage noindex
159
160
// Robots home.
161
+ 'homepage_noindex' => 0, // Homepage robots noindex
162
+ 'homepage_nofollow' => 0, // Homepage robots noarchive
163
+ 'homepage_noarchive' => 0, // Homepage robots nofollow
164
165
// Home meta.
166
+ 'homepage_title' => '', // Homepage Title string
167
+ 'homepage_tagline' => 1, // Homepage add blog Tagline
168
+ 'homepage_description' => '', // Homepage Description string
169
+ 'homepage_title_tagline' => '', // Homepage Tagline string
170
'home_title_location' => $h_titleloc, // Title separation location
171
172
// Homepage Social
294
'title_rem_additions' => 1, // Title remove additions.
295
'site_noindex' => 1, // Site Page robots noindex
296
'site_nofollow' => 1, // Site Page robots nofollow
297
+ 'homepage_noindex' => 1, // Homepage robots noindex
298
+ 'homepage_nofollow' => 1, // Homepage robots noarchive
299
]
300
);
301
}
inc/compat/plugin-polylang.php CHANGED
@@ -34,3 +34,46 @@ function pll__( $string ) {
34
}
35
return $string;
36
}
34
}
35
return $string;
36
}
37
+
38
+ \add_filter( 'pll_home_url_white_list', __NAMESPACE__ . '\\_whitelist_tsf_urls' );
39
+ \add_filter( 'pll_home_url_black_list', __NAMESPACE__ . '\\_blaclist_tsf_sitemap_styles' );
40
+ /**
41
+ * Accompany the most broken and asinine idea in WordPress' history.
42
+ * Adds The SEO Framework's files to their whitelist of autoincompatible doom.
43
+ *
44
+ * @since 3.2.4
45
+ *
46
+ * @param array $whitelist
47
+ * @return array
48
+ */
49
+ function _whitelist_tsf_urls( $whitelist ) {
50
+ $whitelist[] = [ 'file' => 'autodescription/inc' ];
51
+ return $whitelist;
52
+ }
53
+
54
+ /**
55
+ * Accompany the most broken and asinine idea in WordPress' history.
56
+ * ...and stop messing with the rewrite system while doing so.
57
+ * Also, you should add support for class methods. Stop living in the PHP 4 era.
58
+ *
59
+ * @since 3.2.4
60
+ *
61
+ * @param array $blacklist
62
+ * @return array
63
+ */
64