The SEO Framework - Version 3.0.2

Version Description

  • Esteem =

Release date:

  • November 23rd, 2017

Fixed:

  • A fatal error no longer occurs on the wpForo Forum plugin pages.
Download this release

Release Info

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

Code changes from version 2.9.4 to 3.0.2

Files changed (80) hide show
  1. autodescription.php +8 -8
  2. inc/classes/admin-init.class.php +174 -74
  3. inc/classes/admin-pages.class.php +166 -103
  4. inc/classes/cache.class.php +104 -18
  5. inc/classes/compat.class.php +15 -22
  6. inc/classes/core.class.php +54 -17
  7. inc/classes/debug.class.php +22 -29
  8. inc/classes/deprecated.class.php +2012 -1290
  9. inc/classes/detect.class.php +8 -3
  10. inc/classes/doing-it-right.class.php +73 -61
  11. inc/classes/feed.class.php +184 -187
  12. inc/classes/generate-description.class.php +23 -13
  13. inc/classes/generate-image.class.php +17 -1
  14. inc/classes/generate-ldjson.class.php +214 -226
  15. inc/classes/generate-title.class.php +18 -12
  16. inc/classes/generate-url.class.php +467 -548
  17. inc/classes/generate.class.php +38 -35
  18. inc/classes/index.php +48 -0
  19. inc/classes/init.class.php +70 -66
  20. inc/classes/inpost.class.php +51 -108
  21. inc/classes/load.class.php +10 -18
  22. inc/classes/metaboxes.class.php +12 -0
  23. inc/classes/post-data.class.php +217 -25
  24. inc/classes/profile.class.php +138 -0
  25. inc/classes/query.class.php +49 -16
  26. inc/classes/render.class.php +151 -128
  27. inc/classes/sanitize.class.php +76 -34
  28. inc/classes/site-options.class.php +16 -129
  29. inc/classes/sitemaps.class.php +54 -50
  30. inc/classes/term-data.class.php +92 -33
  31. inc/classes/user-data.class.php +235 -0
  32. inc/compat/php-mbstring.php +11 -11
  33. inc/compat/plugin-bbpress.php +3 -12
  34. inc/compat/plugin-buddypress.php +22 -0
  35. inc/compat/plugin-donncha-dm.php +0 -69
  36. inc/compat/plugin-polylang.php +0 -187
  37. inc/compat/plugin-qtranslatex.php +0 -100
  38. inc/compat/plugin-wpforo.php +3 -23
  39. inc/compat/plugin-wpml.php +1 -183
  40. inc/compat/plugin-wpmudev-dm.php +0 -134
  41. inc/compat/theme-genesis.php +10 -25
  42. inc/compat/wp-460.php +58 -0
  43. inc/functions/optionsapi.php +1 -2
  44. inc/functions/plugin-activation.php +73 -0
  45. inc/functions/plugin-deactivation.php +71 -0
  46. inc/functions/plugin-test-server.php +1 -1
  47. inc/functions/upgrade.php +72 -8
  48. inc/views/admin/index.php +6 -0
  49. inc/views/admin/seo-settings-columns.php +35 -0
  50. inc/views/admin/seo-settings-wrap.php +48 -0
  51. inc/views/inpost/seo-settings-singular.php +34 -47
  52. inc/views/inpost/seo-settings-tt.php +69 -23
  53. inc/views/inpost/wrap.php +100 -0
  54. inc/views/metaboxes/description-metabox.php +15 -7
  55. inc/views/metaboxes/feed-metabox.php +2 -2
  56. inc/views/metaboxes/general-metabox.php +119 -14
  57. inc/views/metaboxes/homepage-metabox.php +40 -31
  58. inc/views/metaboxes/robots-metabox.php +56 -54
  59. inc/views/metaboxes/schema-metabox.php +90 -94
  60. inc/views/metaboxes/sitemaps-metabox.php +27 -67
  61. inc/views/metaboxes/social-metabox.php +66 -67
  62. inc/views/metaboxes/title-metabox.php +10 -8
  63. inc/views/metaboxes/webmaster-metabox.php +29 -9
  64. inc/views/profile/author.php +26 -0
  65. inc/views/profile/index.php +6 -0
  66. inc/views/templates/index.php +6 -0
  67. inc/views/templates/inpost/index.php +6 -0
  68. inc/views/templates/inpost/primary-term-selector.php +29 -0
  69. language/autodescription.pot +675 -607
  70. lib/css/tsf-rtl.css +360 -106
  71. lib/css/tsf-rtl.min.css +1 -1
  72. lib/css/tsf.css +358 -109
  73. lib/css/tsf.min.css +1 -1
  74. lib/js/{tsf.externs.js → externs/tsf.externs.js} +0 -0
  75. lib/js/{tsf.externs.protected.js → externs/tsf.externs.protected.js} +1 -1
  76. lib/js/tsf.js +2145 -1272
  77. lib/js/tsf.min.js +1 -38
  78. load.php +4 -96
  79. patch/index.php +0 -10
  80. readme.txt +101 -146
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: 2.9.4
7
* Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
@@ -33,7 +33,7 @@ defined( 'ABSPATH' ) or die;
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', '0' );
@@ -51,7 +51,7 @@ defined( 'ABSPATH' ) or die;
51
*
52
* @since 1.0.0
53
*/
54
- define( 'THE_SEO_FRAMEWORK_VERSION', '2.9.4' );
55
56
/**
57
* The plugin Database version.
@@ -60,7 +60,7 @@ define( 'THE_SEO_FRAMEWORK_VERSION', '2.9.4' );
60
*
61
* @since 2.7.0
62
*/
63
- define( 'THE_SEO_FRAMEWORK_DB_VERSION', '2941' );
64
65
/**
66
* The plugin options database option_name.
@@ -182,7 +182,7 @@ function the_seo_framework_pre_load() {
182
function the_seo_framework_test_server() {
183
184
//* Load on init action (manual FTP upload) or after plugin has been upgraded.
185
- require_once( THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'plugin-test-server.php' );
186
187
if ( get_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
188
the_seo_framework_load_base_files();
@@ -200,7 +200,7 @@ function the_seo_framework_load_base_files() {
200
* @since 1.0.0
201
* @uses THE_SEO_FRAMEWORK_DIR_PATH
202
*/
203
- require_once( THE_SEO_FRAMEWORK_DIR_PATH . 'load.php' );
204
205
/**
206
* Load deprecated functions.
@@ -209,12 +209,12 @@ function the_seo_framework_load_base_files() {
209
* @since 2.9.2 No longer called to improve performance.
210
* @uses THE_SEO_FRAMEWORK_DIR_PATH_FUNCT
211
*/
212
- // require_once( THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'deprecated.php' );
213
214
/**
215
* Load API files.
216
* @since 2.1.6
217
* @uses THE_SEO_FRAMEWORK_DIR_PATH_FUNCT
218
*/
219
- require_once( THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'optionsapi.php' );
220
}
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.2
7
* Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
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', '0' );
51
*
52
* @since 1.0.0
53
*/
54
+ define( 'THE_SEO_FRAMEWORK_VERSION', '3.0.2' );
55
56
/**
57
* The plugin Database version.
60
*
61
* @since 2.7.0
62
*/
63
+ define( 'THE_SEO_FRAMEWORK_DB_VERSION', '3001' );
64
65
/**
66
* The plugin options database option_name.
182
function the_seo_framework_test_server() {
183
184
//* Load on init action (manual FTP upload) or after plugin has been upgraded.
185
+ require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'plugin-test-server.php';
186
187
if ( get_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
188
the_seo_framework_load_base_files();
200
* @since 1.0.0
201
* @uses THE_SEO_FRAMEWORK_DIR_PATH
202
*/
203
+ require THE_SEO_FRAMEWORK_DIR_PATH . 'load.php';
204
205
/**
206
* Load deprecated functions.
209
* @since 2.9.2 No longer called to improve performance.
210
* @uses THE_SEO_FRAMEWORK_DIR_PATH_FUNCT
211
*/
212
+ // require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'deprecated.php';
213
214
/**
215
* Load API files.
216
* @since 2.1.6
217
* @uses THE_SEO_FRAMEWORK_DIR_PATH_FUNCT
218
*/
219
+ require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'optionsapi.php';
220
}
inc/classes/admin-init.class.php CHANGED
@@ -153,7 +153,6 @@ class Admin_Init extends Init {
153
* @since 2.5.2.2
154
*/
155
\add_action( 'admin_footer', array( $this, '_localize_admin_javascript' ) );
156
-
157
}
158
159
/**
@@ -177,7 +176,6 @@ class Admin_Init extends Init {
177
\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 );
178
179
$registered = true;
180
-
181
}
182
183
/**
@@ -199,12 +197,13 @@ class Admin_Init extends Init {
199
\wp_localize_script( $this->js_name, "{$this->js_name}L10n", $strings );
200
201
$localized = true;
202
-
203
}
204
205
/**
206
* Generate Javascript Localization.
207
*
208
* @since 2.6.0
209
* @staticvar array $strings : The l10n strings.
210
* @since 2.7.0 Added AJAX nonce: 'autodescription-ajax-nonce'
@@ -218,137 +217,178 @@ class Admin_Init extends Init {
218
*/
219
protected function get_javascript_l10n() {
220
221
$blog_name = $this->get_blogname();
222
$description = $this->get_blogdescription();
223
- $title = '';
224
$additions = '';
225
226
- $tagline = (bool) $this->get_option( 'homepage_tagline' );
227
$home_tagline = $this->get_option( 'homepage_title_tagline' );
228
$title_location = $this->get_option( 'title_location' );
229
$title_add_additions = $this->add_title_additions();
230
$counter_type = (int) $this->get_user_option( 0, 'counter_type', 3 );
231
232
- //* Enunciate the lenghts of Titles and Descriptions.
233
- $good = \__( 'Good', 'autodescription' );
234
- $okay = \__( 'Okay', 'autodescription' );
235
- $bad = \__( 'Bad', 'autodescription' );
236
- $unknown = \__( 'Unknown', 'autodescription' );
237
-
238
$title_separator = $this->get_separator( 'title' );
239
$description_separator = $this->get_separator( 'description' );
240
241
$ishome = false;
242
243
if ( isset( $this->page_base_file ) && $this->page_base_file ) {
244
// We're somewhere within default WordPress pages.
245
- $post_id = $this->get_the_real_ID();
246
-
247
- if ( $this->is_static_frontpage( $post_id ) ) {
248
- $title = $blog_name;
249
$title_location = $this->get_option( 'home_title_location' );
250
$ishome = true;
251
252
- if ( $tagline ) {
253
$additions = $home_tagline ? $home_tagline : $description;
254
} else {
255
$additions = '';
256
}
257
- } elseif ( $post_id ) {
258
//* We're on post.php
259
$generated_doctitle_args = array(
260
- 'term_id' => $post_id,
261
'notagline' => true,
262
'get_custom_field' => false,
263
);
264
265
- $title = $this->title( '', '', '', $generated_doctitle_args );
266
267
if ( $title_add_additions ) {
268
$additions = $blog_name;
269
- $tagline = true;
270
} else {
271
$additions = '';
272
- $tagline = false;
273
}
274
- } elseif ( $this->is_archive() ) {
275
//* Category or Tag.
276
- if ( isset( $GLOBALS['current_screen']->taxonomy ) ) {
277
-
278
- $term_id = $this->get_admin_term_id();
279
-
280
- if ( $term_id ) {
281
- $generated_doctitle_args = array(
282
- 'term_id' => $term_id,
283
- 'taxonomy' => $GLOBALS['current_screen']->taxonomy,
284
- 'notagline' => true,
285
- 'get_custom_field' => false,
286
- );
287
-
288
- $title = $this->title( '', '', '', $generated_doctitle_args );
289
- $additions = $title_add_additions ? $blog_name : '';
290
- }
291
}
292
} else {
293
//* We're in a special place.
294
// Can't fetch title.
295
- $title = '';
296
$additions = $title_add_additions ? $blog_name : '';
297
}
298
- } else {
299
// We're on our SEO settings pages.
300
if ( $this->has_page_on_front() ) {
301
// Home is a page.
302
- $inpost_title = $this->get_custom_field( '_genesis_title', \get_option( 'page_on_front' ) );
303
} else {
304
// Home is a blog.
305
$inpost_title = '';
306
}
307
- $title = $inpost_title ?: $blog_name;
308
$additions = $home_tagline ?: $description;
309
}
310
311
- //* @TODO deprecate
312
- $nonce = \wp_create_nonce( 'autodescription-ajax-nonce' );
313
-
314
$this->set_js_nonces( array(
315
/**
316
- * Use $this->settings_capability() ?... might conflict with other nonces.
317
*/
318
// 'manage_options' => \current_user_can( 'manage_options' ) ? \wp_create_nonce( 'tsf-ajax-manage_options' ) : false,
319
'upload_files' => \current_user_can( 'upload_files' ) ? \wp_create_nonce( 'tsf-ajax-upload_files' ) : false,
320
'edit_posts' => \current_user_can( 'edit_posts' ) ? \wp_create_nonce( 'tsf-ajax-edit_posts' ) : false,
321
) );
322
323
- return array(
324
- 'nonce' => $nonce,
325
'nonces' => $this->get_js_nonces(),
326
- 'i18n' => array(
327
- 'saveAlert' => \esc_html__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
328
- 'confirmReset' => \esc_html__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
329
- 'good' => \esc_html( $good ),
330
- 'okay' => \esc_html( $okay ),
331
- 'bad' => \esc_html( $bad ),
332
- 'unknown' => \esc_html( $unknown ),
333
- ),
334
'states' => array(
335
'isRTL' => (bool) \is_rtl(),
336
'isHome' => $ishome,
337
- 'hasInput' => $this->is_term_edit() || $this->is_post_edit() || $this->is_seo_settings_page(),
338
'counterType' => \absint( $counter_type ),
339
- 'titleTagline' => $tagline,
340
- 'isSettingsPage' => $this->is_seo_settings_page(),
341
),
342
'params' => array(
343
- 'siteTitle' => \esc_html( \wp_kses_decode_entities( $title ) ),
344
- 'titleAdditions' => \esc_html( \wp_kses_decode_entities( $additions ) ),
345
- 'blogDescription' => \esc_html( \wp_kses_decode_entities( $description ) ),
346
- 'titleSeparator' => \esc_html( $title_separator ),
347
- 'descriptionSeparator' => \esc_html( $description_separator ),
348
- 'titleLocation' => \esc_html( $title_location ),
349
),
350
'other' => $this->additional_js_l10n( null, array(), true ),
351
);
352
}
353
354
/**
@@ -448,13 +488,14 @@ class Admin_Init extends Init {
448
* valid and generated between 12-24 hours ago.
449
*/
450
public function check_tsf_ajax_referer( $capability ) {
451
- return \check_ajax_referer( 'tsf-ajax-' . $capability, 'nonce' );
452
}
453
454
/**
455
* CSS for the AutoDescription Bar
456
*
457
* @since 2.1.9
458
*
459
* @param $hook the current page
460
*/
@@ -475,6 +516,8 @@ class Admin_Init extends Init {
475
476
\wp_enqueue_style( $this->css_name );
477
478
}
479
480
/**
@@ -496,7 +539,65 @@ class Admin_Init extends Init {
496
$registered = true;
497
498
\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' );
499
500
}
501
502
/**
@@ -505,7 +606,7 @@ class Admin_Init extends Init {
505
* @since 2.8.0
506
*
507
* @param array $removable_query_args
508
- * @return array $removable_query_args The adjusted removable query args.
509
*/
510
public function add_removable_query_args( $removable_query_args = array() ) {
511
@@ -569,7 +670,7 @@ class Admin_Init extends Init {
569
* Provides an accessible error for when redirecting fails.
570
*
571
* @since 2.9.2
572
- * @link https://developer.wordpress.org/reference/functions/wp_redirect/
573
*
574
* @param string $target The redirect target location. Should be escaped.
575
* @return void
@@ -607,6 +708,7 @@ class Admin_Init extends Init {
607
* @since 2.6.0
608
* @since 2.9.0 : 1. Changed capability from 'publish_posts' to 'edit_posts'.
609
* 2. Added json header.
610
* @access private
611
*/
612
public function wp_ajax_update_counter_type() {
@@ -614,11 +716,12 @@ class Admin_Init extends Init {
614
if ( $this->is_admin() && $this->doing_ajax() ) :
615
616
$this->check_tsf_ajax_referer( 'edit_posts' );
617
//* If current user isn't allowed to edit posts, don't do anything and kill PHP.
618
if ( ! \current_user_can( 'edit_posts' ) ) {
619
- //* Remove output buffer.
620
- $this->clean_response_header();
621
-
622
//* Encode and echo results. Requires JSON decode within JS.
623
echo json_encode( array( 'type' => 'failure', 'value' => '' ) );
624
exit;
@@ -642,9 +745,6 @@ class Admin_Init extends Init {
642
'value' => $value,
643
);
644
645
- //* Remove output buffer.
646
- $this->clean_response_header();
647
-
648
//* Encode and echo results. Requires JSON decode within JS.
649
echo json_encode( $results );
650
@@ -663,6 +763,7 @@ class Admin_Init extends Init {
663
* 4. It no longer accepts a default context.
664
*
665
* @since 2.9.0
666
* @access private
667
*/
668
public function wp_ajax_crop_image() {
@@ -720,7 +821,6 @@ class Admin_Init extends Init {
720
* Filters the cropped image attachment metadata.
721
*
722
* @since 4.3.0 WordPress Core
723
- *
724
* @see wp_generate_attachment_metadata()
725
*
726
* @param array $metadata Attachment metadata.
153
* @since 2.5.2.2
154
*/
155
\add_action( 'admin_footer', array( $this, '_localize_admin_javascript' ) );
156
}
157
158
/**
176
\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 );
177
178
$registered = true;
179
}
180
181
/**
197
\wp_localize_script( $this->js_name, "{$this->js_name}L10n", $strings );
198
199
$localized = true;
200
}
201
202
/**
203
* Generate Javascript Localization.
204
*
205
+ * @TODO rewrite, it's slow and a mess.
206
+ *
207
* @since 2.6.0
208
* @staticvar array $strings : The l10n strings.
209
* @since 2.7.0 Added AJAX nonce: 'autodescription-ajax-nonce'
217
*/
218
protected function get_javascript_l10n() {
219
220
+ $id = $this->get_the_real_ID();
221
$blog_name = $this->get_blogname();
222
$description = $this->get_blogdescription();
223
+ $object_title = '';
224
$additions = '';
225
226
+ $use_additions = (bool) $this->get_option( 'homepage_tagline' );
227
$home_tagline = $this->get_option( 'homepage_title_tagline' );
228
$title_location = $this->get_option( 'title_location' );
229
$title_add_additions = $this->add_title_additions();
230
$counter_type = (int) $this->get_user_option( 0, 'counter_type', 3 );
231
232
$title_separator = $this->get_separator( 'title' );
233
$description_separator = $this->get_separator( 'description' );
234
235
$ishome = false;
236
+ $is_settings_page = $this->is_seo_settings_page();
237
+ $is_post_edit = $this->is_post_edit();
238
+ $is_term_edit = $this->is_term_edit();
239
+ $has_input = $is_settings_page || $is_post_edit || $is_term_edit;
240
+
241
+ $post_type = $is_post_edit ? \get_post_type( $id ) : false;
242
+ $_taxonomies = $post_type ? $this->get_hierarchical_taxonomies_as( 'objects', $post_type ) : array();
243
+
244
+ $taxonomies = array();
245
+
246
+ foreach ( $_taxonomies as $_t ) {
247
+ $_i18n_name = strtolower( $_t->labels->singular_name );
248
+ $taxonomies[ $_t->name ] = array(
249
+ 'name' => $_t->name,
250
+ 'i18n' => array(
251
+ /* translators: %s = term name */
252
+ 'makePrimary' => sprintf( \esc_html__( 'Make primary %s', 'autodescription' ), $_i18n_name ),
253
+ /* translators: %s = term name */
254
+ 'primary' => sprintf( \esc_html__( 'Primary %s', 'autodescription' ), $_i18n_name ),
255
+ ),
256
+ 'primary' => $this->get_primary_term_id( $id, $_t->name ) ?: 0,
257
+ );
258
+ }
259
260
if ( isset( $this->page_base_file ) && $this->page_base_file ) {
261
// We're somewhere within default WordPress pages.
262
+ if ( $this->is_static_frontpage( $id ) ) {
263
+ $object_title = $this->get_option( 'homepage_title' ) ?: $blog_name;
264
$title_location = $this->get_option( 'home_title_location' );
265
$ishome = true;
266
267
+ if ( $use_additions ) {
268
$additions = $home_tagline ? $home_tagline : $description;
269
} else {
270
$additions = '';
271
}
272
+ } elseif ( $is_post_edit ) {
273
//* We're on post.php
274
$generated_doctitle_args = array(
275
+ 'term_id' => $id,
276
'notagline' => true,
277
'get_custom_field' => false,
278
);
279
280
+ $object_title = $this->title( '', '', '', $generated_doctitle_args );
281
282
if ( $title_add_additions ) {
283
$additions = $blog_name;
284
+ $use_additions = true;
285
} else {
286
$additions = '';
287
+ $use_additions = false;
288
}
289
+ } elseif ( $is_term_edit ) {
290
//* Category or Tag.
291
+ if ( isset( $GLOBALS['current_screen']->taxonomy ) && $id ) {
292
+ $object_title = $this->single_term_title( '', false, $this->fetch_the_term( $id ) );
293
+ $additions = $title_add_additions ? $blog_name : '';
294
}
295
} else {
296
//* We're in a special place.
297
// Can't fetch title.
298
+ $object_title = '';
299
$additions = $title_add_additions ? $blog_name : '';
300
}
301
+ } elseif ( $is_settings_page ) {
302
// We're on our SEO settings pages.
303
if ( $this->has_page_on_front() ) {
304
// Home is a page.
305
+ $id = \get_option( 'page_on_front' );
306
+ $inpost_title = $this->get_custom_field( '_genesis_title', $id );
307
} else {
308
// Home is a blog.
309
$inpost_title = '';
310
}
311
+ $object_title = $inpost_title ?: $blog_name;
312
$additions = $home_tagline ?: $description;
313
}
314
315
$this->set_js_nonces( array(
316
/**
317
+ * Use $this->get_settings_capability() ?... might conflict with other nonces.
318
*/
319
// 'manage_options' => \current_user_can( 'manage_options' ) ? \wp_create_nonce( 'tsf-ajax-manage_options' ) : false,
320
'upload_files' => \current_user_can( 'upload_files' ) ? \wp_create_nonce( 'tsf-ajax-upload_files' ) : false,
321
'edit_posts' => \current_user_can( 'edit_posts' ) ? \wp_create_nonce( 'tsf-ajax-edit_posts' ) : false,
322
) );
323
324
+ $term_name = '';
325
+ $use_term_prefix = false;
326
+ if ( $is_term_edit ) {
327
+ $_term = $this->fetch_the_term( $id );
328
+ $term_name = $this->get_the_term_name( $_term, true, false );
329
+ $use_term_prefix = $this->use_archive_prefix( $_term );
330
+ }
331
+
332
+ $l10n = array(
333
'nonces' => $this->get_js_nonces(),
334
'states' => array(
335
'isRTL' => (bool) \is_rtl(),
336
'isHome' => $ishome,
337
+ 'hasInput' => $has_input,
338
'counterType' => \absint( $counter_type ),
339
+ 'useTagline' => $use_additions,
340
+ 'useTermPrefix' => $use_term_prefix,
341
+ 'isSettingsPage' => $is_settings_page,
342
+ 'isPostEdit' => $is_post_edit,
343
+ 'isTermEdit' => $is_term_edit,
344
+ 'postType' => $post_type,
345
+ 'taxonomies' => $taxonomies,
346
+ 'isPrivate' => $has_input && $id && $this->is_private( $id ),
347
+ 'isPasswordProtected' => $has_input && $id && $this->is_password_protected( $id ),
348
+ 'debug' => $this->script_debug,
349
+ ),
350
+ 'i18n' => array(
351
+ 'saveAlert' => \__( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
352
+ 'confirmReset' => \__( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
353
+ 'good' => \__( 'Good', 'autodescription' ),
354
+ 'okay' => \__( 'Okay', 'autodescription' ),
355
+ 'bad' => \__( 'Bad', 'autodescription' ),
356
+ 'unknown' => \__( 'Unknown', 'autodescription' ),
357
+ 'privateTitle' => $has_input && $id ? \__( 'Private:', 'autodescription' ) : '',
358
+ 'protectedTitle' => $has_input && $id ? \__( 'Protected:', 'autodescription' ) : '',
359
+ /* translators: Pixel counter. 1: width, 2: guideline */
360
+ 'pixelsUsed' => $has_input ? \__( '%1$d out of %2$d pixels are used.', 'autodescription' ) : '',
361
),
362
'params' => array(
363
+ 'objectTitle' => $object_title,
364
+ 'titleAdditions' => $additions,
365
+ 'blogDescription' => $description,
366
+ 'termName' => $term_name,
367
+ 'untitledTitle' => $this->untitled(),
368
+ 'titleSeparator' => $title_separator,
369
+ 'descriptionSeparator' => $description_separator,
370
+ 'titleLocation' => $title_location,
371
+ 'titlePixelGuideline' => 600,
372
+ 'descPixelGuideline' => $is_post_edit ? ( $this->is_page() ? 920 : 820 ) : 920,
373
),
374
'other' => $this->additional_js_l10n( null, array(), true ),
375
);
376
+
377
+ $decode = array( 'i18n', 'params' );
378
+ $flags = ENT_COMPAT;
379
+ foreach ( $decode as $key ) {
380
+ foreach ( $l10n[ $key ] as $k => $v ) {
381
+ $l10n[ $key ][ $k ] = \esc_js( \html_entity_decode( $v, $flags, 'UTF-8' ) );
382
+ }
383
+ }
384
+
385
+ /**
386
+ * Applies filters 'the_seo_framework_js_l10n'
387
+ *
388
+ * @since 3.0.0
389
+ * @param array $l10n
390
+ */
391
+ return (array) \apply_filters( 'the_seo_framework_js_l10n', $l10n );
392
}
393
394
/**
488
* valid and generated between 12-24 hours ago.
489
*/
490
public function check_tsf_ajax_referer( $capability ) {
491
+ return \check_ajax_referer( 'tsf-ajax-' . $capability, 'nonce', true );
492
}
493
494
/**
495
* CSS for the AutoDescription Bar
496
*
497
* @since 2.1.9
498
+ * @since 3.0.0 Now also outputs colors.
499
*
500
* @param $hook the current page
501
*/
516
517
\wp_enqueue_style( $this->css_name );
518
519
+ $color_css = $this->get_admin_color_css()
520
+ and \wp_add_inline_style( $this->css_name, $color_css );
521
}
522
523
/**
539
$registered = true;
540
541
\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' );
542
+ }
543
544
+ /**
545
+ * Outputs additional CSS based on admin theme colors.
546
+ *
547
+ * @since 3.0.0
548
+ *
549
+ * @return string Additional admin CSS.
550
+ */
551
+ protected function get_admin_color_css() {
552
+
553
+ //* @see wp_style_loader_src()
554
+ $scheme = \get_user_option( 'admin_color' ) ?: 'fresh';
555
+
556
+ $_colors = $GLOBALS['_wp_admin_css_colors'];
557
+
558
+ if ( ! isset( $_colors[ $scheme ]->colors ) || ! is_array( $_colors[ $scheme ]->colors ) )
559
+ return '';
560
+
561
+ $_scheme = $_colors[ $scheme ]->colors;
562
+
563
+ $bg = $_scheme[0];
564
+ $bg_accent = $_scheme[1];
565
+ $color = $_scheme[2];
566
+ $color_accent = $_scheme[3];
567
+
568
+ $bg_alt_font = '#' . $this->get_relative_fontcolor( $bg );
569
+ // $bg_accent_alt_font = '#' . $this->get_relative_fontcolor( $bg_accent );
570
+
571
+ $css = array(
572
+ '.tsf-flex-nav-tab .tsf-flex-nav-tab-radio:checked + .tsf-flex-nav-tab-label' => array(
573
+ "box-shadow:0 -2px 0 0 $color_accent inset",
574
+ ),
575
+ '.tsf-tooltip-text-wrap' => array(
576
+ "background-color:$bg_accent",
577
+ "color:$bg_alt_font",
578
+ ),
579
+ '.tsf-tooltip-arrow:after' => array(
580
+ "border-top-color:$bg_accent",
581
+ ),
582
+ '.tsf-tooltip-down .tsf-tooltip-arrow:after' => array(
583
+ "border-bottom-color:$bg_accent",
584
+ ),
585
+ );
586
+
587
+ /**
588
+ * Applies filters 'the_seo_framework_admin_color_css'
589
+ *
590
+ * @since 3.0.0
591
+ * @param array $css The current styles.
592
+ * @param string $scheme The current admin scheme.
593
+ */
594
+ $css = (array) \apply_filters( 'the_seo_framework_admin_color_css', $css, $scheme );
595
+
596
+ $out = '';
597
+ foreach ( $css as $attr => $style )
598
+ $out .= $attr . '{' . implode( ';', $style ) . '}';
599
+
600
+ return $out;
601
}
602
603
/**
606
* @since 2.8.0
607
*
608
* @param array $removable_query_args
609
+ * @return array The adjusted removable query args.
610
*/
611
public function add_removable_query_args( $removable_query_args = array() ) {
612
670
* Provides an accessible error for when redirecting fails.
671
*
672
* @since 2.9.2
673
+ * @see https://developer.wordpress.org/reference/functions/wp_redirect/
674
*
675
* @param string $target The redirect target location. Should be escaped.
676
* @return void
708
* @since 2.6.0
709
* @since 2.9.0 : 1. Changed capability from 'publish_posts' to 'edit_posts'.
710
* 2. Added json header.
711
+ * @securitycheck 3.0.0 OK.
712
* @access private
713
*/
714
public function wp_ajax_update_counter_type() {
716
if ( $this->is_admin() && $this->doing_ajax() ) :
717
718
$this->check_tsf_ajax_referer( 'edit_posts' );
719
+
720
+ //* Remove output buffer.
721
+ $this->clean_response_header();
722
+
723
//* If current user isn't allowed to edit posts, don't do anything and kill PHP.
724
if ( ! \current_user_can( 'edit_posts' ) ) {
725
//* Encode and echo results. Requires JSON decode within JS.
726
echo json_encode( array( 'type' => 'failure', 'value' => '' ) );
727
exit;
745
'value' => $value,
746
);
747
748
//* Encode and echo results. Requires JSON decode within JS.
749
echo json_encode( $results );
750
763
* 4. It no longer accepts a default context.
764
*
765
* @since 2.9.0
766
+ * @securitycheck 3.0.0 OK.
767
* @access private
768
*/
769
public function wp_ajax_crop_image() {
821
* Filters the cropped image attachment metadata.
822
*
823
* @since 4.3.0 WordPress Core
824
* @see wp_generate_attachment_metadata()
825
*
826
* @param array $metadata Attachment metadata.
inc/classes/admin-pages.class.php CHANGED
@@ -108,9 +108,9 @@ class Admin_Pages extends Inpost {
108
$menu = array(
109
'page_title' => \esc_html__( 'SEO Settings', 'autodescription' ),
110
'menu_title' => \esc_html__( 'SEO', 'autodescription' ),
111
- 'capability' => $this->settings_capability(),
112
'menu_slug' => $this->seo_settings_page_slug,
113
- 'callback' => array( $this, 'admin' ),
114
'icon' => 'dashicons-search',
115
'position' => '90.9001',
116
);
@@ -160,50 +160,36 @@ class Admin_Pages extends Inpost {
160
$this->handle_update_post();
161
162
//* Output metaboxes.
163
- \add_action( $this->seo_settings_page_hook . '_settings_page_boxes', array( $this, 'do_metaboxes' ) );
164
- \add_action( 'load-' . $this->seo_settings_page_hook, array( $this, 'metaboxes' ) );
165
}
166
167
/**
168
- * Echo out the do_metaboxes() and wrapping markup.
169
*
170
- * @since 2.2.2
171
*/
172
- public function do_metaboxes() {
173
- ?>
174
- <div class="metabox-holder columns-2">
175
- <div class="postbox-container-1">
176
- <?php
177
- \do_action( 'the_seo_framework_before_siteadmin_metaboxes', $this->seo_settings_page_hook );
178
-
179
- \do_meta_boxes( $this->seo_settings_page_hook, 'main', null );
180
-
181
- if ( isset( $GLOBALS['wp_meta_boxes'][ $this->seo_settings_page_hook ]['main_extra'] ) )
182
- \do_meta_boxes( $this->seo_settings_page_hook, 'main_extra', null );
183
-
184
- \do_action( 'the_seo_framework_after_siteadmin_metaboxes', $this->seo_settings_page_hook );
185
- ?>
186
- </div>
187
- <div class="postbox-container-2">
188
- <?php
189
- \do_action( 'the_seo_framework_before_siteadmin_metaboxes_side', $this->seo_settings_page_hook );
190
-
191
- /**
192
- * @TODO fill this in
193
- * @priority low 2.9.0
194
- */
195
-
196
- \do_action( 'the_seo_framework_after_siteadmin_metaboxes_side', $this->seo_settings_page_hook );
197
- ?>
198
- </div>
199
- </div>
200
- <?php
201
}
202
203
/**
204
- * Register meta boxes on the Site SEO Settings page.
205
*
206
- * @since 2.2.2
207
*
208
* @see $this->general_metabox() Callback for General Settings box.
209
* @see $this->title_metabox() Callback for Title Settings box.
@@ -216,7 +202,7 @@ class Admin_Pages extends Inpost {
216
* @see $this->sitemaps_metabox() Callback for Sitemap Settings box.
217
* @see $this->feed_metabox() Callback for Feed Settings box.
218
*/
219
- public function metaboxes() {
220
221
/**
222
* Various metabox filters.
@@ -347,63 +333,13 @@ class Admin_Pages extends Inpost {
347
);
348
}
349
350
- /**
351
- * Use this as the settings admin callback to create an admin page with sortable metaboxes.
352
- * Create a 'settings_boxes' method to add metaboxes.
353
- *
354
- * @since 2.2.2
355
- * @todo deprecate (method name is arbitrary) and convert to view.
356
- */
357
- public function admin() {
358
-
359
- ?>
360
- <div class="wrap tsf-metaboxes">
361
- <form method="post" action="options.php">
362
-
363
- <?php \wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
364
- <?php \wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
365
- <?php \settings_fields( $this->settings_field ); ?>
366
-
367
- <div class="tsf-top-wrap">
368
- <h1><?php echo \esc_html( \get_admin_page_title() ); ?></h1>
369
- <p class="tsf-top-buttons">
370
- <?php
371
- \submit_button( $this->page_defaults['save_button_text'], 'primary', 'submit', false, array( 'id' => '' ) );
372
- \submit_button( $this->page_defaults['reset_button_text'], 'secondary tsf-js-confirm-reset', $this->get_field_name( 'tsf-settings-reset' ), false, array( 'id' => '' ) );
373
- ?>
374
- </p>
375
- </div>
376
-
377
- <?php \do_action( "{$this->seo_settings_page_hook}_settings_page_boxes", $this->seo_settings_page_hook ); ?>
378
-
379
- <div class="tsf-bottom-buttons">
380
- <?php
381
- \submit_button( $this->page_defaults['save_button_text'], 'primary', 'submit', false, array( 'id' => '' ) );
382
- \submit_button( $this->page_defaults['reset_button_text'], 'secondary tsf-js-confirm-reset', $this->get_field_name( 'tsf-settings-reset' ), false, array( 'id' => '' ) );
383
- ?>
384
- </div>
385
- </form>
386
- </div>
387
- <?php // Add postbox listeners ?>
388
- <script type="text/javascript">
389
- //<![CDATA[
390
- jQuery(document).ready( function($) {
391
- // close postboxes that should be closed
392
- $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
393
- // postboxes setup
394
- postboxes.add_postbox_toggles('<?php echo \esc_js( $this->seo_settings_page_hook ); ?>');
395
- });
396
- //]]>
397
- </script>
398
- <?php
399
-
400
- }
401
-
402
/**
403
* Display notices on the save or reset of settings.
404
*
405
* @since 2.2.2
406
* @todo convert the "get" into secure "error_notice" option. See TSF Extension Manager.
407
*
408
* @return void
409
*/
@@ -519,7 +455,7 @@ class Admin_Pages extends Inpost {
519
*
520
* @param string $input The input to wrap. Should already be escaped.
521
* @param boolean $echo Whether to escape echo or just return.
522
- * @return Wrapped $input.
523
*/
524
public function wrap_fields( $input = '', $echo = false ) {
525
@@ -544,7 +480,7 @@ class Admin_Pages extends Inpost {
544
* @param string $label The checkbox description label.
545
* @param string $description Addition description to place beneath the checkbox.
546
* @param bool $escape Whether to escape the label and description.
547
- * @return HTML checkbox output.
548
*/
549
public function make_checkbox( $field_id = '', $label = '', $description = '', $escape = true ) {
550
@@ -586,7 +522,7 @@ class Admin_Pages extends Inpost {
586
* @param string $description Addition description to place beneath the checkbox.
587
* @param string $placeholder The text field placeholder.
588
* @param bool $escape Whether to escape the label and description.
589
- * @return HTML text field output.
590
*/
591
public function make_textfield( $field_id = '', $label = '', $description = '', $placeholder = '', $escape = true ) {
592
@@ -620,20 +556,30 @@ class Admin_Pages extends Inpost {
620
* Return a wrapped question mark.
621
*
622
* @since 2.6.0
623
*
624
* @param string $description The descriptive on-hover title.
625
* @param string $link The non-escaped link.
626
* @param bool $echo Whether to echo or return.
627
- * @return HTML checkbox output if $echo is false.
628
*/
629
public function make_info( $description = '', $link = '', $echo = true ) {
630
631
if ( $link ) {
632
- $output = '<a href="' . \esc_url( $link, array( 'http', 'https' ) ) . '" target="_blank" title="' . \esc_attr( $description ) . '">[?]</a>';
633
} else {
634
- $output = '<span title="' . \esc_attr( $description ) . '">[?]</span>';
635
}
636
637
if ( $echo ) {
638
//* Already escaped.
639
echo $output;
@@ -831,7 +777,6 @@ class Admin_Pages extends Inpost {
831
* Also registers additional i18n strings for JS.
832
*
833
* @since 2.8.0
834
- * @todo optimize? Sanitation and translations are duplicated -> microseconds...
835
*
836
* @param string $input_id Required. The HTML input id to pass URL into.
837
* @return string The image uploader button.
@@ -841,11 +786,20 @@ class Admin_Pages extends Inpost {
841
if ( ! $input_id )
842
return '';
843
844
- $content = sprintf( '<a href="%1$s" class="tsf-set-social-image button button-primary button-small" title="%2$s" id="%3$s-select" data-inputid="%3$s">%4$s</a>',
845
- \esc_url( \get_upload_iframe_src( 'image', $this->get_the_real_ID() ) ),
846
- \esc_attr_x( 'Select social image', 'Button hover', 'autodescription' ),
847
- \esc_attr( $input_id ),
848
- \esc_html__( 'Select Image', 'autodescription' )
849
);
850
851
$button_labels = array(
@@ -859,8 +813,117 @@ class Admin_Pages extends Inpost {
859
);
860
861
//* Already escaped. Turn off escaping.
862
- $this->additional_js_l10n( \esc_attr( $input_id ), $button_labels, false, false );
863
864
return $content;
865
}
866
}
108
$menu = array(
109
'page_title' => \esc_html__( 'SEO Settings', 'autodescription' ),
110
'menu_title' => \esc_html__( 'SEO', 'autodescription' ),
111
+ 'capability' => $this->get_settings_capability(),
112
'menu_slug' => $this->seo_settings_page_slug,
113
+ 'callback' => array( $this, '_output_seo_settings_wrap' ),
114
'icon' => 'dashicons-search',
115
'position' => '90.9001',
116
);
160
$this->handle_update_post();
161
162
//* Output metaboxes.
163
+ \add_action( $this->seo_settings_page_hook . '_settings_page_boxes', array( $this, '_output_seo_settings_columns' ) );
164
+ \add_action( 'load-' . $this->seo_settings_page_hook, array( $this, '_register_seo_settings_metaboxes' ) );
165
}
166
167
/**
168
+ * Outputs SEO Settings page wrap.
169
*
170
+ * @since 3.0.0
171
+ * @access private
172
*/
173
+ public function _output_seo_settings_wrap() {
174
+ \do_action( 'the_seo_framework_pre_seo_settings' );
175
+ $this->get_view( 'admin/seo-settings-wrap', get_defined_vars() );
176
+ \do_action( 'the_seo_framework_pro_seo_settings' );
177
}
178
179
/**
180
+ * Outputs SEO Settings columns.
181
*
182
+ * @since 3.0.0
183
+ * @access private
184
+ */
185
+ public function _output_seo_settings_columns() {
186
+ $this->get_view( 'admin/seo-settings-columns', get_defined_vars() );
187
+ }
188
+
189
+ /**
190
+ * Registers meta boxes on the Site SEO Settings page.
191
+ *
192
+ * @since 3.0.0
193
*
194
* @see $this->general_metabox() Callback for General Settings box.
195
* @see $this->title_metabox() Callback for Title Settings box.
202
* @see $this->sitemaps_metabox() Callback for Sitemap Settings box.
203
* @see $this->feed_metabox() Callback for Feed Settings box.
204
*/
205
+ public function _register_seo_settings_metaboxes() {
206
207
/**
208
* Various metabox filters.
333
);
334
}
335
336
/**
337
* Display notices on the save or reset of settings.
338
*
339
* @since 2.2.2
340
+ * @securitycheck 3.0.0 OK. NOTE: Users can however MANUALLY trigger these on the SEO settings page.
341
* @todo convert the "get" into secure "error_notice" option. See TSF Extension Manager.
342
+ * @todo convert $this->page_defaults to inline texts. It's now uselessly rendering.
343
*
344
* @return void
345
*/
455
*
456
* @param string $input The input to wrap. Should already be escaped.
457
* @param boolean $echo Whether to escape echo or just return.
458
+ * @return string|void Wrapped $input.
459
*/
460
public function wrap_fields( $input = '', $echo = false ) {
461
480
* @param string $label The checkbox description label.
481
* @param string $description Addition description to place beneath the checkbox.
482
* @param bool $escape Whether to escape the label and description.
483
+ * @return string HTML checkbox output.
484
*/
485
public function make_checkbox( $field_id = '', $label = '', $description = '', $escape = true ) {
486
522
* @param string $description Addition description to place beneath the checkbox.
523
* @param string $placeholder The text field placeholder.
524
* @param bool $escape Whether to escape the label and description.
525
+ * @return string HTML text field output.
526
*/
527
public function make_textfield( $field_id = '', $label = '', $description = '', $placeholder = '', $escape = true ) {
528
556
* Return a wrapped question mark.
557
*
558
* @since 2.6.0
559
+ * @since 3.0.0 Links are now no longer followed, referred or bound to opener.
560
*
561
* @param string $description The descriptive on-hover title.
562
* @param string $link The non-escaped link.
563
* @param bool $echo Whether to echo or return.
564
+ * @return string HTML checkbox output if $echo is false.
565
*/
566
public function make_info( $description = '', $link = '', $echo = true ) {
567
568
if ( $link ) {
569
+ $output = sprintf(
570
+ '<a href="%1$s" class="tsf-tooltip-item" target="_blank" rel="nofollow noreferrer noopener" title="%2$s" data-desc="%2$s">[?]</a>',
571
+ \esc_url( $link, array( 'http', 'https' ) ),
572
+ \esc_attr( $description )
573
+ );
574
} else {
575
+ $output = sprintf(
576
+ '<span class="tsf-tooltip-item" title="%1$s" data-desc="%1$s">[?]</span>',
577
+ \esc_attr( $description )
578
+ );
579
}
580
581
+ $output = sprintf( '<span class="tsf-tooltip-wrap">%s</span>', $output );
582
+
583
if ( $echo ) {
584
//* Already escaped.
585
echo $output;
777
* Also registers additional i18n strings for JS.
778
*
779
* @since 2.8.0
780
*
781
* @param string $input_id Required. The HTML input id to pass URL into.
782
* @return string The image uploader button.
786
if ( ! $input_id )
787
return '';
788
789
+ $s_input_id = \esc_attr( $input_id );
790
+
791
+ $content = vsprintf(
792
+ '<a href="%1$s" class="tsf-set-social-image button button-primary button-small" title="%2$s" id="%3$s-select"
793
+ data-inputid="%3$s" data-width="%4$s" data-height="%5$s" data-flex="%6$d">%7$s</a>',
794
+ array(
795
+ \esc_url( \get_upload_iframe_src( 'image', $this->get_the_real_ID() ) ),
796
+ \esc_attr_x( 'Select social image', 'Button hover', 'autodescription' ),
797
+ $s_input_id,
798
+ '1200',
799
+ '630',
800
+ true,
801
+ \esc_html__( 'Select Image', 'autodescription' ),
802
+ )
803
);
804
805
$button_labels = array(
813
);
814
815
//* Already escaped. Turn off escaping.
816
+ $this->additional_js_l10n( $s_input_id, $button_labels, false, false );
817
818
return $content;
819
}
820
+
821
+ /**
822
+ * Returns logo uploader form buttons.
823
+ * Also registers additional i18n strings for JS.
824
+ *
825
+ * @since 3.0.0
826
+ *
827
+ * @param string $input_id Required. The HTML input id to pass URL into.
828
+ * @return string The image uploader button.
829
+ */
830
+ public function get_logo_uploader_form( $input_id ) {
831
+
832
+ if ( ! $input_id )
833
+ return '';
834
+
835
+ $s_input_id = \esc_attr( $input_id );
836
+
837
+ $content = vsprintf(
838
+ '<a href="%1$s" class="tsf-set-social-image button button-primary button-small" title="%2$s" id="%3$s-select"
839
+ data-inputid="%3$s" data-width="%4$s" data-height="%5$s" data-flex="%6$d">%7$s</a>',
840
+ array(
841
+ \esc_url( \get_upload_iframe_src( 'image', $this->get_the_real_ID() ) ),
842
+ '',
843
+ $s_input_id,
844
+ '512',
845
+ '512',
846
+ false,
847
+ \esc_html__( 'Select Logo', 'autodescription' ),
848
+ )
849
+ );
850
+
851
+ $button_labels = array(
852
+ 'select' => \esc_attr__( 'Select Logo', 'autodescription' ),
853
+ 'select_title' => '',
854
+ 'change' => \esc_attr__( 'Change Logo', 'autodescription' ),
855
+ 'remove' => \esc_attr__( 'Remove Logo', 'autodescription' ),
856
+ 'remove_title' => \esc_attr__( 'Unset selected logo', 'autodescription' ),
857
+ 'frame_title' => \esc_attr_x( 'Select Logo', 'Frame title', 'autodescription' ),
858
+ 'frame_button' => \esc_attr__( 'Use this image', 'autodescription' ),
859
+ );
860
+
861
+ //* Already escaped. Turn off escaping.
862
+ $this->additional_js_l10n( $s_input_id, $button_labels, false, false );
863
+
864
+ return $content;
865
+ }
866
+
867
+ /**
868
+ * Outputs floating title HTML for JavaScript.
869
+ *
870
+ * @since 3.0.0
871
+ */
872
+ public function output_floating_title_elements() {
873
+ ?>
874
+ <span id="tsf-title-offset" class="hide-if-no-js"></span>
875
+ <span id="tsf-title-placeholder" class="hide-if-no-js"></span>
876
+ <span id="tsf-title-placeholder-prefix" class="hide-if-no-js"></span>
877
+ <?php
878
+ }
879
+
880
+ /**
881
+ * Outputs character counter wrap for both JavaScript and no-Javascript.
882
+ *
883
+ * @since 3.0.0
884
+ *
885
+ * @param string $for The input ID it's for.
886
+ * @param string $initial The initial value for no-JS.
887
+ * @param bool $display Whether to display the counter.
888
+ */
889
+ public function output_character_counter_wrap( $for, $initial = 0, $display = true ) {
890
+ printf(
891
+ '<div class="tsf-counter-wrap" %s><span class="description tsf-counter">%s</span><span class="hide-if-no-js tsf-ajax"></span></div>',
892
+ $display ? '' : 'style="display:none;"',
893
+ sprintf(
894
+ /* translators: %s = number */
895
+ \esc_html__( 'Characters Used: %s', 'autodescription' ),
896
+ sprintf(
897
+ '<span id="%s_chars">%s</span>',
898
+ \esc_attr( $for ),
899
+ (int) mb_strlen( $initial )
900
+ )
901
+ )
902
+ );
903
+ }
904
+
905
+ /**
906
+ * Outputs pixel counter wrap for javascript.
907
+ *
908
+ * @since 3.0.0
909
+ *
910
+ * @param string $for The input ID it's for.
911
+ * @param string $type Whether it's a 'title' or 'description' counter.
912
+ * @param bool $display Whether to display the counter.
913
+ */
914
+ public function output_pixel_counter_wrap( $for, $type, $display = true ) {
915
+ printf(
916
+ '<div class="tsf-pixel-counter-wrap hide-if-no-js" %s>%s%s</div>',
917
+ $display ? '' : 'style="display:none;"',
918
+ sprintf(
919
+ '<div id="%s_pixels" class="tsf-tooltip-wrap">%s</div>',
920
+ \esc_attr( $for ),
921
+ '<span class="tsf-pixel-counter-bar tsf-tooltip-item" aria-label="" data-desc=""><span class="tsf-pixel-counter-fluid"></span></span>'
922
+ ),
923
+ sprintf(
924
+ '<div class="tsf-pixel-shadow-wrap"><span class="tsf-pixel-counter-shadow tsf-%s-pixel-counter-shadow"></span></div>',
925
+ \esc_attr( $type )
926
+ )
927
+ );
928
+ }
929
}
inc/classes/cache.class.php CHANGED
@@ -64,10 +64,19 @@ class Cache extends Sitemaps {
64
*
65
* @since 2.5.2
66
*
67
- * @var string The Theme Doing It Right Transient Name.
68
*/
69
protected $theme_doing_it_right_transient;
70
71
/**
72
* Constructor, load parent constructor and set up caches.
73
*/
@@ -148,6 +157,9 @@ class Cache extends Sitemaps {
148
\add_action( 'post_updated', array( $this, 'delete_post_cache' ) );
149
\add_action( 'page_updated', array( $this, 'delete_post_cache' ) );
150
151
$run = true;
152
}
153
@@ -166,15 +178,19 @@ class Cache extends Sitemaps {
166
}
167
168
/**
169
- * Delete transient on post save.
170
*
171
* @since 2.8.0
172
*
173
* @param int $post_id The Post ID that has been updated.
174
* @return bool True on success, false on failure.
175
*/
176
public function delete_post_cache( $post_id ) {
177
178
$success = array();
179
180
$success[] = $this->delete_cache( 'post', $post_id );
@@ -188,6 +204,30 @@ class Cache extends Sitemaps {
188
return ! in_array( false, $success, true );
189
}
190
191
/**
192
* Deletes cache on profile save.
193
*
@@ -284,6 +324,10 @@ class Cache extends Sitemaps {
284
return $this->object_cache_delete( $this->get_robots_txt_cache_key() );
285
break;
286
287
case 'detection' :
288
return $this->delete_theme_dir_transient();
289
break;
@@ -380,7 +424,7 @@ class Cache extends Sitemaps {
380
* @param string $value Transient value. Expected to not be SQL-escaped.
381
* @param int $expiration Optional Transient expiration date, optional. Expected to not be SQL-escaped.
382
*/
383
- public function set_transient( $transient, $value, $expiration = '' ) {
384
385
if ( $this->the_seo_framework_use_transients )
386
\set_transient( $transient, $value, $expiration );
@@ -469,6 +513,7 @@ class Cache extends Sitemaps {
469
* @since 2.8.0:
470
* 1. Added locale suffix.
471
* 2. Added check for option 'cache_sitemap'.
472
* @global int $blog_id
473
*/
474
public function setup_transient_names() {
@@ -478,11 +523,13 @@ class Cache extends Sitemaps {
478
* When the caching mechanism changes. Change this value.
479
* Use hex. e.g. 0, 1, 2, 9, a, b
480
*/
481
- $sitemap_revision = '3';
482
- $theme_dir_revision = '0';
483
484
$this->sitemap_transient = $this->is_option_checked( 'cache_sitemap' ) ? $this->add_cache_key_suffix( 'tsf_sitemap_' . $sitemap_revision ) : '';
485
$this->theme_doing_it_right_transient = 'tsf_tdir_' . $theme_dir_revision . '_' . $blog_id;
486
}
487
488
/**
@@ -519,7 +566,7 @@ class Cache extends Sitemaps {
519
520
$cache_key = $this->generate_cache_key( $page_id, $taxonomy, $type );
521
522
- $revision = '2';
523
$additions = $this->add_description_additions( $page_id, $taxonomy );
524
525
if ( $additions ) {
@@ -563,13 +610,12 @@ class Cache extends Sitemaps {
563
564
$cache_key = $this->generate_cache_key( $page_id, $taxonomy, $type );
565
566
- $revision = '5';
567
568
/**
569
* Change key based on options.
570
*/
571
$options = $this->enable_ld_json_breadcrumbs() ? '1' : '0';
572
- $options .= $this->enable_ld_json_sitename() ? '1' : '0';
573
$options .= $this->enable_ld_json_searchbox() ? '1' : '0';
574
575
return 'tsf_' . $revision . '_' . $options . '_ldjs_' . $cache_key;
@@ -822,18 +868,18 @@ class Cache extends Sitemaps {
822
* @since 2.8.0 1: $locale is now static.
823
* 2: $key may now be empty.
824
* @staticvar string $locale
825
*
826
* @return string the cache key.
827
*/
828
protected function add_cache_key_suffix( $key = '' ) {
829
- global $blog_id;
830
831
static $locale = null;
832
833
if ( is_null( $locale ) )
834
$locale = strtolower( \get_locale() );
835
836
- return $key . '_' . $blog_id . '_' . $locale;
837
}
838
839
/**
@@ -970,6 +1016,8 @@ class Cache extends Sitemaps {
970
*
971
* @since 2.9.1
972
* @uses THE_SEO_FRAMEWORK_DB_VERSION as cache key buster.
973
*
974
* @param int $id The ID. Defaults to $this->get_the_real_ID();
975
* @param string $taxonomy The term taxonomy
@@ -983,10 +1031,10 @@ class Cache extends Sitemaps {
983
*/
984
$key = $this->generate_cache_key_by_type( $id, $taxonomy, $type ) . '_' . THE_SEO_FRAMEWORK_DB_VERSION;
985
986
- $page = '1';
987
- $paged = '1';
988
989
- return $cache_key = 'seo_framework_output_' . $key . '_' . $paged . '_' . $page;
990
}
991
992
/**
@@ -1011,13 +1059,13 @@ class Cache extends Sitemaps {
1011
*
1012
* @since 2.3.0
1013
* @since 2.7.0 : Added admin referer check.
1014
*
1015
* @return bool Whether if sitemap transient is deleted.
1016
*/
1017
public function delete_sitemap_transient_permalink_updated() {
1018
1019
if ( isset( $_POST['permalink_structure'] ) || isset( $_POST['category_base'] ) ) {
1020
-
1021
if ( \check_admin_referer( 'update-permalink' ) )
1022
return $this->delete_cache( 'sitemap' );
1023
}
@@ -1126,10 +1174,8 @@ class Cache extends Sitemaps {
1126
*/
1127
public function delete_theme_dir_transient( $value = null, $options = null ) {
1128
1129
- if ( isset( $options['type'] ) ) {
1130
- if ( 'theme' !== $options['type'] )
1131
- return false;
1132
- }
1133
1134
\delete_transient( $this->theme_doing_it_right_transient );
1135
@@ -1158,4 +1204,44 @@ class Cache extends Sitemaps {
1158
\set_transient( $this->theme_doing_it_right_transient, $dir, 0 );
1159
}
1160
}
1161
}
64
*
65
* @since 2.5.2
66
*
67
+ * @var string
68
*/
69
protected $theme_doing_it_right_transient;
70
71
+ /**
72
+ * The excluded Post IDs transient name.
73
+ *
74
+ * @since 3.0.0
75
+ *
76
+ * @var string
77
+ */
78
+ protected $excluded_post_ids_transient;
79
+
80
/**
81
* Constructor, load parent constructor and set up caches.
82
*/
157
\add_action( 'post_updated', array( $this, 'delete_post_cache' ) );
158
\add_action( 'page_updated', array( $this, 'delete_post_cache' ) );
159
160
+ //* Excluded IDs cache.
161
+ \add_action( 'save_post', array( $this, 'delete_excluded_ids_cache' ) );
162
+
163
$run = true;
164
}
165
178
}
179
180
/**
181
+ * Deletes transient on post save.
182
*
183
* @since 2.8.0
184
+ * @since 3.0.0 Process is halted when no valid $post_id is supplied.
185
*
186
* @param int $post_id The Post ID that has been updated.
187
* @return bool True on success, false on failure.
188
*/
189
public function delete_post_cache( $post_id ) {
190
191
+ if ( ! $post_id )
192
+ return false;
193
+
194
$success = array();
195
196
$success[] = $this->delete_cache( 'post', $post_id );
204
return ! in_array( false, $success, true );
205
}
206
207
+ /**
208
+ * Deletes excluded post IDs cache.
209
+ *
210
+ * @since 3.0.0
211
+ *
212
+ * @return bool True on success, false on failure.
213
+ */
214
+ public function delete_excluded_ids_cache() {
215
+ return $this->delete_cache( 'excluded_post_ids' );
216
+ }
217
+
218
+ /**
219
+ * Deletes excluded post IDs transient cache.
220
+ *
221
+ * @since 3.0.0
222
+ * @see $this->delete_excluded_ids_cache()
223
+ *
224
+ * @return bool True
225
+ */
226
+ public function delete_excluded_post_ids_transient() {
227
+ \delete_transient( $this->excluded_post_ids_transient );
228
+ return true;
229
+ }
230
+
231
/**
232
* Deletes cache on profile save.
233
*
324
return $this->object_cache_delete( $this->get_robots_txt_cache_key() );
325
break;
326
327
+ case 'excluded_post_ids' :
328
+ return $this->delete_excluded_post_ids_transient();
329
+ break;
330
+
331
case 'detection' :
332
return $this->delete_theme_dir_transient();
333
break;
424
* @param string $value Transient value. Expected to not be SQL-escaped.
425
* @param int $expiration Optional Transient expiration date, optional. Expected to not be SQL-escaped.
426
*/
427
+ public function set_transient( $transient, $value, $expiration = 0 ) {
428
429
if ( $this->the_seo_framework_use_transients )
430
\set_transient( $transient, $value, $expiration );
513
* @since 2.8.0:
514
* 1. Added locale suffix.
515
* 2. Added check for option 'cache_sitemap'.
516
+ * @since 3.0.0 Now also sets up $excluded_post_ids_transient
517
* @global int $blog_id
518
*/
519
public function setup_transient_names() {
523
* When the caching mechanism changes. Change this value.
524
* Use hex. e.g. 0, 1, 2, 9, a, b
525
*/
526
+ $sitemap_revision = '4';
527
+ $theme_dir_revision = '1';
528
+ $exclude_revision = '0';
529
530
$this->sitemap_transient = $this->is_option_checked( 'cache_sitemap' ) ? $this->add_cache_key_suffix( 'tsf_sitemap_' . $sitemap_revision ) : '';
531
$this->theme_doing_it_right_transient = 'tsf_tdir_' . $theme_dir_revision . '_' . $blog_id;
532
+ $this->excluded_post_ids_transient = 'tsf_exclude_' . $exclude_revision . '_' . $blog_id;
533
}
534
535
/**
566
567
$cache_key = $this->generate_cache_key( $page_id, $taxonomy, $type );
568
569
+ $revision = '3';
570
$additions = $this->add_description_additions( $page_id, $taxonomy );
571
572
if ( $additions ) {
610
611
$cache_key = $this->generate_cache_key( $page_id, $taxonomy, $type );
612
613
+ $revision = '6';
614
615
/**
616
* Change key based on options.
617
*/
618
$options = $this->enable_ld_json_breadcrumbs() ? '1' : '0';
619
$options .= $this->enable_ld_json_searchbox() ? '1' : '0';
620
621
return 'tsf_' . $revision . '_' . $options . '_ldjs_' . $cache_key;
868
* @since 2.8.0 1: $locale is now static.
869
* 2: $key may now be empty.
870
* @staticvar string $locale
871
+ * @global string $blog_id
872
*
873
* @return string the cache key.
874
*/
875
protected function add_cache_key_suffix( $key = '' ) {
876
877
static $locale = null;
878
879
if ( is_null( $locale ) )
880
$locale = strtolower( \get_locale() );
881
882
+ return $key . '_' . $GLOBALS['blog_id'] . '_' . $locale;
883
}
884
885
/**
1016
*
1017
* @since 2.9.1
1018
* @uses THE_SEO_FRAMEWORK_DB_VERSION as cache key buster.
1019
+ * @uses $this->generate_cache_key_by_type()
1020
+ * @see $this->get_meta_output_cache_key_by_query()
1021
*
1022
* @param int $id The ID. Defaults to $this->get_the_real_ID();
1023
* @param string $taxonomy The term taxonomy
1031
*/
1032
$key = $this->generate_cache_key_by_type( $id, $taxonomy, $type ) . '_' . THE_SEO_FRAMEWORK_DB_VERSION;
1033
1034
+ //= Refers to the first page, always.
1035
+ $_page = $_paged = '1';
1036
1037
+ return $cache_key = 'seo_framework_output_' . $key . '_' . $_paged . '_' . $_page;
1038
}
1039
1040
/**
1059
*
1060
* @since 2.3.0
1061
* @since 2.7.0 : Added admin referer check.
1062
+ * @securitycheck 3.0.0 OK.
1063
*
1064
* @return bool Whether if sitemap transient is deleted.
1065
*/
1066
public function delete_sitemap_transient_permalink_updated() {
1067
1068
if ( isset( $_POST['permalink_structure'] ) || isset( $_POST['category_base'] ) ) {
1069
if ( \check_admin_referer( 'update-permalink' ) )
1070
return $this->delete_cache( 'sitemap' );
1071
}
1174
*/
1175
public function delete_theme_dir_transient( $value = null, $options = null ) {
1176
1177
+ if ( isset( $options['type'] ) && 'theme' !== $options['type'] )
1178
+ return false;
1179
1180
\delete_transient( $this->theme_doing_it_right_transient );
1181
1204
\set_transient( $this->theme_doing_it_right_transient, $dir, 0 );
1205
}
1206
}
1207
+
1208
+ /**
1209
+ * Builds and returns the excluded post IDs transient.
1210
+ *
1211
+ * @since 3.0.0
1212
+ * @staticvar array $cache
1213
+ *
1214
+ * @return array : { 'archive', 'search' }
1215
+ */
1216
+ public function get_excluded_ids_from_cache() {
1217
+
1218
+ static $cache = null;
1219
+
1220
+ if ( null === $cache )
1221
+ $cache = $this->get_transient( $this->excluded_post_ids_transient );
1222
+
1223
+ if ( false === $cache ) {
1224
+ global $wpdb;
1225
+ $cache = array();
1226
+
1227
+ //= Two separated equals queries are faster than a single IN with 'meta_key'.
1228
+ $cache['archive'] = $wpdb->get_results(
1229
+ $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '%s'", 'exclude_from_archive' )
1230
+ );
1231
+ $cache['search'] = $wpdb->get_results(
1232
+ $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = '%s'", 'exclude_local_search' )
1233
+ );
1234
+
1235
+ foreach ( array( 'archive', 'search' ) as $key ) {
1236
+ array_walk( $cache[ $key ], function( &$v ) {
1237
+ $v = $v->meta_value ? (int) $v->post_id : false;
1238
+ } );
1239
+ $cache[ $key ] = array_filter( $cache[ $key ] );
1240
+ }
1241
+
1242
+ $this->set_transient( $this->excluded_post_ids_transient, $cache );
1243
+ }
1244
+
1245
+ return $cache;
1246
+ }
1247
}
inc/classes/compat.class.php CHANGED
@@ -43,9 +43,6 @@ class Compat extends Core {
43
44
//* Jetpack compat.
45
\add_action( 'init', array( $this, 'jetpack_compat' ) );
46
-
47
- //* BuddyPress front-end compat.
48
- \remove_action( 'wp_head', '_bp_maybe_remove_rel_canonical', 8 );
49
}
50
51
/**
@@ -63,36 +60,32 @@ class Compat extends Core {
63
$this->_include_compat( 'mbstring', 'php' );
64
}
65
66
if ( $this->is_theme( 'genesis' ) ) {
67
//* Genesis Framework
68
$this->_include_compat( 'genesis', 'theme' );
69
}
70
71
- if ( defined( 'DOMAIN_MAPPING' ) ) {
72
- if ( $this->detect_plugin( array( 'functions' => array( 'redirect_to_mapped_domain' ) ) ) ) {
73
- //* Donncha domain mapping.
74
- $this->_include_compat( 'donncha-dm', 'plugin' );
75
- } elseif ( $this->detect_plugin( array( 'functions' => array( 'domainmap_launch' ) ) ) ) {
76
- //* WPMUdev domain mapping.
77
- $this->_include_compat( 'wpmudev-dm', 'plugin' );
78
- }
79
- }
80
-
81
- if ( $this->detect_plugin( array( 'globals' => array( 'polylang' ) ) ) ) {
82
- //* PolyLang... it includes compat for WPML, but let's see how this works for now.
83
- $this->_include_compat( 'polylang', 'plugin' );
84
- } elseif ( $this->detect_plugin( array( 'constants' => array( 'ICL_LANGUAGE_CODE' ) ) ) ) {
85
//* WPML
86
$this->_include_compat( 'wpml', 'plugin' );
87
- } elseif ( $this->detect_plugin( array( 'constants' => array( 'QTX_VERSION' ) ) ) ) {
88
- //* qTranslate X
89
- $this->_include_compat( 'qtranslatex', 'plugin' );
90
}
91
92
if ( $this->detect_plugin( array( 'globals' => array( 'ultimatemember' ) ) ) ) {
93
//* Ultimate Member
94
$this->_include_compat( 'ultimatemember', 'plugin' );
95
}
96
97
if ( $this->detect_plugin( array( 'functions' => array( 'bbpress' ) ) ) ) {
98
//* bbPress
@@ -118,8 +111,8 @@ class Compat extends Core {
118
119
static $included = array();
120
121
- isset( $included[ $what ][ $type ] )
122
- or $included[ $what ][ $type ] = (bool) require_once( THE_SEO_FRAMEWORK_DIR_PATH_COMPAT . $type . '-' . $what . '.php' );
123
124
return $included[ $what ][ $type ];
125
}
43
44
//* Jetpack compat.
45
\add_action( 'init', array( $this, 'jetpack_compat' ) );
46
}
47
48
/**
60
$this->_include_compat( 'mbstring', 'php' );
61
}
62
63
+ $wp_version = $GLOBALS['wp_version'];
64
+
65
+ if ( version_compare( $wp_version, '4.6', '<' ) ) {
66
+ //* WP 4.6.0
67
+ $this->_include_compat( '460', 'wp' );
68
+ }
69
+
70
if ( $this->is_theme( 'genesis' ) ) {
71
//* Genesis Framework
72
$this->_include_compat( 'genesis', 'theme' );
73
}
74
75
+ if ( $this->detect_plugin( array( 'constants' => array( 'ICL_LANGUAGE_CODE' ) ) ) ) {
76
//* WPML
77
$this->_include_compat( 'wpml', 'plugin' );
78
}
79
80
if ( $this->detect_plugin( array( 'globals' => array( 'ultimatemember' ) ) ) ) {
81
//* Ultimate Member
82
$this->_include_compat( 'ultimatemember', 'plugin' );
83
}
84
+ if ( $this->detect_plugin( array( 'globals' => array( 'bp' ) ) ) ) {
85
+ //* BuddyPress
86
+ $this->_include_compat( 'buddypress', 'plugin' );
87
+
88
+ }
89
90
if ( $this->detect_plugin( array( 'functions' => array( 'bbpress' ) ) ) ) {
91
//* bbPress
111
112
static $included = array();
113
114
+ if ( ! isset( $included[ $what ][ $type ] ) )
115
+ $included[ $what ][ $type ] = (bool) require THE_SEO_FRAMEWORK_DIR_PATH_COMPAT . $type . '-' . $what . '.php';
116
117
return $included[ $what ][ $type ];
118
}
inc/classes/core.class.php CHANGED
@@ -54,7 +54,7 @@ class Core {
54
*/
55
final public function __set( $name, $value ) {
56
/**
57
- * For now, no deprecation is being handled; as no properties are deprecated.
58
*/
59
$this->_deprecated_function( 'the_seo_framework()->' . \esc_html( $name ), 'unknown' );
60
@@ -76,7 +76,7 @@ class Core {
76
77
switch ( $name ) :
78
case 'pagehook' :
79
- $this->_deprecated_function( 'the_seo_framework()->' . \esc_html( $name ), '2.7.0', 'the_seo_framework()->seo_settings_page_hook' );
80
return $this->seo_settings_page_hook;
81
break;
82
@@ -120,7 +120,7 @@ class Core {
120
121
if ( $this->the_seo_framework_debug ) {
122
123
- $debug_instance = \The_SEO_Framework\Debug::get_instance();
124
125
\add_action( 'the_seo_framework_do_before_output', array( $debug_instance, 'set_debug_query_output_cache' ) );
126
\add_action( 'admin_footer', array( $debug_instance, 'debug_screens' ) );
@@ -140,9 +140,8 @@ class Core {
140
protected function clean_response_header() {
141
142
if ( $level = ob_get_level() ) {
143
- while ( $level ) {
144
ob_end_clean();
145
- $level--;
146
}
147
return true;
148
}
@@ -160,7 +159,7 @@ class Core {
160
*
161
* @param string $view The file name.
162
* @param array $args The arguments to be supplied within the file name.
163
- * Each array key is converted to a variable with its value attached.
164
* @param string $instance The instance suffix to call back upon.
165
*/
166
public function get_view( $view, array $args = array(), $instance = 'main' ) {
@@ -170,7 +169,7 @@ class Core {
170
171
$file = THE_SEO_FRAMEWORK_DIR_PATH_VIEWS . $view . '.php';
172
173
- include( $file );
174
}
175
176
/**
@@ -241,6 +240,8 @@ class Core {
241
*
242
* @since 2.2.8
243
* @since 2.9.2 : Added TSFEM link.
244
*
245
* @param array $links The current links.
246
* @return array The plugin links.
@@ -250,9 +251,9 @@ class Core {
250
$tsf_links = array();
251
252
if ( $this->load_options )
253
- $tsf_links['settings'] = '<a href="' . \esc_url( \admin_url( 'admin.php?page=' . $this->seo_settings_page_slug ) ) . '">' . \esc_html__( 'SEO Settings', 'autodescription' ) . '</a>';
254
255
- $tsf_links['home'] = '<a href="' . \esc_url( 'https://theseoframework.com/' ) . '" rel="noopener" target="_blank">' . \esc_html_x( 'Plugin Home', 'As in: The Plugin Home Page', 'autodescription' ) . '</a>';
256
257
/**
258
* These are weak checks.
@@ -261,7 +262,7 @@ class Core {
261
if ( ! defined( 'TSF_EXTENSION_MANAGER_VERSION' ) ) {
262
$tsfem = \get_plugins( '/the-seo-framework-extension-manager' );
263
if ( empty( $tsfem ) )
264
- $tsf_links['tsfem'] = '<a href="' . \esc_url( \__( 'https://wordpress.org/plugins/the-seo-framework-extension-manager/', 'autodescription' ) ) . '" rel="noopener" target="_blank">' . \esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' ) . '</a>';
265
}
266
267
return array_merge( $tsf_links, $links );
@@ -572,18 +573,32 @@ class Core {
572
/**
573
* Returns the minimum role required to adjust settings.
574
*
575
- * Applies filter 'the_seo_framework_settings_capability' : string
576
- * This filter changes the minimum role for viewing and editing the plugin's settings.
577
- *
578
- * @since 2.6.0
579
- * @access private
580
*
581
* @return string The minimum required capability for SEO Settings.
582
*/
583
- public function settings_capability() {
584
return (string) \apply_filters( 'the_seo_framework_settings_capability', 'manage_options' );
585
}
586
587
/**
588
* Returns the SEO Settings page URL.
589
*
@@ -612,7 +627,7 @@ class Core {
612
*
613
* @param bool $guess : If true, the timezone will be guessed from the
614
* WordPress core gmt_offset option.
615
- * @return string|empty PHP Timezone String.
616
*/
617
public function get_timezone_string( $guess = false ) {
618
@@ -710,6 +725,28 @@ class Core {
710
return '';
711
}
712
713
/**
714
* Counts words encounters from input string.
715
* Case insensitive. Returns first encounter of each word if found multiple times.
54
*/
55
final public function __set( $name, $value ) {
56
/**
57
+ * For now, no deprecation is being handled; as no properties have been deprecated.
58
*/
59
$this->_deprecated_function( 'the_seo_framework()->' . \esc_html( $name ), 'unknown' );
60
76
77
switch ( $name ) :
78
case 'pagehook' :
79
+ $this->_deprecated_function( 'the_seo_framework()->pagehook', '2.7.0', 'the_seo_framework()->seo_settings_page_hook' );
80
return $this->seo_settings_page_hook;
81
break;
82
120
121
if ( $this->the_seo_framework_debug ) {
122
123
+ $debug_instance = Debug::get_instance();
124
125
\add_action( 'the_seo_framework_do_before_output', array( $debug_instance, 'set_debug_query_output_cache' ) );
126
\add_action( 'admin_footer', array( $debug_instance, 'debug_screens' ) );
140
protected function clean_response_header() {
141
142
if ( $level = ob_get_level() ) {
143
+ while ( $level-- ) {
144
ob_end_clean();
145
}
146
return true;
147
}
159
*
160
* @param string $view The file name.
161
* @param array $args The arguments to be supplied within the file name.
162
+ * Each array key is converted to a variable with its value attached.
163
* @param string $instance The instance suffix to call back upon.
164
*/
165
public function get_view( $view, array $args = array(), $instance = 'main' ) {
169
170
$file = THE_SEO_FRAMEWORK_DIR_PATH_VIEWS . $view . '.php';
171
172
+ include $file;
173
}
174
175
/**
240
*
241
* @since 2.2.8
242
* @since 2.9.2 : Added TSFEM link.
243
+ * @since 3.0.0 : 1. Shortened names.
244
+ * 2. Added noreferrer to the external links.
245
*
246
* @param array $links The current links.
247
* @return array The plugin links.
251
$tsf_links = array();
252
253
if ( $this->load_options )
254
+ $tsf_links['settings'] = '<a href="' . \esc_url( \admin_url( 'admin.php?page=' . $this->seo_settings_page_slug ) ) . '">' . \esc_html__( 'Settings', 'autodescription' ) . '</a>';
255
256
+ $tsf_links['home'] = '<a href="' . \esc_url( 'https://theseoframework.com/' ) . '" rel="noreferrer noopener" target="_blank">' . \esc_html_x( 'Home', 'As in: The Plugin Home Page', 'autodescription' ) . '</a>';
257
258
/**
259
* These are weak checks.
262
if ( ! defined( 'TSF_EXTENSION_MANAGER_VERSION' ) ) {
263
$tsfem = \get_plugins( '/the-seo-framework-extension-manager' );
264
if ( empty( $tsfem ) )
265
+ $tsf_links['tsfem'] = '<a href="' . \esc_url( \__( 'https://wordpress.org/plugins/the-seo-framework-extension-manager/', 'autodescription' ) ) . '" rel="noreferrer noopener" target="_blank">' . \esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' ) . '</a>';
266
}
267
268
return array_merge( $tsf_links, $links );
573
/**
574
* Returns the minimum role required to adjust settings.
575
*
576
+ * @since 3.0.0
577
*
578
* @return string The minimum required capability for SEO Settings.
579
*/
580
+ public function get_settings_capability() {
581
+ /**
582
+ * Applies filters 'the_seo_framework_settings_capability'
583
+ *
584
+ * @since 2.6.0
585
+ * @string $capability The user capability required to adjust settings.
586
+ */
587
return (string) \apply_filters( 'the_seo_framework_settings_capability', 'manage_options' );
588
}
589
590
+ /**
591
+ * Determines if the current user can do settings.
592
+ * Not cached as it's imposing security functionality.
593
+ *
594
+ * @since 3.0.0
595
+ *
596
+ * @return bool
597
+ */
598
+ public function can_access_settings() {
599
+ return \current_user_can( $this->get_settings_capability() );
600
+ }
601
+
602
/**
603
* Returns the SEO Settings page URL.
604
*
627
*
628
* @param bool $guess : If true, the timezone will be guessed from the
629
* WordPress core gmt_offset option.
630
+ * @return string PHP Timezone String.
631
*/
632
public function get_timezone_string( $guess = false ) {
633
725
return '';
726
}
727
728
+ /**
729
+ * Returns timestamp format based on timestamp settings.
730
+ *
731
+ * @since 3.0.0
732
+ *
733
+ * @return string The timestamp format used in PHP date.
734
+ */
735
+ public function get_timestamp_format() {
736
+ return '1' === $this->get_option( 'timestamps_format' ) ? 'Y-m-d\TH:iP' : 'Y-m-d';
737
+ }
738
+
739
+ /**
740
+ * Determines if time is used in the timestamp format.
741
+ *
742
+ * @since 3.0.0
743
+ *
744
+ * @return bool True if time is used. False otherwise.
745
+ */
746
+ public function uses_time_in_timestamp_format() {
747
+ return '1' === $this->get_option( 'timestamps_format' );
748
+ }
749
+
750
/**
751
* Counts words encounters from input string.
752
* Case insensitive. Returns first encounter of each word if found multiple times.
inc/classes/debug.class.php CHANGED
@@ -209,29 +209,29 @@ final class Debug implements Debug_Interface {
209
* @since 2.8.0 Now escapes all input, except for $message.
210
* @access private
211
*
212
- * @param string $function The function that was called.
213
- * @param string $message A message explaining what has been done incorrectly.
214
- * @param string $version The version of WordPress where the message was added.
215
*/
216
public function _doing_it_wrong( $function, $message, $version = null ) {
217
/**
218
- * Fires when the given function is being used incorrectly.
219
- *
220
- * @since WP Core 3.1.0
221
- *
222
- * @param string $function The function that was called.
223
- * @param string $message A message explaining what has been done incorrectly.
224
- * @param string $version The version of WordPress where the message was added.
225
- */
226
\do_action( 'doing_it_wrong_run', $function, $message, $version );
227
228
/**
229
- * Filter whether to trigger an error for _doing_it_wrong() calls.
230
- *
231
- * @since 3.1.0
232
- *
233
- * @param bool $trigger Whether to trigger the error for _doing_it_wrong() calls. Default true.
234
- */
235
if ( WP_DEBUG && \apply_filters( 'doing_it_wrong_trigger_error', true ) ) {
236
237
set_error_handler( array( $this, 'error_handler_doing_it_wrong' ) );
@@ -272,8 +272,8 @@ final class Debug implements Debug_Interface {
272
*
273
* @since 2.7.0
274
*
275
- * @param string $p_or_m The Property or Method.
276
- * @param string $message A message explaining what has been done incorrectly.
277
*/
278
\do_action( 'the_seo_framework_inaccessible_p_or_m_run', $p_or_m, $message );
279
@@ -451,8 +451,7 @@ final class Debug implements Debug_Interface {
451
* @return bool True if there's output.
452
*/
453
public static function has_debug_output() {
454
- $instance = static::get_instance();
455
- return (bool) $instance->debug_output;
456
}
457
458
/**
@@ -462,11 +461,8 @@ final class Debug implements Debug_Interface {
462
* @access private
463
*/
464
public static function _output_debug() {
465
-
466
- $instance = static::get_instance();
467
//* Already escaped.
468
- echo $instance->debug_output;
469
-
470
}
471
472
/**
@@ -864,11 +860,8 @@ final class Debug implements Debug_Interface {
864
* @access private
865
*/
866
public static function _output_debug_header() {
867
-
868
- $instance = static::get_instance();
869
//* Already escaped.
870
- echo $instance->get_debug_header_output();
871
-
872
}
873
874
/**
209
* @since 2.8.0 Now escapes all input, except for $message.
210
* @access private
211
*
212
+ * @param string $function The function that was called.
213
+ * @param string $message A message explaining what has been done incorrectly.
214
+ * @param string $version The version of WordPress where the message was added.
215
*/
216
public function _doing_it_wrong( $function, $message, $version = null ) {
217
/**
218
+ * Fires when the given function is being used incorrectly.
219
+ *
220
+ * @since WP Core 3.1.0
221
+ *
222
+ * @param string $function The function that was called.
223
+ * @param string $message A message explaining what has been done incorrectly.
224
+ * @param string $version The version of WordPress where the message was added.
225
+ */
226
\do_action( 'doing_it_wrong_run', $function, $message, $version );
227
228
/**
229
+ * Filter whether to trigger an error for _doing_it_wrong() calls.
230
+ *
231
+ * @since 3.1.0
232
+ *
233
+ * @param bool $trigger Whether to trigger the error for _doing_it_wrong() calls. Default true.
234
+ */
235
if ( WP_DEBUG && \apply_filters( 'doing_it_wrong_trigger_error', true ) ) {
236
237
set_error_handler( array( $this, 'error_handler_doing_it_wrong' ) );
272
*
273
* @since 2.7.0
274
*
275
+ * @param string $p_or_m The Property or Method.
276
+ * @param string $message A message explaining what has been done incorrectly.
277
*/
278
\do_action( 'the_seo_framework_inaccessible_p_or_m_run', $p_or_m, $message );
279
451
* @return bool True if there's output.
452
*/
453
public static function has_debug_output() {
454
+ return (bool) static::get_instance()->debug_output;
455
}
456
457
/**
461
* @access private
462
*/
463
public static function _output_debug() {
464
//* Already escaped.
465
+ echo static::get_instance()->debug_output;
466
}
467
468
/**
860
* @access private
861
*/
862
public static function _output_debug_header() {
863
//* Already escaped.
864
+ echo static::get_instance()->get_debug_header_output();
865
}
866
867
/**
inc/classes/deprecated.class.php CHANGED
@@ -1,1290 +1,2012 @@
1
- <?php
2
- /**
3
- * @package The_SEO_Framework\Classes\Deprecated
4
- */
5
- namespace The_SEO_Framework;
6
-
7
- defined( 'ABSPATH' ) or die;
8
-
9
- /**
10
- * The SEO Framework plugin
11
- * Copyright (C) 2015 - 2017 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
- defined( 'ABSPATH' ) or die;
27
-
28
- /**
29
- * Class The_SEO_Framework\Deprecated
30
- *
31
- * Contains all deprecated functions.
32
- *
33
- * @since 2.8.0
34
- */
35
- final class Deprecated {
36
-
37
- /**
38
- * Constructor. Does nothing.
39
- */
40
- public function __construct() { }
41
-
42
- /**
43
- * HomePage Metabox General Tab Output.
44
- *
45
- * @since 2.6.0
46
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
47
- *
48
- * @deprecated
49
- * @since 2.7.0
50
- */
51
- public function homepage_metabox_general() {
52
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Metaboxes::' . __FUNCTION__, '2.7.0', 'The_SEO_Framework_Metaboxes::homepage_metabox_general_tab()' );
53
- \the_seo_framework()->get_view( 'metaboxes/homepage-metabox', array(), 'general' );
54
- }
55
-
56
- /**
57
- * HomePage Metabox Additions Tab Output.
58
- *
59
- * @since 2.6.0
60
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
61
- *
62
- * @deprecated
63
- * @since 2.7.0
64
- */
65
- public function homepage_metabox_additions() {
66
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Metaboxes::' . __FUNCTION__, '2.7.0', 'The_SEO_Framework_Metaboxes::homepage_metabox_additions_tab()' );
67
- \the_seo_framework()->get_view( 'metaboxes/homepage-metabox', array(), 'additions' );
68
- }
69
-
70
- /**
71
- * HomePage Metabox Robots Tab Output
72
- *
73
- * @since 2.6.0
74
- * @see $this->homepage_metabox() Callback for HomePage Settings box.
75
- *
76
- * @deprecated
77
- * @since 2.7.0
78
- */
79
- public function homepage_metabox_robots() {
80
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Metaboxes::' . __FUNCTION__, '2.7.0', 'The_SEO_Framework_Metaboxes::homepage_metabox_robots_tab()' );
81
- \the_seo_framework()->get_view( 'metaboxes/homepage-metabox', array(), 'robots' );
82
- }
83
-
84
- /**
85
- * Delete transient for the automatic description for blog on save request.
86
- * Returns old option, since that's passed for sanitation within WP Core.
87
- *
88
- * @since 2.3.3
89
- *
90
- * @deprecated
91
- * @since 2.7.0
92
- *
93
- * @param string $old_option The previous blog description option.
94
- * @return string Previous option.
95
- */
96
- public function delete_auto_description_blog_transient( $old_option ) {
97
-
98
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'The_SEO_Framework_Transients::delete_auto_description_frontpage_transient()' );
99
-
100
- \the_seo_framework()->delete_auto_description_transient( \the_seo_framework()->get_the_front_page_ID(), '', 'frontpage' );
101
-
102
- return $old_option;
103
- }
104
-
105
- /**
106
- * Add term meta data into options table of the term.
107
- * Adds separated database options for terms, as the terms table doesn't allow for addition.
108
- *
109
- * Applies filters array the_seo_framework_term_meta_defaults : Array of default term SEO options
110
- * Applies filters mixed the_seo_framework_term_meta_{field} : Override filter for specifics.
111
- * Applies filters array the_seo_framework_term_meta : Override output for term or taxonomy.
112
- *
113
- * @since 2.1.8
114
- *
115
- * @deprecated silently.
116
- * @since WordPress 4.4.0
117
- * @since The SEO Framework 2.7.0
118
- * @since 2.8.0: Deprecated visually.
119
- *
120
- * @param object $term Database row object.
121
- * @param string $taxonomy Taxonomy name that $term is part of.
122
- * @return object $term Database row object.
123
- */
124
- public function get_term_filter( $term, $taxonomy ) {
125
-
126
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'WordPress Core "get_term_meta()"' );
127
-
128
- return false;
129
- }
130
-
131
- /**
132
- * Adds The SEO Framework term meta data to functions that return multiple terms.
133
- *
134
- * @since 2.0.0
135
- *
136
- * @deprecated silently.
137
- * @since WordPress 4.4.0
138
- * @since The SEO Framework 2.7.0
139
- * @since 2.8.0: Deprecated visually.
140
- *
141
- * @param array $terms Database row objects.
142
- * @param string $taxonomy Taxonomy name that $terms are part of.
143
- * @return array $terms Database row objects.
144
- */
145
- public function get_terms_filter( array $terms, $taxonomy ) {
146
-
147
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'WordPress Core "get_term_meta()"' );
148
-
149
- return false;
150
- }
151
-
152
- /**
153
- * Save taxonomy meta data.
154
- * Fires when a user edits and saves a taxonomy.
155
- *
156
- * @since 2.1.8
157
- *
158
- * @deprecated silently.
159
- * @since WordPress 4.4.0
160
- * @since The SEO Framework 2.7.0
161
- * @since 2.8.0: Deprecated visually.
162
- *
163
- * @param integer $term_id Term ID.
164
- * @param integer $tt_id Term Taxonomy ID.
165
- * @return void Early on AJAX call.
166
- */
167
- public function taxonomy_seo_save( $term_id, $tt_id ) {
168
-
169
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'WordPress Core "update_term_meta()"' );
170
-
171
- return false;
172
- }
173
-
174
- /**
175
- * Delete term meta data.
176
- * Fires when a user deletes a term.
177
- *
178
- * @since 2.1.8
179
- *
180
- * @deprecated silently.
181
- * @since WordPress 4.4.0
182
- * @since The SEO Framework 2.7.0
183
- * @since 2.8.0: Deprecated visually.
184
- *
185
- * @param integer $term_id Term ID.
186
- * @param integer $tt_id Taxonomy Term ID.
187
- */
188
- public function term_meta_delete( $term_id, $tt_id ) {
189
-
190
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Transients::' . __FUNCTION__, '2.7.0', 'WordPress Core "delete_term_meta()"' );
191
-
192
- return false;
193
- }
194
-
195
- /**
196
- * Faster way of doing an in_array search compared to default PHP behavior.
197
- * @NOTE only to show improvement with large arrays. Might slow down with small arrays.
198
- * @NOTE can't do type checks. Always assume the comparing value is a string.
199
- *
200
- * @since 2.5.2
201
- * @since 2.7.0 Deprecated.
202
- * @deprecated
203
- *
204
- * @param string|array $needle The needle(s) to search for
205
- * @param array $array The single dimensional array to search in.
206
- * @return bool true if value is in array.
207
- */
208
- public function in_array( $needle, $array, $strict = true ) {
209
-
210
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Core::' . __FUNCTION__, '2.7.0', 'in_array()' );
211
-
212
- $array = array_flip( $array );
213
-
214
- if ( is_string( $needle ) ) {
215
- if ( isset( $array[ $needle ] ) )
216
- return true;
217
- } elseif ( is_array( $needle ) ) {
218
- foreach ( $needle as $str ) {
219
- if ( isset( $array[ $str ] ) )
220
- return true;
221
- }
222
- }
223
-
224
- return false;
225
- }
226
-
227
- /**
228
- * Fetches posts with exclude_local_search option on
229
- *
230
- * @since 2.1.7
231
- * @since 2.7.0 Deprecated.
232
- * @deprecated
233
- *
234
- * @return array Excluded Post IDs
235
- */
236
- public function exclude_search_ids() {
237
-
238
- \the_seo_framework()->_deprecated_function( 'The_SEO_Framework_Search::' . __FUNCTION__, '2.7.0', 'the_seo_framework()->get_excluded_search_ids()' );
239
-
240
- return $this->get_excluded_search_ids();
241
- }
242
-
243
- /**
244
- * Fetches posts with exclude_local_search option on.
245
- *
246
- * @since 2.1.7
247
- * @since 2.7.0 No longer used for performance reasons.
248
- * @uses $this->exclude_search_ids()
249
- * @deprecated
250
- * @since 2.8.0 deprecated.
251
- *
252
- * @param array $query The possible search query.
253
- * @return void Early if no search query is found.
254
- */
255
- public function search_filter( $query ) {
256
-
257
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->search_filter()', '2.8.0' );
258
-
259
- // Don't exclude pages in wp-admin.
260
- if ( $query->is_search && false === \the_seo_framework()->is_admin() ) {
261
-
262
- $q = $query->query;
263
- //* Only interact with an actual Search Query.
264
- if ( false === isset( $q['s'] ) )
265
- return;
266
-
267
- //* Get excluded IDs.
268
- $protected_posts = $this->get_excluded_search_ids();
269
- if ( $protected_posts ) {
270
- $get = $query->get( 'post__not_in' );
271
-
272
- //* Merge user defined query.
273
- if ( is_array( $get ) && ! empty( $get ) )
274
- $protected_posts = array_merge( $protected_posts, $get );
275
-
276
- $query->set( 'post__not_in', $protected_posts );
277
- }
278
-
279
- // Parse all ID's, even beyond the first page.
280
- $query->set( 'no_found_rows', false );
281
- }
282
- }
283
-
284
- /**
285
- * Fetches posts with exclude_local_search option on.
286
- *
287
- * @since 2.7.0
288
- * @since 2.7.0 No longer used.
289
- * @global int $blog_id
290
- * @deprecated
291
- *
292
- * @return array Excluded Post IDs
293
- */
294
- public function get_excluded_search_ids() {
295
-
296
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->get_excluded_search_ids()', '2.7.0' );
297
-
298
- global $blog_id;
299
-
300
- $cache_key = 'exclude_search_ids_' . $blog_id . '_' . \get_locale();
301
-
302
- $post_ids = \the_seo_framework()->object_cache_get( $cache_key );
303
- if ( false === $post_ids ) {
304
- $post_ids = array();
305
-
306
- $args = array(
307
- 'post_type' => 'any',
308
- 'numberposts' => -1,
309
- 'posts_per_page' => -1,
310
- 'order' => 'DESC',
311
- 'post_status' => 'publish',
312
- 'meta_key' => 'exclude_local_search',
313
- 'meta_value' => 1,
314
- 'meta_compare' => '=',
315
- 'cache_results' => true,
316
- 'suppress_filters' => false,
317
- );
318
- $get_posts = new \WP_Query;
319
- $excluded_posts = $get_posts->query( $args );
320
- unset( $get_posts );
321
-
322
- if ( $excluded_posts )
323
- $post_ids = \wp_list_pluck( $excluded_posts, 'ID' );
324
-
325
- \the_seo_framework()->object_cache_set( $cache_key, $post_ids, 86400 );
326
- }
327
-
328
- // return an array of exclude post IDs
329
- return $post_ids;
330
- }
331
-
332
- /**
333
- * Registers option sanitation filter
334
- *
335
- * @since 2.2.2
336
- * @since 2.7.0 : No longer used internally.
337
- * @since 2.8.0 : Deprecated
338
- * @deprecated
339
- *
340
- * @param string $filter The filter to call (see The_SEO_Framework_Site_Options::$available_filters for options)
341
- * @param string $option The WordPress option name
342
- * @param string|array $suboption Optional. The suboption or suboptions you want to filter
343
- * @return true on completion.
344
- */
345
- public function autodescription_add_option_filter( $filter, $option, $suboption = null ) {
346
-
347
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->add_option_filter()', '2.8.0' );
348
-
349
- return \the_seo_framework()->add_option_filter( $filter, $option, $suboption );
350
- }
351
-
352
- /**
353
- * Register each of the settings with a sanitization filter type.
354
- *
355
- * @since 2.2.2
356
- * @since 2.8.0 Deprecated.
357
- * @uses method add_filter() Assign filter to array of settings.
358
- * @see The_SEO_Framework_Sanitize::add_filter() Add sanitization filters to options.
359
- */
360
- public function sanitizer_filters() {
361
-
362
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->sanitizer_filters()', '2.8.0', 'the_seo_framework()->init_sanitizer_filters()' );
363
-
364
- \the_seo_framework()->init_sanitizer_filters();
365
- }
366
-
367
- /**
368
- * Fetches site icon brought in WordPress 4.3.0
369
- *
370
- * @since 2.2.1
371
- * @since 2.8.0: Deprecated.
372
- * @deprecated
373
- *
374
- * @param string $size The icon size, accepts 'full' and pixel values.
375
- * @param bool $set_og_dimensions Whether to set size for OG image. Always falls back to the current post ID.
376
- * @return string URL site icon, not escaped.
377
- */
378
- public function site_icon( $size = 'full', $set_og_dimensions = false ) {
379
-
380
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->site_icon()', '2.8.0', 'the_seo_framework()->get_site_icon()' );
381
-
382
- return the_seo_framework()->get_site_icon( $size, $set_og_dimensions );
383
- }
384
-
385
- /**
386
- * Delete transient on post save.
387
- *
388
- * @since 2.2.9
389
- * @since 2.8.0 : Deprecated
390
- * @deprecated
391
- *
392
- * @param int $post_id The Post ID that has been updated.
393
- * @return bool|null True when sitemap is flushed. False on revision. Null
394
- * when sitemaps are deactivated.
395
- */
396
- public function delete_transients_post( $post_id ) {
397
-
398
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->delete_transients_post()', '2.8.0', 'the_seo_framework()->delete_post_cache()' );
399
-
400
- return \the_seo_framework()->delete_post_cache( $post_id );
401
- }
402
-
403
- /**
404
- * Delete transient on profile save.
405
- *
406
- * @since 2.6.4
407
- * @since 2.8.0 : Deprecated
408
- * @deprecated
409
- *
410
- * @param int $user_id The User ID that has been updated.
411
- */
412
- public function delete_transients_author( $user_id ) {
413
-
414
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->delete_transients_author()', '2.8.0', 'the_seo_framework()->delete_author_cache()' );
415
-
416
- return \the_seo_framework()->delete_author_cache( $user_id );
417
- }
418
-
419
- /**
420
- * Flushes the home page LD+Json transient.
421
- *
422
- * @since 2.6.0
423
- * @since 2.8.0 deprecated.
424
- * @staticvar bool $flushed Prevents second flush.
425
- * @deprecated
426
- *
427
- * @return bool Whether it's flushed on current call.
428
- */
429
- public function delete_front_ld_json_transient() {
430
-
431
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->delete_front_ld_json_transient()', '2.8.0', 'the_seo_framework()->delete_cache( \'front\' )' );
432
-
433
- static $flushed = null;
434
-
435
- if ( isset( $flushed ) )
436
- return false;
437
-
438
- if ( ! \the_seo_framework()->is_option_checked( 'cache_meta_schema' ) )
439
- return $flushed = false;
440
-
441
- $front_id = \the_seo_framework()->get_the_front_page_ID();
442
-
443
- \the_seo_framework()->delete_ld_json_transient( $front_id, '', 'frontpage' );
444
-
445
- return $flushed = true;
446
- }
447
-
448
- /**
449
- * Determines whether we can use the new WordPress core term meta functionality.
450
- *
451
- * @since 2.7.0
452
- * @since 2.8.0: Deprecated. WordPress 4.4+ is now required.
453
- * @staticvar bool $cache
454
- * @deprecated
455
- *
456
- * @return bool True when WordPress is at version 4.4 or higher and has an
457
- * accordingly upgraded database.
458
- */
459
- public function can_get_term_meta() {
460
-
461
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->can_get_term_meta()', '2.8.0' );
462
-
463
- static $cache = null;
464
-
465
- if ( isset( $cache ) )
466
- return $cache;
467
-
468
- return $cache = \get_option( 'db_version' ) >= 34370 && \get_option( 'the_seo_framework_upgraded_db_version' ) >= '2700' && \the_seo_framework()->wp_version( '4.3.999', '>' );
469
- }
470
-
471
- /**
472
- * Fetches term metadata array for the inpost term metabox.
473
- *
474
- * @since 2.7.0
475
- * @since 2.8.0: Deprecated. WordPress 4.4+ is now required.
476
- * @deprecated
477
- *
478
- * @param object $term The TT object. Must be assigned.
479
- * @return array The SEO Framework TT data.
480
- */
481
- protected function get_old_term_data( $term ) {
482
-
483
- \the_seo_framework()->_deprecated_function( 'the_seo_framework()->get_old_term_data()', '2.8.0' );
484
-
485
- $data = array();
486
-
487
- $data['title'] = isset( $term->admeta['doctitle'] ) ? $term->admeta['doctitle'] : '';
488
- $data['description'] = isset( $term->admeta['description'] ) ? $term->admeta['description'] : '';
489
- $data['noindex'] = isset( $term->admeta['noindex'] ) ? $term->admeta['noindex'] : '';
490
- $data['nofollow'] = isset( $term->admeta['nofollow'] ) ? $term->admeta['nofollow'] : '';
491
- $data['noarchive'] = isset( $term->admeta['noarchive'] ) ? $term->admeta['noarchive'] : '';
492
- $flag = isset( $term->admeta['saved_flag'] ) ? (bool) $term->admeta['saved_flag'] : false;
493
-
494
- //* Genesis data fetch. This will override our options with Genesis options on save.
495
- if ( false === $flag && isset( $term->meta ) ) {
496
- $data['title'] = empty( $data['title'] ) && isset( $term->meta['doctitle'] ) ? $term->meta['doctitle'] : $data['noindex'];
497
- $data['description'] = empty( $data['description'] ) && isset( $term->meta['description'] ) ? $term->meta['description'] : $data['description'];
498
- $data['noindex'] = empty( $data['noindex'] ) && isset( $term->meta['noindex'] ) ? $term->meta['noindex'] : $data['noindex'];
499
- $data['nofollow'] = empty( $data['nofollow'] ) && isset( $term->meta['nofollow'] ) ? $term->meta['nofollow'] : $data['nofollow'];
500
- $data['noarchive'] = empty( $data['noarchive'] ) && isset( $term->meta['noarchive'] ) ? $term->meta['noarchive'] : $data['noarchive'];
501
- }
502
-
503
- return $data;
504
- }
505
-
506
- /**
507
- * Fetches og:image URL.
508
- *
509
- * @since 2.2.2
510
- * @since 2.2.8 : Added theme icon detection.
511
- * @since 2.5.2 : Added args filters.
512
- * @since 2.8.0 : 1. Added theme logo detection.
513
- * 2. Added inpost image selection detection.
514
- * @since 2.8.2 : 1. Now returns something on post ID 0.
515
- * 2. Added SEO settings fallback image selection detection.
516
- * @since 2.9.0 : 1. Added 'skip_fallback' option to arguments.
517
- * 2. Added 'escape' option to arguments.
518
- * 3. First parameter is now arguments. Fallback for integer is added.
519
- * 4. Second parameter is now deprecated.
520
- * 5. Deprecated.
521
- * @deprecated Use get_social_image instead.
522
- *
523
- * @param int|array $args The image arguments.
524
- * Was: $post_id.
525
- * Warning: Integer usage is only used for backwards compat.
526
- * @param array $depr_args, Deprecated;
527
- * Was $args The image arguments.
528
- * @param bool $escape Whether to escape the image URL.
529
- * Deprecated: You should use $args['escape'].
530
- * @return string the image URL.
531
- */
532
- public function get_image( $args = array(), $depr_args = '', $depr_escape = true ) {
533
-
534
- $tsf = \the_seo_framework();
535
-
536
- $tsf->_deprecated_function( 'the_seo_framework()->get_image()', '2.9.0', 'the_seo_framework()->get_social_image()' );
537
-
538
- if ( is_int( $args ) || is_array( $depr_args ) ) {
539
- $tsf->_doing_it_wrong( __METHOD__, 'First parameter is now used for arguments. Second parameter is deprecated.', '2.9.0' );
540
-
541
- $post_id = $args;
542
- $args = array();
543
-
544
- /**
545
- * Backwards compat with parse args.
546
- * @since 2.5.0
547
- */
548
- if ( ! isset( $depr_args['post_id'] ) ) {
549
- $args['post_id'] = $post_id ?: ( $tsf->is_singular( $post_id ) ? $tsf->get_the_real_ID() : 0 );
550
- }
551
-
552
- if ( is_array( $depr_args ) ) {
553
- $args = \wp_parse_args( $depr_args, $args );
554
- }
555
- }
556
-
557
- if ( false === $depr_escape ) {
558
- $tsf->_doing_it_wrong( __METHOD__, 'Third parameter has been deprecated. Use `$args["escape"] => false` instead.', '2.9.0' );
559
- $args['escape'] = false;
560
- }
561
-
562
- $args = $tsf->reparse_image_args( $args );
563
-
564
- //* 0. Image from argument.
565
- pre_0 : {
566
- if ( $image = $args['image'] )