The SEO Framework - Version 2.9.4

Version Description

  • Terminal Queries =

Release date:

  • August 30th, 2017

Summarized:

  • New performance options have been added. They allow you to optimize Search and Archive query alterations.
  • Schema.org JSON-LD data is now cleaner when you run PHP 5.4 or later.
  • Custom input image URLs can now dynamically switch between HTTP and HTTPS and the dimensions are always set, regardless of input.
  • Multisite networks no longer initiate new database connections on every page for plugin compatibility checks.

Did you know?

  • Local SEO has been added to the Extension Manager.
  • It increases location-aware search presence in Google Search, Google Maps, and even Google Images.

Detailed log:

  • I had not overlooked them, and they shall be answered.
Download this release

Release Info

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

Code changes from version 2.9.3 to 2.9.4

autodescription.php CHANGED
@@ -3,7 +3,7 @@
3
* Plugin Name: The SEO Framework
4
* Plugin URI: https://theseoframework.com/
5
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
- * Version: 2.9.3
7
* Author: Sybre Waaijer
8
* Author URI: https://theseoframework.com/
9
* License: GPLv3
@@ -51,7 +51,7 @@ defined( 'ABSPATH' ) or die;
51
*
52
* @since 1.0.0
53
*/
54
- define( 'THE_SEO_FRAMEWORK_VERSION', '2.9.3' );
55
56
/**
57
* The plugin Database version.
@@ -60,7 +60,7 @@ define( 'THE_SEO_FRAMEWORK_VERSION', '2.9.3' );
60
*
61
* @since 2.7.0
62
*/
63
- define( 'THE_SEO_FRAMEWORK_DB_VERSION', '2903' );
64
65
/**
66
* The plugin options database option_name.
@@ -162,10 +162,12 @@ the_seo_framework_pre_load();
162
* Determines whether we can "just" load the plugin, or require verification beforehand.
163
*
164
* @since 2.8.0
165
* @uses get_site_option(), so it will only test once per WordPress installation; multisite included.
166
*/
167
function the_seo_framework_pre_load() {
168
- if ( get_site_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION ) {
169
the_seo_framework_load_base_files();
170
} else {
171
the_seo_framework_test_server();
@@ -182,7 +184,7 @@ function the_seo_framework_test_server() {
182
//* Load on init action (manual FTP upload) or after plugin has been upgraded.
183
require_once( THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'plugin-test-server.php' );
184
185
- if ( get_site_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
186
the_seo_framework_load_base_files();
187
}
188
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
51
*
52
* @since 1.0.0
53
*/
54
+ define( 'THE_SEO_FRAMEWORK_VERSION', '2.9.4' );
55
56
/**
57
* The plugin Database version.
60
*
61
* @since 2.7.0
62
*/
63
+ define( 'THE_SEO_FRAMEWORK_DB_VERSION', '2941' );
64
65
/**
66
* The plugin options database option_name.
162
* Determines whether we can "just" load the plugin, or require verification beforehand.
163
*
164
* @since 2.8.0
165
+ * @since 2.9.4 The option is now autoloaded.
166
* @uses get_site_option(), so it will only test once per WordPress installation; multisite included.
167
+ * @todo This option isn't autoloaded... use is_multisite() condition?
168
*/
169
function the_seo_framework_pre_load() {
170
+ if ( get_option( 'the_seo_framework_tested_upgrade_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION ) {
171
the_seo_framework_load_base_files();
172
} else {
173
the_seo_framework_test_server();
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();
189
}
190
inc/classes/admin-init.class.php CHANGED
@@ -678,7 +678,7 @@ class Admin_Init extends Init {
678
$cropped = \wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] );
679
680
if ( ! $cropped || \is_wp_error( $cropped ) )
681
- \wp_send_json_error( array( 'message' => \esc_js__( 'Image could not be processed.', 'autodescription' ) ) );
682
683
switch ( $context ) :
684
case 'tsf-image':
@@ -740,7 +740,7 @@ class Admin_Init extends Init {
740
break;
741
742
default :
743
- \wp_send_json_error( array( 'message' => \esc_js__( 'Image could not be processed.', 'autodescription' ) ) );
744
break;
745
endswitch;
746
678
$cropped = \wp_crop_image( $attachment_id, $data['x1'], $data['y1'], $data['width'], $data['height'], $data['dst_width'], $data['dst_height'] );
679
680
if ( ! $cropped || \is_wp_error( $cropped ) )
681
+ \wp_send_json_error( array( 'message' => \esc_js( \__( 'Image could not be processed.', 'autodescription' ) ) ) );
682
683
switch ( $context ) :
684
case 'tsf-image':
740
break;
741
742
default :
743
+ \wp_send_json_error( array( 'message' => \esc_js( \__( 'Image could not be processed.', 'autodescription' ) ) ) );
744
break;
745
endswitch;
746
inc/classes/cache.class.php CHANGED
@@ -819,8 +819,8 @@ class Cache extends Sitemaps {
819
* Adds cache key suffix based on blog id and locale.
820
*
821
* @since 2.7.0
822
- * @since 2.8.0 $locale is now static.
823
- * $key may now be empty.
824
* @staticvar string $locale
825
*
826
* @return string the cache key.
@@ -1095,6 +1095,7 @@ class Cache extends Sitemaps {
1095
* @since 2.4.2
1096
* @since 2.8.0 Now listens to option 'cache_meta_schema' before deleting transient.
1097
* @since 2.9.1 Now no longer sets object property $this->ld_json_transient.
1098
*
1099
* @param mixed $page_id The page ID or identifier.
1100
* @param string $taxonomy The tt name.
@@ -1103,20 +1104,12 @@ class Cache extends Sitemaps {
1103
*/
1104
public function delete_ld_json_transient( $page_id, $taxonomy = '', $type = null ) {
1105
1106
- static $flushed = null;
1107
-
1108
- if ( ! isset( $flushed ) ) {
1109
- if ( $this->is_option_checked( 'cache_meta_schema' ) ) {
1110
- $transient = $this->get_ld_json_transient( $page_id, $taxonomy, $type );
1111
- \delete_transient( $transient );
1112
- }
1113
-
1114
- $flushed = 'Oh behave!';
1115
-
1116
- return true;
1117
}
1118
1119
- return false;
1120
}
1121
1122
/**
819
* Adds cache key suffix based on blog id and locale.
820
*
821
* @since 2.7.0
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.
1095
* @since 2.4.2
1096
* @since 2.8.0 Now listens to option 'cache_meta_schema' before deleting transient.
1097
* @since 2.9.1 Now no longer sets object property $this->ld_json_transient.
1098
+ * @since 2.9.4 Removed cache.
1099
*
1100
* @param mixed $page_id The page ID or identifier.
1101
* @param string $taxonomy The tt name.
1104
*/
1105
public function delete_ld_json_transient( $page_id, $taxonomy = '', $type = null ) {
1106
1107
+ if ( $this->is_option_checked( 'cache_meta_schema' ) ) {
1108
+ $transient = $this->get_ld_json_transient( $page_id, $taxonomy, $type );
1109
+ \delete_transient( $transient );
1110
}
1111
1112
+ return true;
1113
}
1114
1115
/**
inc/classes/deprecated.class.php CHANGED
@@ -282,7 +282,7 @@ final class Deprecated {
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.
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.
inc/classes/detect.class.php CHANGED
@@ -58,6 +58,38 @@ class Detect extends Render {
58
return $cache;
59
}
60
61
/**
62
* Returns list of active plugins.
63
*
58
return $cache;
59
}
60
61
+ /**
62
+ * Tests if input URL matches current domain.
63
+ *
64
+ * @since 2.9.4
65
+ *
66
+ * @param string $url The URL to test.
67
+ * @return bool true on match, false otherwise.
68
+ */
69
+ public function matches_this_domain( $url = '' ) {
70
+
71
+ if ( ! $url )
72
+ return false;
73
+
74
+ static $home_domain;
75
+
76
+ if ( ! $home_domain ) {
77
+ $home_domain = \esc_url_raw( \get_home_url(), array( 'http', 'https' ) );
78
+ //= Simply convert to HTTPS/HTTP based on is_ssl()
79
+ $home_domain = $this->set_url_scheme( $home_domain, null, false );
80
+ }
81
+
82
+ $url = \esc_url_raw( $url, array( 'http', 'https' ) );
83
+ //= Simply convert to HTTPS/HTTP based on is_ssl()
84
+ $url = $this->set_url_scheme( $url, null, false );
85
+
86
+ //= If they start with the same, we can assume it's the same domain.
87
+ if ( 0 === stripos( $url, $home_domain ) )
88
+ return true;
89
+
90
+ return false;
91
+ }
92
+
93
/**
94
* Returns list of active plugins.
95
*
inc/classes/doing-it-right.class.php CHANGED
@@ -67,6 +67,7 @@ class Doing_It_Right extends Generate_Ldjson {
67
* Adds post states in post/page edit.php query
68
*
69
* @since 2.1.0
70
*
71
* @param array $states The current post states array
72
* @param object $post The Post Object.
@@ -76,8 +77,8 @@ class Doing_It_Right extends Generate_Ldjson {
76
$post_id = isset( $post->ID ) ? $post->ID : false;
77
78
if ( $post_id ) {
79
- $search_exclude = (bool) $this->get_custom_field( 'exclude_local_search', $post_id );
80
- $archive_exclude = (bool) $this->get_custom_field( 'exclude_from_archive', $post_id );
81
82
if ( $search_exclude )
83
$states[] = \esc_html__( 'No Search', 'autodescription' );
@@ -693,13 +694,13 @@ class Doing_It_Right extends Generate_Ldjson {
693
*
694
* @param array $args The term args.
695
* @return array $data {
696
- * 'title' => $title,
697
- * 'title_is_from_custom_field' => $title_is_from_custom_field,
698
- * 'description' => $description,
699
- * 'description_is_from_custom_field' => $description_is_from_custom_field,
700
- * 'noindex' => $noindex,
701
- * 'nofollow' => $nofollow,
702
- * 'noarchive' => $noarchive
703
* }
704
*/
705
protected function the_seo_bar_term_data( $args ) {
@@ -743,14 +744,14 @@ class Doing_It_Right extends Generate_Ldjson {
743
$nofollow = (bool) $nofollow;
744
$noarchive = (bool) $noarchive;
745
746
- return array(
747
- 'title' => $title,
748
- 'title_is_from_custom_field' => $title_is_from_custom_field,
749
- 'description' => $description,
750
- 'description_is_from_custom_field' => $description_is_from_custom_field,
751
- 'noindex' => $noindex,
752
- 'nofollow' => $nofollow,
753
- 'noarchive' => $noarchive,
754
);
755
}
756
@@ -763,13 +764,13 @@ class Doing_It_Right extends Generate_Ldjson {
763
*
764
* @param array $args The post args.
765
* @return array $data {
766
- * 'title' => $title,
767
- * 'title_is_from_custom_field' => $title_is_from_custom_field,
768
- * 'description' => $description,
769
- * 'description_is_from_custom_field' => $description_is_from_custom_field,
770
- * 'noindex' => $noindex,
771
- * 'nofollow' => $nofollow,
772
- * 'noarchive' => $noarchive
773
* }
774
*/
775
protected function the_seo_bar_post_data( $args ) {
@@ -809,14 +810,14 @@ class Doing_It_Right extends Generate_Ldjson {
809
$nofollow = (bool) $nofollow;
810
$noarchive = (bool) $noarchive;
811
812
- return array(
813
- 'title' => $title,
814
- 'title_is_from_custom_field' => $title_is_from_custom_field,
815
- 'description' => $description,
816
- 'description_is_from_custom_field' => $description_is_from_custom_field,
817
- 'noindex' => $noindex,
818
- 'nofollow' => $nofollow,
819
- 'noarchive' => $noarchive,
820
);
821
}
822
67
* Adds post states in post/page edit.php query
68
*
69
* @since 2.1.0
70
+ * @since 2.9.4 Now listens to `alter_search_query` and `alter_archive_query` options.
71
*
72
* @param array $states The current post states array
73
* @param object $post The Post Object.
77
$post_id = isset( $post->ID ) ? $post->ID : false;
78
79
if ( $post_id ) {
80
+ $search_exclude = $this->get_option( 'alter_search_query' ) && $this->get_custom_field( 'exclude_local_search', $post_id );
81
+ $archive_exclude = $this->get_option( 'alter_archive_query' ) && $this->get_custom_field( 'exclude_from_archive', $post_id );
82
83
if ( $search_exclude )
84
$states[] = \esc_html__( 'No Search', 'autodescription' );
694
*
695
* @param array $args The term args.
696
* @return array $data {
697
+ * $title,
698
+ * $title_is_from_custom_field,
699
+ * $description,
700
+ * $description_is_from_custom_field,
701
+ * $noindex,
702
+ * $nofollow,
703
+ * $noarchive
704
* }
705
*/
706
protected function the_seo_bar_term_data( $args ) {
744
$nofollow = (bool) $nofollow;
745
$noarchive = (bool) $noarchive;
746
747
+ return compact(
748
+ 'title',
749
+ 'title_is_from_custom_field',
750
+ 'description',
751
+ 'description_is_from_custom_field',
752
+ 'noindex',
753
+ 'nofollow',
754
+ 'noarchive'
755
);
756
}
757
764
*
765
* @param array $args The post args.
766
* @return array $data {
767
+ * $title,
768
+ * $title_is_from_custom_field,
769
+ * $description,
770
+ * $description_is_from_custom_field,
771
+ * $noindex,
772
+ * $nofollow,
773
+ * $noarchive
774
* }
775
*/
776
protected function the_seo_bar_post_data( $args ) {
810
$nofollow = (bool) $nofollow;
811
$noarchive = (bool) $noarchive;
812
813
+ return compact(
814
+ 'title',
815
+ 'title_is_from_custom_field',
816
+ 'description',
817
+ 'description_is_from_custom_field',
818
+ 'noindex',
819
+ 'nofollow',
820
+ 'noarchive'
821
);
822
}
823
inc/classes/feed.class.php CHANGED
@@ -173,10 +173,14 @@ class Feed extends Cache {
173
174
/**
175
* Applies filters 'the_seo_framework_feed_source_link' : string
176
* @since 2.6.0
177
*/
178
$source_i18n = (string) \apply_filters( 'the_seo_framework_feed_source_link_text', \_x( 'Source', 'The content source', 'autodescription' ) );
179
- $content = '<p><a href="' . $permalink . '" rel="external nofollow">' . \esc_html( $source_i18n ) . '</a></p>';
180
181
return $content;
182
}
173
174
/**
175
* Applies filters 'the_seo_framework_feed_source_link' : string
176
+ *
177
* @since 2.6.0
178
+ * @since 2.7.2 or 2.7.3: Escaped output.
179
+ *
180
+ * @param string $source The source indication string.
181
*/
182
$source_i18n = (string) \apply_filters( 'the_seo_framework_feed_source_link_text', \_x( 'Source', 'The content source', 'autodescription' ) );
183
+ $content = '<p><a href="' . $permalink . '" rel="nofollow">' . \esc_html( $source_i18n ) . '</a></p>';
184
185
return $content;
186
}
inc/classes/generate-description.class.php CHANGED
@@ -47,11 +47,11 @@ class Generate_Description extends Generate {
47
*
48
* @param string $description The optional description to simply parse.
49
* @param array $args description args : {
50
- * @param int $id the term or page id.
51
- * @param string $taxonomy taxonomy name.
52
- * @param bool $is_home We're generating for the home page.
53
- * @param bool $get_custom_field Do not fetch custom title when false.
54
- * @param bool $social Generate Social Description when true.
55
* }
56
* @return string The description
57
*/
@@ -134,11 +134,11 @@ class Generate_Description extends Generate {
134
135
/**
136
* Applies filters 'the_seo_framework_description_args' : array {
137
- * @param int $id the term or page id.
138
- * @param string $taxonomy taxonomy name.
139
- * @param bool $is_home We're generating for the home page.
140
- * @param bool $get_custom_field Do not fetch custom title when false.
141
- * @param bool $social Generate Social Description when true.
142
* }
143
*
144
* @since 2.5.0
@@ -197,9 +197,9 @@ class Generate_Description extends Generate {
197
* @since 2.4.1
198
*
199
* @param array $args description args : {
200
- * @param int $id the term or page id.
201
- * @param string $taxonomy taxonomy name.
202
- * @param bool $is_home We're generating for the home page.
203
* }
204
* @param bool $escape Escape the output if true.
205
* @return string|mixed The description.
@@ -302,11 +302,11 @@ class Generate_Description extends Generate {
302
* @since 2.3.3
303
*
304
* @param array $args description args : {
305
- * @param int $id the term or page id.
306
- * @param string $taxonomy taxonomy name.
307
- * @param bool $is_home We're generating for the home page.
308
- * @param bool $get_custom_field Do not fetch custom title when false.
309
- * @param bool $social Generate Social Description when true.
310
* }
311
* @param bool $escape Escape output when true.
312
* @return string $output The description.
@@ -342,14 +342,14 @@ class Generate_Description extends Generate {
342
* : The cache will no longer be maintained on previews or search.
343
*
344
* @param array $args description args : {
345
- * @param int $id the term or page id.
346
- * @param string $taxonomy taxonomy name.
347
- * @param bool $is_home We're generating for the home page.
348
- * @param bool $get_custom_field Do not fetch custom title when false.
349
- * @param bool $social Generate Social Description when true.
350
* }
351
* @param bool $escape Whether to escape the description.
352
- * NOTE: When this is false, be sure to trim the output.
353
* @return string The description.
354
*/
355
protected function generate_the_description( $args, $escape = true ) {
@@ -467,8 +467,8 @@ class Generate_Description extends Generate {
467
* @param int $id The post/term ID.
468
* @param bool|object The term object.
469
* @return array {
470
- * 'excerpt' => string The excerpt. Unescaped.
471
- * 'trim' => bool Whether to trim the additions.
472
* }
473
*/
474
public function get_description_excerpt_normal( $id = 0, $term = false ) {
@@ -595,10 +595,10 @@ class Generate_Description extends Generate {
595
596
/**
597
* Applies filters the_seo_framework_add_description_additions : {
598
- * @param bool true to add prefix.
599
- * @param int $id The Term object ID or The Page ID.
600
- * @param object $term The Term object.
601
- * }
602
* @since 2.6.0
603
*/
604
$filter = \apply_filters( 'the_seo_framework_add_description_additions', true, $id, $term );
@@ -661,10 +661,10 @@ class Generate_Description extends Generate {
661
* @param object|empty $term The term object
662
* @param bool $ignore Whether to ignore options and filters.
663
* @return array : {
664
- * $title => The title
665
- * $on => The word separator
666
- * $blogname => The blogname
667
- * $sep => The separator
668
* }
669
*/
670
public function generate_description_additions( $id = 0, $term = '', $ignore = false ) {
47
*
48
* @param string $description The optional description to simply parse.
49
* @param array $args description args : {
50
+ * @param int $id the term or page id.
51
+ * @param string $taxonomy taxonomy name.
52
+ * @param bool $is_home We're generating for the home page.
53
+ * @param bool $get_custom_field Do not fetch custom title when false.
54
+ * @param bool $social Generate Social Description when true.
55
* }
56
* @return string The description
57
*/
134
135
/**
136
* Applies filters 'the_seo_framework_description_args' : array {
137
+ * @param int $id the term or page id.
138
+ * @param string $taxonomy taxonomy name.
139
+ * @param bool $is_home We're generating for the home page.
140
+ * @param bool $get_custom_field Do not fetch custom title when false.
141
+ * @param bool $social Generate Social Description when true.
142
* }
143
*
144
* @since 2.5.0
197
* @since 2.4.1
198
*
199
* @param array $args description args : {
200
+ * @param int $id the term or page id.
201
+ * @param string $taxonomy taxonomy name.
202
+ * @param bool $is_home We're generating for the home page.
203
* }
204
* @param bool $escape Escape the output if true.
205
* @return string|mixed The description.
302
* @since 2.3.3
303
*
304
* @param array $args description args : {
305
+ * @param int $id the term or page id.
306
+ * @param string $taxonomy taxonomy name.
307
+ * @param bool $is_home We're generating for the home page.
308
+ * @param bool $get_custom_field Do not fetch custom title when false.
309
+ * @param bool $social Generate Social Description when true.
310
* }
311
* @param bool $escape Escape output when true.
312
* @return string $output The description.
342
* : The cache will no longer be maintained on previews or search.
343
*
344
* @param array $args description args : {
345
+ * @param int $id the term or page id.
346
+ * @param string $taxonomy taxonomy name.
347
+ * @param bool $is_home We're generating for the home page.
348
+ * @param bool $get_custom_field Do not fetch custom title when false.
349
+ * @param bool $social Generate Social Description when true.
350
* }
351
* @param bool $escape Whether to escape the description.
352
+ * NOTE: When this is false, be sure to trim the output.
353
* @return string The description.
354
*/
355
protected function generate_the_description( $args, $escape = true ) {
467
* @param int $id The post/term ID.
468
* @param bool|object The term object.
469
* @return array {
470
+ * 'excerpt' => string The excerpt. Unescaped.
471
+ * 'trim' => bool Whether to trim the additions.
472
* }
473
*/
474
public function get_description_excerpt_normal( $id = 0, $term = false ) {
595
596
/**
597
* Applies filters the_seo_framework_add_description_additions : {
598
+ * @param bool true to add prefix.
599
+ * @param int $id The Term object ID or The Page ID.
600
+ * @param object $term The Term object.
601
+ * }
602
* @since 2.6.0
603
*/
604
$filter = \apply_filters( 'the_seo_framework_add_description_additions', true, $id, $term );
661
* @param object|empty $term The term object
662
* @param bool $ignore Whether to ignore options and filters.
663
* @return array : {
664
+ * $title => The title
665
+ * $on => The word separator
666
+ * $blogname => The blogname
667
+ * $sep => The separator
668
* }
669
*/
670
public function generate_description_additions( $id = 0, $term = '', $ignore = false ) {
inc/classes/generate-image.class.php CHANGED
@@ -185,6 +185,9 @@ class Generate_Image extends Generate_Url {
185
/**
186
* Applies filters 'the_seo_framework_og_image_after_featured' : string
187
* @since 2.5.2
188
*/
189
fallback_1 : {
190
if ( $image = (string) \apply_filters( 'the_seo_framework_og_image_after_featured', '', $args['post_id'] ) )
@@ -201,6 +204,9 @@ class Generate_Image extends Generate_Url {
201
/**
202
* Applies filters 'the_seo_framework_og_image_after_header' : string
203
* @since 2.5.2
204
*/
205
fallback_2 : {
206
if ( $image = (string) \apply_filters( 'the_seo_framework_og_image_after_header', '', $args['post_id'] ) )
@@ -257,24 +263,24 @@ class Generate_Image extends Generate_Url {
257
);
258
259
/**
260
- * Applies filters the_seo_framework_og_image_args : {
261
- * @param string $image The image url
262
- * @param mixed $size The image size
263
- * @param bool $icon Fetch Image icon
264
- * @param bool 'skip_fallback' Whether to skip fallback images.
265
- * @param array $disallowed Disallowed image types : {
266
- * array (
267
- * string 'featured'
268
- * string 'header'
269
- * string 'icon'
270
- * )
271
- * }
272
- * @param bool 'escape' Whether to escape output.
273
- * }
274
*
275
* @since 2.0.1
276
*
277
- * @param array $defaults The image defaults.
278
* @param array $args The input args.
279
*/
280
$defaults = (array) \apply_filters( 'the_seo_framework_og_image_args', $defaults, $args );
@@ -322,6 +328,7 @@ class Generate_Image extends Generate_Url {
322
* Returns unescaped HomePage settings image URL from post ID input.
323
*
324
* @since 2.9.0
325
* @uses $this->image_dimensions
326
*
327
* @param int $id The post ID.
@@ -347,10 +354,16 @@ class Generate_Image extends Generate_Url {
347
$w = $_src[1]; // Width
348
$h = $_src[2]; // Height
349
350
- if ( \esc_url( $this->set_preferred_url_scheme( $i ) ) === \esc_url( $this->set_preferred_url_scheme( $src ) ) )
351
$this->image_dimensions = $this->image_dimensions + array( $id => array( 'width' => $w, 'height' => $h ) );
352
}
353
354
return $src;
355
}
356
@@ -360,6 +373,7 @@ class Generate_Image extends Generate_Url {
360
* @since 2.8.0
361
* @since 2.9.0 1. The second parameter now works.
362
* 2. Fallback image ID has been removed.
363
* @uses $this->image_dimensions
364
*
365
* @param int $id The post ID. Required.
@@ -381,10 +395,16 @@ class Generate_Image extends Generate_Url {
381
$w = $_src[1]; // Width
382
$h = $_src[2]; // Height
383
384
- if ( \esc_url( $this->set_preferred_url_scheme( $i ) ) === \esc_url( $this->set_preferred_url_scheme( $src ) ) )
385
$this->image_dimensions = $this->image_dimensions + array( $id => array( 'width' => $w, 'height' => $h ) );
386
}
387
388
return $src;
389
}
390
@@ -392,6 +412,8 @@ class Generate_Image extends Generate_Url {
392
* Returns unescaped URL from options input.
393
*
394
* @since 2.8.2
395
* @uses $this->image_dimensions
396
*
397
* @param bool $set_og_dimensions Whether to set open graph and twitter dimensions.
@@ -405,17 +427,23 @@ class Generate_Image extends Generate_Url {
405
return '';
406
407
//* Calculate image sizes.
408
- if ( $img_id = $this->get_option( 'social_image_fb_id' ) ) {
409
$_src = \wp_get_attachment_image_src( $img_id, 'full' );
410
411
$i = $_src[0]; // Source URL
412
$w = $_src[1]; // Width
413
$h = $_src[2]; // Height
414
415
- if ( \esc_url( $this->set_preferred_url_scheme( $i ) ) === \esc_url( $this->set_preferred_url_scheme( $src ) ) )
416
$this->image_dimensions = $this->image_dimensions + array( $this->get_the_real_ID() => array( 'width' => $w, 'height' => $h ) );
417
}
418
419
return $src;
420
}
421
@@ -427,6 +455,7 @@ class Generate_Image extends Generate_Url {
427
*
428
* @since 2.9.0
429
* @since 2.9.3 Now supports 4K.
430
*
431
* @param int $id The post ID. Required.
432
* @param array $args The image args.
@@ -443,9 +472,12 @@ class Generate_Image extends Generate_Url {
443
$args = $this->reparse_image_args( $args );
444
$args['get_the_real_ID'] = true;
445
446
- $image = $this->parse_og_image( $image_id, $args, $set_og_dimensions );
447
448
- return $image;
449
}
450
451
/**
185
/**
186
* Applies filters 'the_seo_framework_og_image_after_featured' : string
187
* @since 2.5.2
188
+ *
189
+ * @param string $image The image URL.
190
+ * @param int $post_id The post ID.
191
*/
192
fallback_1 : {
193
if ( $image = (string) \apply_filters( 'the_seo_framework_og_image_after_featured', '', $args['post_id'] ) )
204
/**
205
* Applies filters 'the_seo_framework_og_image_after_header' : string
206
* @since 2.5.2
207
+ *
208
+ * @param string $image The image URL.
209
+ * @param int $post_id The post ID.
210
*/
211
fallback_2 : {
212
if ( $image = (string) \apply_filters( 'the_seo_framework_og_image_after_header', '', $args['post_id'] ) )
263
);
264
265
/**
266
+ * Applies filters the_seo_framework_og_image_args : array
267
*
268
* @since 2.0.1
269
*
270
+ * @param array $defaults The image defaults: {
271
+ * @param string $image The image url
272
+ * @param mixed $size The image size
273
+ * @param bool $icon Fetch Image icon
274
+ * @param bool 'skip_fallback' Whether to skip fallback images.
275
+ * @param array $disallowed Disallowed image types : {
276
+ * array (
277
+ * string 'featured'
278
+ * string 'header'
279
+ * string 'icon'
280
+ * )
281
+ * }
282
+ * @param bool 'escape' Whether to escape output.
283
+ * }
284
* @param array $args The input args.
285
*/
286
$defaults = (array) \apply_filters( 'the_seo_framework_og_image_args', $defaults, $args );
328
* Returns unescaped HomePage settings image URL from post ID input.
329
*
330
* @since 2.9.0
331
+ * @since 2.9.4 Now converts URL scheme.
332
* @uses $this->image_dimensions
333
*
334
* @param int $id The post ID.
354
$w = $_src[1]; // Width
355
$h = $_src[2]; // Height
356
357
+ $test_i = \esc_url_raw( $this->set_preferred_url_scheme( $i ), array( 'http', 'https' ) );
358
+ $test_src = \esc_url_raw( $this->set_preferred_url_scheme( $src ), array( 'http', 'https' ) );
359
+
360
+ if ( $test_i === $test_src )
361
$this->image_dimensions = $this->image_dimensions + array( $id => array( 'width' => $w, 'height' => $h ) );
362
}
363
364
+ if ( $src && $this->matches_this_domain( $src ) )
365
+ $src = $this->set_preferred_url_scheme( $src );
366
+
367
return $src;
368
}
369
373
* @since 2.8.0
374
* @since 2.9.0 1. The second parameter now works.
375
* 2. Fallback image ID has been removed.
376
+ * @since 2.9.4 Now converts URL scheme.
377
* @uses $this->image_dimensions
378
*
379
* @param int $id The post ID. Required.
395
$w = $_src[1]; // Width
396
$h = $_src[2]; // Height
397
398
+ $test_i = \esc_url_raw( $this->set_preferred_url_scheme( $i ), array( 'http', 'https' ) );
399
+ $test_src = \esc_url_raw( $this->set_preferred_url_scheme( $src ), array( 'http', 'https' ) );
400
+
401
+ if ( $test_i === $test_src )
402
$this->image_dimensions = $this->image_dimensions + array( $id => array( 'width' => $w, 'height' => $h ) );
403
}
404
405
+ if ( $src && $this->matches_this_domain( $src ) )
406
+ $src = $this->set_preferred_url_scheme( $src );
407
+
408
return $src;
409
}
410
412
* Returns unescaped URL from options input.
413
*
414
* @since 2.8.2
415
+ * @since 2.9.4 1: Now converts URL scheme.
416
+ * 2: $set_og_dimensions now works.
417
* @uses $this->image_dimensions
418
*
419
* @param bool $set_og_dimensions Whether to set open graph and twitter dimensions.
427
return '';
428
429
//* Calculate image sizes.
430
+ if ( $set_og_dimensions && $img_id = $this->get_option( 'social_image_fb_id' ) ) {
431
$_src = \wp_get_attachment_image_src( $img_id, 'full' );
432
433
$i = $_src[0]; // Source URL
434
$w = $_src[1]; // Width
435
$h = $_src[2]; // Height
436
437
+ $test_i = \esc_url_raw( $this->set_preferred_url_scheme( $i ), array( 'http', 'https' ) );
438
+ $test_src = \esc_url_raw( $this->set_preferred_url_scheme( $src ), array( 'http', 'https' ) );
439
+
440
+ if ( $test_i === $test_src )
441
$this->image_dimensions = $this->image_dimensions + array( $this->get_the_real_ID() => array( 'width' => $w, 'height' => $h ) );
442
}
443
444
+ if ( $src && $this->matches_this_domain( $src ) )
445
+ $src = $this->set_preferred_url_scheme( $src );
446
+
447
return $src;
448
}
449
455
*
456
* @since 2.9.0
457
* @since 2.9.3 Now supports 4K.
458
+ * @since 2.9.4 Now converts URL scheme.
459
*
460
* @param int $id The post ID. Required.
461
* @param array $args The image args.
472
$args = $this->reparse_image_args( $args );
473
$args['get_the_real_ID'] = true;
474
475
+ $src = $this->parse_og_image( $image_id, $args, $set_og_dimensions );
476
477
+ if ( $src && $this->matches_this_domain( $src ) )
478
+ $src = $this->set_preferred_url_scheme( $src );
479
+
480
+ return $src;
481
}
482
483
/**
inc/classes/generate-ldjson.class.php CHANGED
@@ -70,6 +70,7 @@ class Generate_Ldjson extends Generate_Image {
70
* May return empty values if data is invalid.
71
*
72
* @since 2.9.3
73
* @see $this->build_json_data()
74
* @uses $this->cache_json_data()
75
*
@@ -94,8 +95,14 @@ class Generate_Ldjson extends Generate_Image {
94
$data = (array) \apply_filters_ref_array( 'the_seo_framework_receive_json_data', array( $data, $key ) );
95
}
96
97
- if ( $encode )
98
- return $data ? (string) json_encode( $data ) : '';
99
100
return $data ?: array();
101
}
@@ -220,12 +227,13 @@ class Generate_Ldjson extends Generate_Image {
220
221
if ( $use_searchbox ) {
222
$action_name = 'search_term_string';
223
/**
224
* Applies filters 'the_seo_framework_ld_json_search_url' : string
225
* @since 2.7.0
226
* @param string $search_url The default WordPress search URL without query parameters.
227
*/
228
- $search_url = (string) \apply_filters( 'the_seo_framework_ld_json_search_url', \get_search_link() );
229
230
$data += array(
231
'potentialAction' => array(
70
* May return empty values if data is invalid.
71
*
72
* @since 2.9.3
73
+ * @since 2.9.4 No longer escapes slashes on PHP 5.4+.
74
* @see $this->build_json_data()
75
* @uses $this->cache_json_data()
76
*
95
$data = (array) \apply_filters_ref_array( 'the_seo_framework_receive_json_data', array( $data, $key ) );
96
}
97
98
+
99
+ if ( $encode ) {
100
+ $options = 0;
101
+ //= PHP 5.4+ ( JSON_UNESCAPED_SLASHES === 64 )
102
+ $options |= defined( 'JSON_UNESCAPED_SLASHES' ) ? JSON_UNESCAPED_SLASHES : 0;
103
+
104
+ return $data ? (string) json_encode( $data, $options ) : '';
105
+ }
106
107
return $data ?: array();
108
}
227
228
if ( $use_searchbox ) {
229
$action_name = 'search_term_string';
230
+ $search_link = $this->pretty_permalinks ? \trailingslashit( \get_search_link() ) : \get_search_link();
231
/**
232
* Applies filters 'the_seo_framework_ld_json_search_url' : string
233
* @since 2.7.0
234
* @param string $search_url The default WordPress search URL without query parameters.
235
*/
236
+ $search_url = (string) \apply_filters( 'the_seo_framework_ld_json_search_url', $search_link );
237
238
$data += array(
239
'potentialAction' => array(
inc/classes/generate-title.class.php CHANGED
@@ -56,15 +56,15 @@ class Generate_Title extends Generate_Description {
56
*
57
* @since 2.4.0:
58
* @param array $args : accepted args : {
59
- * @param int term_id The Taxonomy Term ID when taxonomy is also filled in. Else post ID.
60
- * @param string taxonomy The Taxonomy name.
61
- * @param bool page_on_front Page on front condition for example generation.
62
- * @param bool placeholder Generate placeholder, ignoring options.
63
- * @param bool notagline Generate title without tagline.
64
- * @param bool meta Ignore doing_it_wrong. Used in og:title/twitter:title
65
- * @param bool get_custom_field Do not fetch custom title when false.
66
- * @param bool description_title Fetch title for description.
67
- * @param bool is_front_page Fetch front page title.
68
* }
69
* @return string $title Title
70
*/
@@ -120,7 +120,8 @@ class Generate_Title extends Generate_Description {
120
$this->set_theme_dir_transient( true );
121
122
//* Empty title and rebuild it.
123
- return $this->build_title( $title = '', $seplocation, $args );
124
}
125
126
/**
@@ -151,14 +152,14 @@ class Generate_Title extends Generate_Description {
151
152
/**
153
* Applies filters the_seo_framework_title_args : {
154
- * @param int term_id The Taxonomy Term ID when taxonomy is also filled in. Else post ID.
155
- * @param string taxonomy The Taxonomy name.
156
- * @param bool page_on_front Page on front condition for example generation.
157
- * @param bool notagline Generate title without tagline.
158
- * @param bool meta Ignore doing_it_wrong. Used in og:title/twitter:title
159
- * @param bool get_custom_field Do not fetch custom title when false.
160
- * @param bool description_title Fetch title for description.
161
- * @param bool is_front_page Fetch front page title.
162
* }
163
*
164
* @since 2.5.0
@@ -221,9 +222,9 @@ class Generate_Title extends Generate_Description {
221
* @since 2.4.0
222
*
223
* @param array $args : accepted args : {
224
- * @param int term_id The Taxonomy Term ID
225
- * @param bool placeholder Generate placeholder, ignoring options.
226
- * @param bool page_on_front Page on front condition for example generation
227
* }
228
* @return string Title without tagline.
229
*/
@@ -252,9 +253,9 @@ class Generate_Title extends Generate_Description {
252
* @since 2.6.0
253
*
254
* @param array $args : accepted args : {
255
- * @param int $term_id The Taxonomy Term ID
256
- * @param bool $placeholder Generate placeholder, ignoring options.
257
- * @param bool $page_on_front Page on front condition for example generation
258
* }
259
* @return string Title without tagline.
260
*/
@@ -284,10 +285,10 @@ class Generate_Title extends Generate_Description {
284
* @param string $sep The Title sepeartor
285
* @param string $seplocation The Title sepeartor location ( accepts 'left' or 'right' )
286
* @param array $args : accepted args : {
287
- * @param int term_id The Taxonomy Term ID
288
- * @param string taxonomy The Taxonomy name
289
- * @param bool placeholder Generate placeholder, ignoring options.
290
- * @param bool get_custom_field Do not fetch custom title when false.
291
* }
292
* @return string $title Title
293
*/
@@ -322,8 +323,6 @@ class Generate_Title extends Generate_Description {
322
$seplocation = 'right';
323
}
324
325
- $blogname = $this->get_blogname();
326
-
327
/**
328
* Applies filters 'the_seo_framework_doingitwrong_add_sep' : bool
329
* Determines additions of separator.
@@ -419,12 +418,12 @@ class Generate_Title extends Generate_Description {
419
* @param string $title The Title to return
420
* @param string $seplocation The Title sepeartor location ( accepts 'left' or 'right' )
421
* @param array $args : accepted args : {
422
- * @param int term_id The Taxonomy Term ID
423
- * @param string taxonomy The Taxonomy name
424
- * @param bool page_on_front Page on front condition for example generation
425
- * @param bool placeholder Generate placeholder, ignoring options.
426
- * @param bool get_custom_field Do not fetch custom title when false.
427
- * @param bool is_front_page Fetch front page title.
428
* }
429
* @return string $title Title
430
*/
@@ -558,6 +557,10 @@ class Generate_Title extends Generate_Description {
558
}
559
560
$title = $this->get_the_404_title( $title );
561
$title = $this->get_the_search_title( $title, false );
562
563
//* Fetch the post title if no title is found.
@@ -588,11 +591,11 @@ class Generate_Title extends Generate_Description {
588
* @param bool $escape Parse Title through saninitation calls.
589
* @param bool $get_option Whether to fetch the SEO Settings option.
590
* @return array {
591
- * 'title' => (string) $title : The Generated Title
592
- * 'blogname' => (string) $blogname : The Generated Blogname
593
- * 'add_tagline' => (bool) $add_tagline : Whether to add the tagline
594
- * 'seplocation' => (string) $seplocation : The Separator Location
595
- * }
596
*/
597
public function generate_home_title( $get_custom_field = true, $seplocation = '', $deprecated = '', $escape = true, $get_option = true ) {
598
@@ -874,7 +877,7 @@ class Generate_Title extends Generate_Description {
874
$title = \_x( 'Chats', 'post format archive title', 'autodescription' );
875
}
876
} elseif ( \is_post_type_archive() ) {
877
- $title = \post_type_archive_title( '', false );
878
/* translators: Front-end output. */
879
$title = $use_prefix ? sprintf( __( 'Archives: %s' ), $title ) : $title;
880
} elseif ( isset( $term ) ) {
@@ -1247,8 +1250,29 @@ class Generate_Title extends Generate_Description {
1247
if ( $paged >= 2 || $page >= 2 ) {
1248
$sep = $this->get_title_separator();
1249
1250
- /* translators: Front-end output. */
1251
- $title .= " $sep " . sprintf( __( 'Page %s', 'autodescription' ), max( $paged, $page ) );
1252
}
1253
}
1254
56
*
57
* @since 2.4.0:
58
* @param array $args : accepted args : {
59
+ * @param int term_id The Taxonomy Term ID when taxonomy is also filled in. Else post ID.
60
+ * @param string taxonomy The Taxonomy name.
61
+ * @param bool page_on_front Page on front condition for example generation.
62
+ * @param bool placeholder Generate placeholder, ignoring options.
63
+ * @param bool notagline Generate title without tagline.
64
+ * @param bool meta Ignore doing_it_wrong. Used in og:title/twitter:title
65
+ * @param bool get_custom_field Do not fetch custom title when false.
66
+ * @param bool description_title Fetch title for description.
67
+ * @param bool is_front_page Fetch front page title.
68
* }
69
* @return string $title Title
70
*/
120
$this->set_theme_dir_transient( true );
121
122
//* Empty title and rebuild it.
123
+ $title = '';
124
+ return $this->build_title( $title, $seplocation, $args );
125
}
126
127
/**
152
153
/**
154
* Applies filters the_seo_framework_title_args : {
155
+ * @param int term_id The Taxonomy Term ID when taxonomy is also filled in. Else post ID.
156
+ * @param string taxonomy The Taxonomy name.
157
+ * @param bool page_on_front Page on front condition for example generation.
158
+ * @param bool notagline Generate title without tagline.
159
+ * @param bool meta Ignore doing_it_wrong. Used in og:title/twitter:title
160
+ * @param bool get_custom_field Do not fetch custom title when false.
161
+ * @param bool description_title Fetch title for description.
162
+ * @param bool is_front_page Fetch front page title.
163
* }
164
*
165
* @since 2.5.0
222
* @since 2.4.0
223
*
224
* @param array $args : accepted args : {
225
+ * @param int term_id The Taxonomy Term ID
226
+ * @param bool placeholder Generate placeholder, ignoring options.
227
+ * @param bool page_on_front Page on front condition for example generation
228
* }
229
* @return string Title without tagline.
230
*/
253
* @since 2.6.0
254
*
255
* @param array $args : accepted args : {
256
+ * @param int $term_id The Taxonomy Term ID
257
+ * @param bool $placeholder Generate placeholder, ignoring options.
258
+ * @param bool $page_on_front Page on front condition for example generation
259
* }
260
* @return string Title without tagline.
261
*/
285
* @param string $sep The Title sepeartor
286
* @param string $seplocation The Title sepeartor location ( accepts 'left' or 'right' )
287
* @param array $args : accepted args : {
288
+ * @param int term_id The Taxonomy Term ID
289
+ * @param string taxonomy The Taxonomy name
290
+ * @param bool placeholder Generate placeholder, ignoring options.
291
+ * @param bool get_custom_field Do not fetch custom title when false.
292
* }
293
* @return string $title Title
294
*/
323
$seplocation = 'right';
324
}
325
326
/**
327
* Applies filters 'the_seo_framework_doingitwrong_add_sep' : bool
328
* Determines additions of separator.
418
* @param string $title The Title to return
419
* @param string $seplocation The Title sepeartor location ( accepts 'left' or 'right' )
420
* @param array $args : accepted args : {
421
+ * @param int term_id The Taxonomy Term ID
422
+ * @param string taxonomy The Taxonomy name
423
+ * @param bool page_on_front Page on front condition for example generation
424
+ * @param bool placeholder Generate placeholder, ignoring options.
425
+ * @param bool get_custom_field Do not fetch custom title when false.
426
+ * @param bool is_front_page Fetch front page title.
427
* }
428
* @return string $title Title
429
*/
557
}
558
559
$title = $this->get_the_404_title( $title );
560
+
561
+ /**
562
+ * @since 2.9.4 This no longer affects post filters on admin pages.
563
+ */
564
$title = $this->get_the_search_title( $title, false );
565
566
//* Fetch the post title if no title is found.
591
* @param bool $escape Parse Title through saninitation calls.
592
* @param bool $get_option Whether to fetch the SEO Settings option.
593
* @return array {
594
+ * 'title' => (string) $title : The Generated Title
595
+ * 'blogname' => (string) $blogname : The Generated Blogname
596
+ * 'add_tagline' => (bool) $add_tagline : Whether to add the tagline
597
+ * 'seplocation' => (string) $seplocation : The Separator Location
598
+ * }
599
*/
600
public function generate_home_title( $get_custom_field = true, $seplocation = '', $deprecated = '', $escape = true, $get_option = true ) {
601
877
$title = \_x( 'Chats', 'post format archive title', 'autodescription' );
878
}
879
} elseif ( \is_post_type_archive() ) {
880
+ $title = \post_type_archive_title( '', false ) ?: $this->get_the_term_name( $term, true, false );
881
/* translators: Front-end output. */
882
$title = $use_prefix ? sprintf( __( 'Archives: %s' ), $title ) : $title;
883
} elseif ( isset( $term ) ) {
1250
if ( $paged >= 2 || $page >= 2 ) {
1251
$sep = $this->get_title_separator();
1252
1253
+ $page_number = max( $paged, $page );
1254
+
1255
+ /**
1256
+ * Applies filters 'the_seo_framework_title_pagination' : string
1257
+ *
1258
+ * @since 2.9.4
1259
+ *
1260
+ * @param string $pagination The pagination addition.
1261
+ * @param string $title The old title.
1262
+ * @param int $page_number The page number.
1263
+ * @param string $sep The separator used.
1264
+ */
1265
+ $pagination = \apply_filters_ref_array(
1266
+ 'the_seo_framework_title_pagination',
1267
+ array(
1268
+ /* translators: %d = page number. Front-end output. */
1269
+ " $sep " . sprintf( \__( 'Page %d', 'autodescription' ), $page_number ),
1270
+ $title,
1271
+ $page_number,
1272
+ $sep,
1273
+ )
1274
+ );
1275
+ $title .= $pagination;
1276
}
1277
}
1278
inc/classes/generate-url.class.php CHANGED
@@ -71,16 +71,16 @@ class Generate_Url extends Generate_Title {
71
*
72
* @param string $url the url
73
* @param array $args : accepted args : {
74
- * @param bool $paged Return current page URL without pagination if false
75
- * @param bool $paged_plural Whether to add pagination for the second or later page.
76
- * @param bool $from_option Get the canonical uri option
77
- * @param object $post The Post Object.
78
- * @param bool $external Whether to fetch the current WP Request or get the permalink by Post Object.
79
- * @param bool $is_term Fetch url for term.
80
- * @param object $term The term object.
81
- * @param bool $home Fetch home URL.
82
- * @param bool $forceslash Fetch home URL and slash it, always.
83
- * @param int $id The Page or Term ID.
84
* }
85
* @return string Escape url.
86
*/
@@ -778,15 +778,21 @@ class Generate_Url extends Generate_Title {
778
779
$additions = '';
780
if ( ! empty( $query ) ) {
781
-
782
if ( false !== strpos( $query, '&' ) ) {
783
$query = explode( '&', $query );
784
} else {
785
$query = array( $query );
786
}
787
788
foreach ( $query as $arg ) {
789
- if ( false === strpos( $path, $arg ) )
790
$additions .= '&' . $arg;
791
}
792
}
71
*
72
* @param string $url the url
73
* @param array $args : accepted args : {
74
+ * @param bool $paged Return current page URL without pagination if false
75
+ * @param bool $paged_plural Whether to add pagination for the second or later page.
76
+ * @param bool $from_option Get the canonical uri option
77
+ * @param object $post The Post Object.
78
+ * @param bool $external Whether to fetch the current WP Request or get the permalink by Post Object.
79
+ * @param bool $is_term Fetch url for term.
80
+ * @param object $term The term object.
81
+ * @param bool $home Fetch home URL.
82
+ * @param bool $forceslash Fetch home URL and slash it, always.
83
+ * @param int $id The Page or Term ID.
84
* }
85
* @return string Escape url.
86
*/
778
779
$additions = '';
780
if ( ! empty( $query ) ) {
781
if ( false !== strpos( $query, '&' ) ) {
782
+ //= This can fail on malformed URLs
783
$query = explode( '&', $query );
784
} else {
785
$query = array( $query );
786
}
787
788
foreach ( $query as $arg ) {
789
+ /**
790
+ * @since 2.9.4 Added $args availability check.
791
+ * This is a band-aid, not a fix.
792
+ * @TODO inspect prior explode().
793
+ * @link https://wordpress.org/support/topic/error-when-previewing-a-draft-of-knowledge-base-article/#post-9452791
794
+ */
795
+ if ( $arg && false === strpos( $path, $arg ) )
796
$additions .= '&' . $arg;
797
}
798
}
inc/classes/init.class.php CHANGED
@@ -151,6 +151,9 @@ class Init extends Query {
151
*/
152
public function init_admin_actions() {
153
154
\do_action( 'the_seo_framework_admin_init' );
155
156
//* Initialize caching actions.
@@ -215,6 +218,11 @@ class Init extends Query {
215
// Add extra removable query arguments to the list.
216
\add_filter( 'removable_query_args', array( $this, 'add_removable_query_args' ) );
217
endif;
218
}
219
220
/**
@@ -227,6 +235,9 @@ class Init extends Query {
227
*/
228
protected function init_front_end_actions() {
229
230
\do_action( 'the_seo_framework_front_init' );
231
232
//* Remove canonical header tag from WP
@@ -241,15 +252,6 @@ class Init extends Query {
241
//* Earlier removal of the generator tag. Doesn't require filter.
242
\remove_action( 'wp_head', 'wp_generator' );
243
244
- /**
245
- * @since 2.7.0 Changed priority from 999 to 9999.
246
- * Now uses another method. Was: 'search_filter'.
247
- */
248
- \add_action( 'pre_get_posts', array( $this, 'adjust_search_filter' ), 9999, 1 );
249
-
250
- //* Adjusts archives output based on options.
251
- \add_action( 'pre_get_posts', array( $this, 'adjust_archive_query' ), 9999, 1 );
252
-
253
/**
254
* Outputs sitemap or stylesheet on request.
255
*
@@ -267,6 +269,17 @@ class Init extends Query {
267
268
//* Output meta tags.
269
\add_action( 'wp_head', array( $this, 'html_output' ), 1 );
270
}
271
272
/**
@@ -333,8 +346,8 @@ class Init extends Query {
333
* Applies filters 'the_seo_framework_before_output' : array before functions output
334
* Applies filters 'the_seo_framework_after_output' : array after functions output
335
* @param array $functions {
336
- * 'callback' => string|array The function to call.
337
- * 'args' => scalar|array Arguments. When array, each key is a new argument.
338
* }
339
*/
340
$filter_tag = $before ? 'the_seo_framework_before_output' : 'the_seo_framework_after_output';
@@ -469,7 +482,7 @@ class Init extends Query {
469
. $this->get_plugin_indicator( 'after', $init_start );
470
471
//* Already escaped.
472
- echo "\r\n" . $output . "\r\n";
473
474
\do_action( 'the_seo_framework_do_after_output' );
475
@@ -485,9 +498,10 @@ class Init extends Query {
485
*/
486
public function _init_custom_field_redirect() {
487
488
- if ( $this->is_singular() && $url = $this->get_custom_field( 'redirect' ) )
489
- $this->do_redirect( $url );
490
-
491
}
492
493
/**
@@ -505,6 +519,7 @@ class Init extends Query {
505
return;
506
}
507
508
$url = \esc_url_raw( $url );
509
510
if ( empty( $url ) ) {
@@ -516,7 +531,10 @@ class Init extends Query {
516
517
/**
518
* Applies filters 'the_seo_framework_redirect_status_code' : Absolute integer.
519
* @since 2.8.0
520
*/
521
$redirect_type = \absint( \apply_filters( 'the_seo_framework_redirect_status_code', 301 ) );
522
@@ -524,6 +542,7 @@ class Init extends Query {
524
$this->_doing_it_wrong( __METHOD__, 'You should use 3xx HTTP Status Codes. Recommended 301 and 302.', '2.8.0' );
525
526
if ( false === $allow_external ) {
527
$url = $this->set_url_scheme( $url, 'relative' );
528
$url = $this->add_url_host( $url );
529
$scheme = $this->is_ssl() ? 'https' : 'http';
@@ -627,25 +646,67 @@ class Init extends Query {
627
}
628
629
/**
630
- * Excludes posts from search with certain metadata.
631
- * For now, it only looks at 'exclude_local_search'. If it exists, the post or
632
- * page will be excluded from the local Search Results.
633
*
634
- * @since 2.7.0
635
*
636
- * @param array $query The possible search query.
637
* @return void Early if no search query is found.
638
*/
639
- public function adjust_search_filter( $query ) {
640
641
// Don't exclude pages in wp-admin.
642
- if ( $query->is_search && ! $this->is_admin() ) {
643
-
644
//* Only interact with an actual Search Query.
645
- if ( ! isset( $query->query['s'] ) )
646
return;
647
648
- $meta_query = $query->get( 'meta_query' );
649
650
//* Convert to array. Unset it if it's empty.
651
if ( ! is_array( $meta_query ) )
@@ -659,33 +720,31 @@ class Init extends Query {
659
* of 'compare'. Having no effect whatsoever as it's an exclusion.
660
*/
661
$meta_query[] = array(
662
- array(
663
- 'key' => 'exclude_local_search',
664
- 'type' => 'NUMERIC',
665
- 'compare' => 'NOT EXISTS',
666
- ),
667
);
668
669
- $query->set( 'meta_query', $meta_query );
670
}
671
}
672
673
/**
674
- * Excludes posts from Archive results with certain metadata.
675
- * For now, it only looks at 'exclude_from_archive'. If it exists, the post or
676
- * page will be excluded from the Archive Results.
677
*
678
- * @since 2.9.3
679
*
680
- * @param array $query The possible archive query.
681
- * @return void Early if no archive query is found.
682
*/
683
- public function adjust_archive_query( $query ) {
684
685
- // Don't exclude pages in wp-admin.
686
- if ( ( $query->is_archive || $query->is_home ) && ! $this->is_admin() ) {
687
688
- $meta_query = $query->get( 'meta_query' );
689
690
//* Convert to array. Unset it if it's empty.
691
if ( ! is_array( $meta_query ) )
@@ -699,14 +758,118 @@ class Init extends Query {
699
* of 'compare'. Having no effect whatsoever as it's an exclusion.
700
*/
701
$meta_query[] = array(
702
- array(
703
- 'key' => 'exclude_from_archive',
704
- 'type' => 'NUMERIC',
705
- 'compare' => 'NOT EXISTS',
706
- ),
707
);
708
709
- $query->set( 'meta_query', $meta_query );
710
}
711
}
712
}
151
*/
152
public function init_admin_actions() {
153
154
+ /**
155
+ * @since 2.8.0
156
+ */
157
\do_action( 'the_seo_framework_admin_init' );
158
159
//* Initialize caching actions.
218
// Add extra removable query arguments to the list.
219
\add_filter( 'removable_query_args', array( $this, 'add_removable_query_args' ) );
220
endif;
221
+
222
+ /**
223
+ * @since 2.9.4
224
+ */
225
+ \do_action( 'the_seo_framework_after_admin_init' );
226
}
227
228
/**
235
*/
236
protected function init_front_end_actions() {
237
238
+ /**
239
+ * @since 2.8.0
240
+ */
241
\do_action( 'the_seo_framework_front_init' );
242
243
//* Remove canonical header tag from WP
252
//* Earlier removal of the generator tag. Doesn't require filter.
253
\remove_action( 'wp_head', 'wp_generator' );
254
255
/**
256
* Outputs sitemap or stylesheet on request.
257
*
269
270
//* Output meta tags.
271
\add_action( 'wp_head', array( $this, 'html_output' ), 1 );
272
+
273
+ if ( $this->is_option_checked( 'alter_archive_query' ) )
274
+ $this->init_alter_archive_query();
275
+
276
+ if ( $this->is_option_checked( 'alter_search_query' ) )
277
+ $this->init_alter_search_query();
278
+
279
+ /**
280
+ * @since 2.9.4
281
+ */
282
+ \do_action( 'the_seo_framework_after_front_init' );
283
}
284
285
/**
346
* Applies filters 'the_seo_framework_before_output' : array before functions output
347
* Applies filters 'the_seo_framework_after_output' : array after functions output
348
* @param array $functions {
349
+ * 'callback' => string|array The function to call.
350
+ * 'args' => scalar|array Arguments. When array, each key is a new argument.
351
* }
352
*/
353
$filter_tag = $before ? 'the_seo_framework_before_output' : 'the_seo_framework_after_output';
482
. $this->get_plugin_indicator( 'after', $init_start );
483
484
//* Already escaped.
485
+ echo PHP_EOL . $output . PHP_EOL;
486
487
\do_action( 'the_seo_framework_do_after_output' );
488
498
*/
499
public function _init_custom_field_redirect() {
500
501
+ if ( $this->is_singular() ) {
502
+ $url = $this->get_custom_field( 'redirect' );
503
+ $url && $this->do_redirect( $url );
504
+ }
505
}
506
507
/**
519
return;
520
}
521
522
+ //= All WP defined protocols are allowed.
523
$url = \esc_url_raw( $url );
524
525
if ( empty( $url ) ) {
531
532
/**
533
* Applies filters 'the_seo_framework_redirect_status_code' : Absolute integer.
534
+ *
535
* @since 2.8.0
536
+ *
537
+ * @param unsigned int $redirect_type
538
*/
539
$redirect_type = \absint( \apply_filters( 'the_seo_framework_redirect_status_code', 301 ) );
540
542
$this->_doing_it_wrong( __METHOD__, 'You should use 3xx HTTP Status Codes. Recommended 301 and 302.', '2.8.0' );
543
544
if ( false === $allow_external ) {
545
+ //= Only HTTP/HTTPS and internal URLs are allowed.
546
$url = $this->set_url_scheme( $url, 'relative' );
547
$url = $this->add_url_host( $url );
548
$scheme = $this->is_ssl() ? 'https' : 'http';
646
}
647
648
/**
649
+ * Initializes search query adjustments.
650
*
651
+ * @since 2.9.4
652
+ */
653
+ public function init_alter_search_query() {
654
+
655
+ $type = $this->get_option( 'alter_search_query_type' );
656
+
657
+ switch ( $type ) :
658
+ case 'post_query' :
659
+ \add_filter( 'the_posts', array( $this, '_alter_search_query_post' ), 10, 2 );
660
+ break;
661
+
662
+ default :
663
+ case 'in_query' :
664
+ \add_action( 'pre_get_posts', array( $this, '_alter_search_query_in' ), 9999, 1 );
665
+ break;
666
+ endswitch;
667
+ }
668
+
669
+ /**
670
+ * Initializes archive query adjustments.
671
*
672
+ * @since 2.9.4
673
+ */
674
+ public function init_alter_archive_query() {
675
+
676
+ $type = $this->get_option( 'alter_archive_query_type' );
677
+
678
+ switch ( $type ) :
679
+ case 'post_query' :
680
+ \add_filter( 'the_posts', array( $this, '_alter_archive_query_post' ), 10, 2 );
681
+ break;
682
+
683
+ default :
684
+ case 'in_query' :
685
+ \add_action( 'pre_get_posts', array( $this, '_alter_archive_query_in' ), 9999, 1 );
686
+ break;
687
+ endswitch;
688
+ }
689
+
690
+ /**
691
+ * Alters search query.
692
+ *
693
+ * @since 2.9.4
694
+ *
695
+ * @param WP_Query $wp_query The WP_Query instance.
696
* @return void Early if no search query is found.
697
*/
698
+ public function _alter_search_query_in( $wp_query ) {
699
700
// Don't exclude pages in wp-admin.
701
+ if ( $wp_query->is_search ) {
702
//* Only interact with an actual Search Query.
703
+ if ( ! isset( $wp_query->query['s'] ) )
704
+ return;
705
+
706
+ if ( $this->is_archive_query_adjustment_blocked( $wp_query ) )
707
return;
708
709
+ $meta_query = $wp_query->get( 'meta_query' );
710
711
//* Convert to array. Unset it if it's empty.
712
if ( ! is_array( $meta_query ) )
720
* of 'compare'. Having no effect whatsoever as it's an exclusion.
721
*/
722
$meta_query[] = array(
723
+ 'key' => 'exclude_local_search',
724
+ 'type' => 'NUMERIC',
725
+ 'compare' => 'NOT EXISTS',
726
);
727
728
+ $wp_query->set( 'meta_query', $meta_query );
729
}
730
}
731
732
/**
733
+ * Alters archive query.
734
*
735
+ * @since 2.9.4
736
+ * @access private
737
*
738
+ * @param WP_Query $wp_query The WP_Query instance.
739
+ * @return void Early if query alteration is useless or blocked.
740
*/
741
+ public function _alter_archive_query_in( $wp_query ) {
742
743
+ if ( $wp_query->is_archive || $wp_query->is_home ) {
744
+ if ( $this->is_archive_query_adjustment_blocked( $wp_query ) )
745
+ return;
746
747
+ $meta_query = $wp_query->get( 'meta_query' );
748
749
//* Convert to array. Unset it if it's empty.
750
if ( ! is_array( $meta_query ) )
758
* of 'compare'. Having no effect whatsoever as it's an exclusion.
759
*/
760
$meta_query[] = array(
761
+ 'key' => 'exclude_from_archive',
762
+ 'type' => 'NUMERIC',
763
+ 'compare' => 'NOT EXISTS',
764
);
765
766
+ $wp_query->set( 'meta_query', $meta_query );
767
}
768
+
769
+ /* @TODO exchange above with this 3.0+
770
+ if ( ! empty( $wp_query->is_archive ) || ! empty( $wp_query->is_home ) ) {
771
+
772
+ $excluded = $this->get_exclude_from_archive_ids_cache();
773
+
774
+ if ( ! $excluded )
775
+ return;
776
+
777
+ $post__not_in = $wp_query->get( 'post__not_in' );
778
+
779
+ if ( ! empty( $post__not_in ) ) {
780
+ $excluded = array_merge( (array) $post__not_in, $excluded );
781
+ $excluded = array_unique( $excluded );
782
+ }
783
+
784
+ $wp_query->set( 'post__not_in', $excluded );
785
+ }
786
+ */
787
+ }
788
+
789
+ /**
790
+ * Alters search results after database query.
791
+ *
792
+ * @since 2.9.4
793
+ * @access private
794
+ *
795
+ * @param array $posts The array of retrieved posts.
796
+ * @param WP_Query $wp_query The WP_Query instance.
797
+ * @return array $posts
798
+ */
799
+ public function _alter_search_query_post( $posts, $wp_query ) {
800
+
801
+ if ( $wp_query->is_search ) {
802
+ if ( $this->is_archive_query_adjustment_blocked( $wp_query ) )
803
+ return $posts;
804
+
805
+ foreach ( $posts as $n => $post ) {
806
+ if ( $this->get_custom_field( 'exclude_local_search', $post->ID ) ) {
807
+ unset( $posts[ $n ] );
808
+ }
809
+ }
810
+ //= Reset numeric index.
811
+ $posts = array_values( $posts );
812
+ }
813
+
814
+ return $posts;
815
+ }
816
+
817
+ /**
818
+ * Alters archive results after database query.
819
+ *
820
+ * @since 2.9.4
821
+ * @access private
822
+ *
823
+ * @param array $posts The array of retrieved posts.
824
+ * @param WP_Query $wp_query The WP_Query instance.
825
+ * @return array $posts
826
+ */
827
+ public function _alter_archive_query_post( $posts, $wp_query ) {
828
+
829
+ if ( $wp_query->is_archive || $wp_query->is_home ) {
830
+ if ( $this->is_archive_query_adjustment_blocked( $wp_query ) )
831
+ return $posts;
832
+
833
+ foreach ( $posts as $n => $post ) {
834
+ if ( $this->get_custom_field( 'exclude_from_archive', $post->ID ) ) {
835
+ unset( $posts[ $n ] );
836
+ }
837
+ }
838
+ //= Reset numeric index.
839
+ $posts = array_values( $posts );
840
+ }
841
+
842
+ return $posts;
843
+ }
844
+
845
+ /**
846
+ * Determines whether the archive query adjustment is blocked.
847
+ *
848
+ * @since 2.9.4
849
+ *
850
+ * @param WP_Query $wp_query WP_Query object. Passed by reference.
851
+ * @return bool
852
+ */
853
+ protected function is_archive_query_adjustment_blocked( &$wp_query ) {
854
+
855
+ static $has_filter = null;
856
+
857
+ if ( null === $has_filter ) {
858
+ $has_filter = \has_filter( 'the_seo_framework_do_adjust_archive_query' );
859
+ }
860
+ if ( $has_filter ) {
861
+ /**
862
+ * Applies filters 'the_seo_framework_do_adjust_archive_query' : boolean
863
+ *
864
+ * @since 2.9.4
865
+ *
866
+ * @param bool $do Whether to execute adjustment.
867
+ * @param object $wp_query The current query. Passed by reference.
868
+ */
869
+ if ( ! \apply_filters_ref_array( 'the_seo_framework_do_adjust_archive_query', array( true, &$wp_query ) ) )
870
+ return true;
871
+ }
872
+
873
+ return false;
874
}
875
}
inc/classes/inpost.class.php CHANGED
@@ -71,10 +71,14 @@ class Inpost extends Doing_It_Right {
71
/**
72
* Applies filters bool|string the_seo_framework_inpost_seo_bar :
73
* Whether to output the SEO bar within the inpost SEO Settings metabox.
74
- * @param : string 'above' Outputs it above the Settings
75
- * : string 'below' Outputs it below the Settings
76
- * : bool false No output.
77
* @since 2.5.2
78
*/
79
$this->inpost_seo_bar = \apply_filters( 'the_seo_framework_inpost_seo_bar', false );
80
@@ -88,13 +92,13 @@ class Inpost extends Doing_It_Right {
88
*
89
* @param string $id The Nav Tab ID
90
* @param array $tabs the tab content {
91
- * $tabs = tab ID key = array(
92
- * $tabs['name'] => tab name
93
- * $tabs['callback'] => string|array callback function
94
- * $tabs['dashicon'] => string Dashicon
95
- * $tabs['args'] => mixed optional callback function args
96
- * )
97
- * }
98
* @param string $version the The SEO Framework version for debugging. May be emptied.
99
* @param bool $use_tabs Whether to output tabs, only works when $tabs is greater than 1.
100
*/
@@ -125,9 +129,9 @@ class Inpost extends Doing_It_Right {
125
$input_id = \esc_attr( 'tsf-flex-' . $id . '-tab-' . $tab );
126
$input_name = \esc_attr( 'tsf-flex-' . $id . '-tabs' );
127
128
- //* All output below is escaped.
129
?>
130
- <div class="tsf-flex tsf-flex-nav-tab tsf-flex<?php echo $wrapper_active ?>" id="<?php echo $wrapper_id ?>">
131
<input type="radio" class="tsf-flex-nav-tab-radio" id="<?php echo $input_id; ?>" name="<?php echo $input_name; ?>" <?php echo $input_checked; ?>>
132
<label for="<?php echo $input_id; ?>" class="tsf-flex tsf-flex-nav-tab-label">
133
<?php
@@ -299,6 +303,7 @@ class Inpost extends Doing_It_Right {
299
*/
300
$priority = (string) \apply_filters( 'the_seo_framework_metabox_priority', 'high' );
301
302
\add_meta_box( $id, sprintf( \__( '%s SEO Settings', 'autodescription' ), $title ), array( $this, 'pre_seo_box' ), $post_type, $context, $priority, $args );
303
endif;
304
endif;
@@ -310,8 +315,8 @@ class Inpost extends Doing_It_Right {
310
* @since 2.1.8
311
* @access private
312
*
313
- * @param $object the page/post/taxonomy object
314
- * @param $args the page/post arguments or taxonomy slug.
315
* @return string Inpost SEO box.
316
*/
317
public function pre_seo_box( $object, $args ) {
@@ -327,8 +332,7 @@ class Inpost extends Doing_It_Right {
327
return $this->inpost_seo_box( $object, (array) $args );
328
}
329
} else {
330
- //* Empty the arguments, if any.
331
- return $this->inpost_seo_box( $object, $args = '' );
332
}
333
334
return '';
@@ -341,8 +345,8 @@ class Inpost extends Doing_It_Right {
341
* @access private
342
* @uses $this->get_custom_field() Get custom field value.
343
*
344
- * @param object $object the page/post/taxonomy object
345
- * @param array $args the page/post arguments or taxonomy slug
346
*/
347
public function inpost_seo_box( $object, $args ) {
348
@@ -475,11 +479,6 @@ class Inpost extends Doing_It_Right {
475
* Placeholder method that's used prior to upgrade merge 2.9 -> 3.0+.
476
* Do not use. It will take a little too much time to perfect this.
477
*
478
- * Will anyone even notice this?
479
- * If so: Hi there, do not forget to smile!
480
- * Do send me an email @ sybre at theseoframework.com.
481
- * Subject: CAUGHT! Content: Hi Sybre :D, noob.
482
- *
483
* @since 2.9.0
484
* @access private
485
* @ignore
71
/**
72
* Applies filters bool|string the_seo_framework_inpost_seo_bar :
73
* Whether to output the SEO bar within the inpost SEO Settings metabox.
74
+ *
75
* @since 2.5.2
76
+ *
77
+ * @param $inpost_seo_bar : {
78
+ * string 'above' : Outputs it above the Settings
79
+ * string 'below' : Outputs it below the Settings
80
+ * bool false : No output.
81
+ * }
82
*/
83
$this->inpost_seo_bar = \apply_filters( 'the_seo_framework_inpost_seo_bar', false );
84
92
*
93
* @param string $id The Nav Tab ID
94
* @param array $tabs the tab content {
95
+ * $tabs = tab ID key = array(
96
+ * $tabs['name'] => tab name
97
+ * $tabs['callback'] => string|array callback function
98
+ * $tabs['dashicon'] => string Dashicon
99
+ * $tabs['args'] => mixed optional callback function args
100
+ * )
101
+ * }
102
* @param string $version the The SEO Framework version for debugging. May be emptied.
103
* @param bool $use_tabs Whether to output tabs, only works when $tabs is greater than 1.
104
*/
129
$input_id = \esc_attr( 'tsf-flex-' . $id . '-tab-' . $tab );
130
$input_name = \esc_attr( 'tsf-flex-' . $id . '-tabs' );
131
132
+ //= All output below is escaped.
133
?>
134
+ <div class="tsf-flex tsf-flex-nav-tab tsf-flex<?php echo $wrapper_active; ?>" id="<?php echo $wrapper_id; ?>">
135
<input type="radio" class="tsf-flex-nav-tab-radio" id="<?php echo $input_id; ?>" name="<?php echo $input_name; ?>" <?php echo $input_checked; ?>>
136
<label for="<?php echo $input_id; ?>" class="tsf-flex tsf-flex-nav-tab-label">
137
<?php
303
*/
304
$priority = (string) \apply_filters( 'the_seo_framework_metabox_priority', 'high' );
305
306
+ /* translators: %s = Post type name */
307
\add_meta_box( $id, sprintf( \__( '%s SEO Settings', 'autodescription' ), $title ), array( $this, 'pre_seo_box' ), $post_type, $context, $priority, $args );
308
endif;
309
endif;
315
* @since 2.1.8
316
* @access private
317
*
318
+ * @param object $object the page/post/taxonomy object
319
+ * @param array $args the page/post arguments or taxonomy slug.
320
* @return string Inpost SEO box.
321
*/
322
public function pre_seo_box( $object, $args ) {
332
return $this->inpost_seo_box( $object, (array) $args );
333
}
334
} else {
335
+ return $this->inpost_seo_box( $object, '' );
336
}
337
338
return '';
345
* @access private
346
* @uses $this->get_custom_field() Get custom field value.
347
*
348
+ * @param object $object The page/post/taxonomy object
349
+ * @param array $args The page/post arguments or taxonomy slug
350
*/
351
public function inpost_seo_box( $object, $args ) {
352
479
* Placeholder method that's used prior to upgrade merge 2.9 -> 3.0+.
480
* Do not use. It will take a little too much time to perfect this.
481
*
482
* @since 2.9.0
483
* @access private
484
* @ignore
inc/classes/post-data.class.php CHANGED
@@ -48,8 +48,8 @@ class Post_Data extends Detect {
48
* @since 2.0.0
49
* @staticvar array $field_cache
50
*
51
- * @param string $field Custom field key.
52
- * @param int $post_id The post ID
53
* @return string|boolean Return value or false on failure.
54
*/
55
public function get_custom_field( $field, $post_id = null ) {
48
* @since 2.0.0
49
* @staticvar array $field_cache
50
*
51
+ * @param string $field Custom field key.
52
+ * @param int $post_id The post ID
53
* @return string|boolean Return value or false on failure.
54
*/
55
public function get_custom_field( $field, $post_id = null ) {
inc/classes/query.class.php CHANGED
@@ -713,19 +713,19 @@ class Query extends Compat {
713
}
714
715
/**
716
- * Detects preview.
717
*
718
* @since 2.6.0
719
- * @staticvar bool $cache
720
*
721
* @return bool
722
*/
723
public function is_search() {
724
- return \is_search();
725
}
726
727
/**
728
- * Detects posts.
729
* When $post is supplied, it will check against the current object. So it will not work in the admin screens.
730
*
731
* @since 2.6.0
713
}
714
715
/**
716
+ * Detects search.
717
*
718
* @since 2.6.0
719
+ * @since 2.9.4 Now always returns false in admin.
720
*
721
* @return bool
722
*/
723
public function is_search() {
724
+ return \is_search() && ! is_admin();
725
}
726
727
/**
728
+ * Detects single post pages.
729
* When $post is supplied, it will check against the current object. So it will not work in the admin screens.
730
*
731
* @since 2.6.0
inc/classes/sanitize.class.php CHANGED
@@ -181,10 +181,22 @@ class Sanitize extends Admin_Pages {
181
)
182
);
183
184
$this->add_option_filter(
185
's_one_zero',
186
$this->settings_field,
187
array(
188
'cache_meta_description',
189
'cache_meta_schema',
190
'cache_sitemap',
@@ -535,6 +547,7 @@ class Sanitize extends Admin_Pages {
535
's_title' => array( $this, 's_title' ),
536
's_title_raw' => array( $this, 's_title_raw' ),
537
's_knowledge_type' => array( $this, 's_knowledge_type' ),
538
's_one_zero' => array( $this, 's_one_zero' ),
539
's_no_html' => array( $this, 's_no_html' ),
540
's_no_html_space' => array( $this, 's_no_html_space' ),
@@ -702,6 +715,7 @@ class Sanitize extends Admin_Pages {
702
* Removes duplicated spaces from the input value.
703
*
704
* @since 2.8.2
705
* @see $this->s_nsbp() For converting other spaces prior to using this method.
706
*
707
* @param string $new_value The input value with possible multispaces.
@@ -714,7 +728,7 @@ class Sanitize extends Admin_Pages {
714
do {
715
$new_value = str_replace( ' ', ' ', $new_value );
716
$i++;
717
- } while ( $i <= 2 && strpos( $new_value, ' ' ) );
718
719
return $new_value;
720
}
@@ -901,6 +915,26 @@ class Sanitize extends Admin_Pages {
901
return (string) $previous;
902
}
903
904
/**
905
* Returns a 1 or 0, for all truthy / falsy values.
906
*
181
)
182
);
183
184
+ $this->add_option_filter(
185
+ 's_alter_query_type',
186
+ $this->settings_field,
187
+ array(
188
+ 'alter_archive_query_type',
189
+ 'alter_search_query_type',
190
+ )
191
+ );
192
+
193
$this->add_option_filter(
194
's_one_zero',
195
$this->settings_field,
196
array(
197
+ 'alter_search_query',
198
+ 'alter_archive_query',
199
+
200
'cache_meta_description',
201
'cache_meta_schema',
202
'cache_sitemap',
547
's_title' => array( $this, 's_title' ),
548
's_title_raw' => array( $this, 's_title_raw' ),
549
's_knowledge_type' => array( $this, 's_knowledge_type' ),
550
+ 's_alter_query_type' => array( $this, 's_alter_query_type' ),
551
's_one_zero' => array( $this, 's_one_zero' ),
552
's_no_html' => array( $this, 's_no_html' ),
553
's_no_html_space' => array( $this, 's_no_html_space' ),
715
* Removes duplicated spaces from the input value.
716
*
717
* @since 2.8.2
718
+ * @since 2.9.4 Now no longer fails when first two characters are spaces.
719
* @see $this->s_nsbp() For converting other spaces prior to using this method.
720
*
721
* @param string $new_value The input value with possible multispaces.
728
do {
729
$new_value = str_replace( ' ', ' ', $new_value );
730
$i++;
731
+ } while ( $i <= 2 && false !== strpos( $new_value, ' ' ) );
732
733
return $new_value;
734
}
915
return (string) $previous;
916
}
917
918
+ /**
919
+ * Sanitizes alter query type.
920
+ *
921
+ * @since 2.9.4
922
+ *
923
+ * @param mixed $new_value Should ideally be a string 'in_query' or 'post_query' passed in.
924
+ * @return string 'in_query' or 'post_query'
925
+ */
926
+ public function s_alter_query_type( $new_value ) {
927
+
928
+ switch ( $new_value ) {
929
+ case 'in_query' :
930
+ case 'post_query' :
931
+ return (string) $new_value;
932
+
933
+ default :
934
+ return 'in_query';
935
+ }
936
+ }
937
+
938
/**
939
* Returns a 1 or 0, for all truthy / falsy values.
940
*
inc/classes/site-options.class.php CHANGED
@@ -105,6 +105,12 @@ class Site_Options extends Sanitize {
105
*/
106
return array(
107
// General. Performance.
108
'cache_meta_description' => 0, // Description transient cache.
109
'cache_meta_schema' => 0, // Schema.org transient cache.
110
'cache_sitemap' => 1, // Sitemap transient cache.
105
*/
106
return array(
107
// General. Performance.
108
+ 'alter_search_query' => 1, // Search query adjustments.
109
+ 'alter_archive_query' => 1, // Archive query adjustments.
110
+
111
+ 'alter_archive_query_type' => 'in_query', // Archive query type.
112
+ 'alter_search_query_type' => 'in_query', // Search query type.
113
+
114
'cache_meta_description' => 0, // Description transient cache.
115
'cache_meta_schema' => 0, // Schema.org transient cache.
116
'cache_sitemap' => 1, // Sitemap transient cache.
inc/classes/sitemaps.class.php CHANGED
@@ -917,7 +917,7 @@ class Sitemaps extends Metaboxes {
917
);
918
919
/**
920
- * Applies filters 'the_seo_framework_sitemap_posts_query_args' : array
921
*
922
* @since 2.8.0
923
*
917
);
918
919
/**
920
+ * Applies filters 'the_seo_framework_sitemap_cpt_query_args' : array
921
*
922
* @since 2.8.0
923
*
inc/classes/term-data.class.php CHANGED
@@ -286,6 +286,7 @@ class Term_Data extends Post_Data {
286
* Get the current screen term labels.
287
*
288
* @since 2.6.0
289
* @staticvar string $term_name : Caution: This function only runs once per screen and doesn't check the term type more than once.
290
*
291
* @param object $term The Taxonomy Term object.
@@ -324,6 +325,10 @@ class Term_Data extends Post_Data {
324
if ( isset( $term_labels->name ) )
325
return $term_name[ $singular ] = $term_labels[ $tax_type ]->name;
326
}
327
}
328
329
if ( $fallback ) {
286
* Get the current screen term labels.
287
*
288
* @since 2.6.0
289
+ * @since 2.9.4 Added $term->label and $term->labels->singular_name as additional fallbacks.
290
* @staticvar string $term_name : Caution: This function only runs once per screen and doesn't check the term type more than once.
291
*
292
* @param object $term The Taxonomy Term object.
325
if ( isset( $term_labels->name ) )
326
return $term_name[ $singular ] = $term_labels[ $tax_type ]->name;
327
}
328
+ } elseif ( isset( $term->label ) ) {
329
+ return $term->label;
330
+ } elseif ( isset( $term->labels->singular_name ) ) {
331
+ return $term->labels->singular_name;
332
}
333
334
if ( $fallback ) {
inc/compat/plugin-qtranslatex.php CHANGED
@@ -69,7 +69,7 @@ function _qtranslate_get_relative_url( $path = '', $post_id = '' ) {
69
* Path must have trailing slash for pagination permalinks to work.
70
* So we remove the query string and add it back with slash.
71
*/
72
- if ( strpos( $path, '?lang=' . $current_lang ) !== false )
73
$path = str_replace( '?lang=' . $current_lang, '', $path );
74
75
return \user_trailingslashit( $path ) . '?lang=' . $current_lang;
69
* Path must have trailing slash for pagination permalinks to work.
70
* So we remove the query string and add it back with slash.
71
*/
72
+ if ( false !== strpos( $path, '?lang=' . $current_lang ) )
73
$path = str_replace( '?lang=' . $current_lang, '', $path );
74
75
return \user_trailingslashit( $path ) . '?lang=' . $current_lang;
inc/functions/plugin-test-server.php CHANGED
@@ -32,12 +32,42 @@ the_seo_framework_test_server_phase();
32
* Tests plugin upgrade.
33
*
34
* @since 2.8.0
35
* @access private
36
* @link http://php.net/eol.php
37
* @link https://codex.wordpress.org/WordPress_Versions
38
*/
39
function the_seo_framework_test_server_phase() {
40
41
$requirements = array(
42
'php' => '50300',
43
'wp' => '35700',
@@ -49,11 +79,11 @@ function the_seo_framework_test_server_phase() {
49
50
//* All good.
51
if ( true === $test ) {
52
- update_site_option( 'the_seo_framework_tested_upgrade_version', THE_SEO_FRAMEWORK_DB_VERSION );
53
return;
54
}
55
56
- if ( is_multisite() ) {
57
$plugins = get_site_option( 'active_sitewide_plugins' );
58
$network_mode = isset( $plugins[ THE_SEO_FRAMEWORK_PLUGIN_BASENAME ] );
59
} else {
32
* Tests plugin upgrade.
33
*
34
* @since 2.8.0
35
+ * @since 2.9.4 Changed the testing option from a site option to a blog option.
36
* @access private
37
* @link http://php.net/eol.php
38
* @link https://codex.wordpress.org/WordPress_Versions
39
*/
40
function the_seo_framework_test_server_phase() {
41
42
+ $ms = is_multisite();
43
+
44
+ //* @TODO clean this up @ 4.6 requirement. i.e. only check for `get_network()` and $nw->site_id.
45
+ //= WP_Network is WP > 4.4.
46
+ if ( $ms && class_exists( '\\WP_Network', false ) ) {
47
+ //* Try bypassing testing and deactivation gaming when the main blog has already been tested.
48
+
49
+ /**
50
+ * @since 2.9.4
51
+ * Delete old and redundant network option.
52
+ */
53
+ delete_site_option( 'the_seo_framework_tested_upgrade_version' );
54
+
55
+ //= WP < 4.6 doesn't have get_network().
56
+ $nw = function_exists( 'get_network' ) ? get_network() : $GLOBALS['current_site'];
57
+ if ( $nw instanceof \WP_Network ) {
58
+ //= WP < 4.6 doesn't have property 'site_id'.
59
+ $site_id = isset( $nw->site_id ) ? $nw->site_id : (int) $nw->blog_id;
60
+
61
+ //= Free memory. Var is not passed by reference, so it's safe.
62
+ unset( $nw );
63
+
64
+ if ( get_blog_option( $site_id, 'the_seo_framework_tested_upgrade_version' ) ) {
65
+ update_option( 'the_seo_framework_tested_upgrade_version', THE_SEO_FRAMEWORK_DB_VERSION );
66
+ return;
67
+ }
68
+ }
69
+ }
70
+
71
$requirements = array(
72
'php' => '50300',
73
'wp' => '35700',
79
80
//* All good.
81
if ( true === $test ) {
82
+ update_option( 'the_seo_framework_tested_upgrade_version', THE_SEO_FRAMEWORK_DB_VERSION );
83
return;
84
}
85
86
+ if ( $ms ) {
87
$plugins = get_site_option( 'active_sitewide_plugins' );
88
$network_mode = isset( $plugins[ THE_SEO_FRAMEWORK_PLUGIN_BASENAME ] );
89
} else {
inc/functions/upgrade.php CHANGED
@@ -37,6 +37,7 @@ add_action( 'admin_init', 'the_seo_framework_do_upgrade', 20 );
37
* Only works on WordPress 4.4 and later to ensure and force maximum compatibility.
38
*
39
* @since 2.7.0
40
*
41
* @thanks StudioPress for some code.
42
*/
@@ -45,9 +46,6 @@ function the_seo_framework_do_upgrade() {
45
if ( get_option( 'the_seo_framework_upgraded_db_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
46
return;
47
48
- if ( ! the_seo_framework()->wp_version( '4.4', '>=' ) )
49
- return;
50
-
51
//* If the WordPress Database hasn't been upgraded yet, make the user upgrade first.
52
if ( (int) get_option( 'db_version' ) !== (int) $GLOBALS['wp_db_version'] ) {
53
wp_safe_redirect( admin_url( 'upgrade.php?_wp_http_referer=' . rawurlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
@@ -66,7 +64,6 @@ function the_seo_framework_do_upgrade() {
66
do_action( 'the_seo_framework_upgraded' );
67
}
68
69
-
70
add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_to_current' );
71
/**
72
* Upgrades the Database version to the latest version.
@@ -149,7 +146,6 @@ function the_seo_framework_do_upgrade_2802() {
149
update_option( 'the_seo_framework_upgraded_db_version', '2802' );
150
}
151
152
-
153
/**
154
* Updates Twitter 'photo' card option to 'summary_large_image'.
155
* Invalidates object cache if changed.
37
* Only works on WordPress 4.4 and later to ensure and force maximum compatibility.
38
*
39
* @since 2.7.0
40
+ * @since 2.9.4 No longer tests WP version. This file won't be loaded anyway if rendered incompatible.
41
*
42
* @thanks StudioPress for some code.
43
*/
46
if ( get_option( 'the_seo_framework_upgraded_db_version' ) >= THE_SEO_FRAMEWORK_DB_VERSION )
47
return;
48
49
//* If the WordPress Database hasn't been upgraded yet, make the user upgrade first.
50
if ( (int) get_option( 'db_version' ) !== (int) $GLOBALS['wp_db_version'] ) {
51
wp_safe_redirect( admin_url( 'upgrade.php?_wp_http_referer=' . rawurlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
64
do_action( 'the_seo_framework_upgraded' );
65
}
66
67
add_action( 'the_seo_framework_upgraded', 'the_seo_framework_upgrade_to_current' );
68
/**
69
* Upgrades the Database version to the latest version.
146
update_option( 'the_seo_framework_upgraded_db_version', '2802' );
147
}
148
149
/**
150
* Updates Twitter 'photo' card option to 'summary_large_image'.
151
* Invalidates object cache if changed.
inc/views/inpost/seo-settings-singular.php CHANGED
@@ -22,13 +22,15 @@ switch ( $instance ) :
22
* @see $this->call_function()
23
* @see PHP call_user_func_array() For args.
24
*
25
- * @param array $default_tabs { 'id' = The identifier =>
26
- * array(
27
- * 'name' => The name
28
- * 'callback' => The callback function, use array for method calling
29
- * 'dashicon' => Desired dashicon
30
- * 'args' => Callback parameters
31
- * )
32
* }
33
*/
34
$default_tabs = array(
@@ -70,7 +72,6 @@ switch ( $instance ) :
70
break;
71
72
case 'inpost_general' :
73
-
74
//* Temporarily. TODO refactor.
75
$tit_len_parsed = $desc_len_parsed = 0;
76
$doctitle_placeholder = $description_placeholder = '';
@@ -101,11 +102,29 @@ switch ( $instance ) :
101
<div class="tsf-flex-setting-label tsf-flex">
102
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
103
<label for="autodescription_title" class="tsf-flex-setting-label-item tsf-flex">
104
- <div><strong><?php printf( esc_html__( 'Custom %s Title', 'autodescription' ), esc_html( $type ) ); ?></strong></div>
105
- <div><?php $this->make_info( __( 'Recommended Length: 50 to 55 characters', 'autodescription' ), 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#3' ); ?></div>
106
</label>
107
<span class="description tsf-counter">
108
- <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription_title_chars">' . (int) mb_strlen( $tit_len_parsed ) . '</span>' ); ?>
109
<span class="hide-if-no-js tsf-ajax"></span>
110
</span>
111
</div>
@@ -123,11 +142,22 @@ switch ( $instance ) :
123
<div class="tsf-flex-setting-label tsf-flex">
124
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
125
<label for="autodescription_description" class="tsf-flex-setting-label-item tsf-flex">
126
- <div><strong><?php printf( esc_html__( 'Custom %s Description', 'autodescription' ), esc_html( $type ) ); ?></strong></div>
127
<div><?php $this->make_info( __( 'Recommended Length: 145 to 155 characters', 'autodescription' ), 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#1' ); ?></div>
128
</label>
129
<span class="description tsf-counter">
130
- <?php printf( esc_html__( 'Characters Used: %s', 'autodescription' ), '<span id="autodescription_description_chars">' . (int) mb_strlen( $desc_len_parsed ) . '</span>' ); ?>
131
<span class="hide-if-no-js tsf-ajax"></span>
132
</span>
133
</div>
@@ -151,7 +181,18 @@ switch ( $instance ) :
151
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
152
<label for="autodescription_canonical" class="tsf-flex-setting-label-item tsf-flex">
153
<div><strong><?php esc_html_e( 'Custom Canonical URL', 'autodescription' ); ?></strong></div>
154
- <div><?php $this->make_info( sprintf( __( 'Preferred %s URL location', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/139066?hl=' . $language ); ?></div>
155
</label>
156
</div>
157
</div>
@@ -172,12 +213,18 @@ switch ( $instance ) :
172
<div class="tsf-checkbox-wrapper">
173
<label for="autodescription_noindex">
174
<input type="checkbox" name="autodescription[_genesis_noindex]" id="autodescription_noindex" value="1" <?php checked( $this->get_custom_field( '_genesis_noindex' ) ); ?> />
175
- <?php
176
/* translators: 1: Option, 2: Post or Page */
177
printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noindex' ), esc_html( $type ) );
178
echo ' ';
179
- $this->make_info( sprintf( __( 'Tell Search Engines not to show this %s in their search results', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/93710?hl=' . $language );
180
- ?>
181
</label>
182
</div>
183
<div class="tsf-checkbox-wrapper">
@@ -194,8 +241,13 @@ switch ( $instance ) :
194
<label for="autodescription_noarchive"><input type="checkbox" name="autodescription[_genesis_noarchive]" id="autodescription_noarchive" value="1" <?php checked( $this->get_custom_field( '_genesis_noarchive' ) ); ?> />
195
<?php
196
/* translators: 1: Option, 2: Post or Page */
197
- printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noarchive' ), esc_html( $type ) );
198
echo ' ';
199
$this->make_info( sprintf( __( 'Tell Search Engines not to save a cached copy of this %s', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/79812?hl=' . $language );
200
?>
201
</label>
@@ -203,6 +255,12 @@ switch ( $instance ) :
203
</div>
204
</div>
205
206
<div class="tsf-flex-setting tsf-flex">
207
<div class="tsf-flex-setting-label tsf-flex">
208
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
@@ -212,21 +270,27 @@ switch ( $instance ) :
212
</div>
213
</div>
214
<div class="tsf-flex-setting-input tsf-flex">
215
<div class="tsf-checkbox-wrapper">
216
<label for="autodescription_exclude_local_search"><input type="checkbox" name="autodescription[exclude_local_search]" id="autodescription_exclude_local_search" value="1" <?php checked( $this->get_custom_field( 'exclude_local_search' ) ); ?> />
217
<?php
218
printf( esc_html__( 'Exclude this %s from local search', 'autodescription' ), esc_html( $type ) );
219
echo ' ';
220
$this->make_info( sprintf( __( 'This excludes this %s from local on-site search results', 'autodescription' ), $type ) );
221
?>
222
</label>
223
</div>
224
- <?php if ( $this->post_type_supports_taxonomies() ) : ?>
225
<div class="tsf-checkbox-wrapper">
226
<label for="autodescription_exclude_from_archive"><input type="checkbox" name="autodescription[exclude_from_archive]" id="autodescription_exclude_from_archive" value="1" <?php checked( $this->get_custom_field( 'exclude_from_archive' ) ); ?> />
227
<?php
228
- printf( esc_html__( 'Exclude this %s from archive listing', 'autodescription' ), esc_html( $type ) );
229
echo ' ';
230
$this->make_info( sprintf( __( 'This excludes this %s from on-site archive pages', 'autodescription' ), $type ) );
231
?>
232
</label>
@@ -234,6 +298,7 @@ switch ( $instance ) :
234
<?php endif; ?>
235
</div>
236
</div>
237
238
<div class="tsf-flex-setting tsf-flex">
239
<div class="tsf-flex-setting-label tsf-flex">
@@ -244,7 +309,10 @@ switch ( $instance ) :
244
</div>
245
<div>
246
<?php
247
- $this->make_info( __( 'This will force visitors to go to another URL', 'autodescription' ), 'https://support.google.com/webmasters/answer/93633?hl=' . $language );
248
?>
249
</div>
250
</label>
@@ -258,7 +326,6 @@ switch ( $instance ) :
258
break;
259
260
case 'inpost_social' :
261
-
262
//* Fetch image placeholder.
263
$image_placeholder = $this->get_social_image( array( 'post_id' => $post_id, 'disallowed' => array( 'postmeta' ), 'escape' => false ) );
264
@@ -268,7 +335,18 @@ switch ( $instance ) :
268
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
269
<label for="autodescription_socialimage-url" class="tsf-flex-setting-label-item tsf-flex">
270
<div><strong><?php esc_html_e( 'Custom Social Image URL', 'autodescription' ); ?></strong></div>
271
- <div><?php $this->make_info( sprintf( __( 'Preferred %s Social Image URL location', 'autodescription' ), esc_attr( $type ) ), 'https://developers.facebook.com/docs/sharing/best-practices#images' ); ?></div>
272
</label>
273
</div>
274
</div>
@@ -276,7 +354,7 @@ switch ( $instance ) :
276
<input class="large-text" type="text" name="autodescription[_social_image_url]" id="autodescription_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_custom_field( '_social_image_url' ) ); ?>" />
277
<div class="hide-if-no-js tsf-social-image-buttons">
278
<?php
279
- //* Already escaped.
280
echo $this->get_social_image_uploader_form( 'autodescription_socialimage' );
281
?>
282
</div>
22
* @see $this->call_function()
23
* @see PHP call_user_func_array() For args.
24
*
25
+ * @param array $default_tabs {
26
+ * 'id' = The identifier => {
27
+ * array(
28
+ * 'name' => The name
29
+ * 'callback' => The callback function, use array for method calling
30
+ * 'dashicon' => Desired dashicon
31
+ * 'args' => Callback parameters
32
+ * )
33
+ * }
34
* }
35
*/
36
$default_tabs = array(
72
break;
73
74
case 'inpost_general' :
75
//* Temporarily. TODO refactor.
76
$tit_len_parsed = $desc_len_parsed = 0;
77
$doctitle_placeholder = $description_placeholder = '';
102
<div class="tsf-flex-setting-label tsf-flex">
103
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
104
<label for="autodescription_title" class="tsf-flex-setting-label-item tsf-flex">
105
+ <div><strong>
106
+ <?php
107
+ /* translators: %s = Post type name */
108
+ printf( esc_html__( 'Custom %s Title', 'autodescription' ), esc_html( $type ) );
109
+ ?>
110
+ </strong></div>
111
+ <div>
112
+ <?php
113
+ $this->make_info(
114
+ __( 'Recommended Length: 50 to 55 characters', 'autodescription' ),
115
+ 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#3'
116
+ );
117
+ ?>
118
+ </div>
119
</label>
120
<span class="description tsf-counter">
121
+ <?php
122
+ printf(
123
+ /* translators: %s = number */
124
+ esc_html__( 'Characters Used: %s', 'autodescription' ),
125
+ '<span id="autodescription_title_chars">' . (int) mb_strlen( $tit_len_parsed ) . '</span>'
126
+ );
127
+ ?>
128
<span class="hide-if-no-js tsf-ajax"></span>
129
</span>
130
</div>
142
<div class="tsf-flex-setting-label tsf-flex">
143
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
144
<label for="autodescription_description" class="tsf-flex-setting-label-item tsf-flex">
145
+ <div><strong>
146
+ <?php
147
+ /* translators: %s = Post type name */
148
+ printf( esc_html__( 'Custom %s Description', 'autodescription' ), esc_html( $type ) );
149
+ ?>
150
+ </strong></div>
151
<div><?php $this->make_info( __( 'Recommended Length: 145 to 155 characters', 'autodescription' ), 'https://support.google.com/webmasters/answer/35624?hl=' . $language . '#1' ); ?></div>
152
</label>
153
<span class="description tsf-counter">
154
+ <?php
155
+ printf(
156
+ /* translators: %s = number */
157
+ esc_html__( 'Characters Used: %s', 'autodescription' ),
158
+ '<span id="autodescription_description_chars">' . (int) mb_strlen( $desc_len_parsed ) . '</span>'
159
+ );
160
+ ?>
161
<span class="hide-if-no-js tsf-ajax"></span>
162
</span>
163
</div>
181
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
182
<label for="autodescription_canonical" class="tsf-flex-setting-label-item tsf-flex">
183
<div><strong><?php esc_html_e( 'Custom Canonical URL', 'autodescription' ); ?></strong></div>
184
+ <div>
185
+ <?php
186
+ $this->make_info(
187
+ sprintf(
188
+ /* translators: %s = Post type name */
189
+ __( 'Preferred %s URL location', 'autodescription' ),
190
+ $type
191
+ ),
192
+ 'https://support.google.com/webmasters/answer/139066?hl=' . $language
193
+ );
194
+ ?>
195
+ </div>
196
</label>
197
</div>
198
</div>
213
<div class="tsf-checkbox-wrapper">
214
<label for="autodescription_noindex">
215
<input type="checkbox" name="autodescription[_genesis_noindex]" id="autodescription_noindex" value="1" <?php checked( $this->get_custom_field( '_genesis_noindex' ) ); ?> />
216
+ <?php
217
/* translators: 1: Option, 2: Post or Page */
218
printf( esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ), $this->code_wrap( 'noindex' ), esc_html( $type ) );
219
echo ' ';
220
+ $this->make_info(
221
+ sprintf(
222
+ __( 'Tell Search Engines not to show this %s in their search results', 'autodescription' ),
223
+ $type
224
+ ),
225
+ 'https://support.google.com/webmasters/answer/93710?hl=' . $language
226
+ );
227
+ ?>
228
</label>
229
</div>
230
<div class="tsf-checkbox-wrapper">
241
<label for="autodescription_noarchive"><input type="checkbox" name="autodescription[_genesis_noarchive]" id="autodescription_noarchive" value="1" <?php checked( $this->get_custom_field( '_genesis_noarchive' ) ); ?> />
242
<?php
243
/* translators: 1: Option, 2: Post or Page */
244
+ printf(
245
+ esc_html__( 'Apply %1$s to this %2$s', 'autodescription' ),
246
+ $this->code_wrap( 'noarchive' ),
247
+ esc_html( $type )
248
+ );
249
echo ' ';
250
+ /* translators: %s = Post type name */
251
$this->make_info( sprintf( __( 'Tell Search Engines not to save a cached copy of this %s', 'autodescription' ), $type ), 'https://support.google.com/webmasters/answer/79812?hl=' . $language );
252
?>
253
</label>
255
</div>
256
</div>
257
258
+ <?php
259
+ $can_do_archive_query = $this->is_option_checked( 'alter_archive_query' ) && $this->post_type_supports_taxonomies();
260
+ $can_do_search_query = $this->is_option_checked( 'alter_search_query' );
261
+ ?>
262
+
263
+ <?php if ( $can_do_archive_query || $can_do_search_query ) : ?>
264
<div class="tsf-flex-setting tsf-flex">
265
<div class="tsf-flex-setting-label tsf-flex">
266
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
270
</div>
271
</div>
272
<div class="tsf-flex-setting-input tsf-flex">
273
+ <?php if ( $can_do_search_query ) : ?>
274
<div class="tsf-checkbox-wrapper">
275
<label for="autodescription_exclude_local_search"><input type="checkbox" name="autodescription[exclude_local_search]" id="autodescription_exclude_local_search" value="1" <?php checked( $this->get_custom_field( 'exclude_local_search' ) ); ?> />
276
<?php
277
+ /* translators: %s = Post type name */
278
printf( esc_html__( 'Exclude this %s from local search', 'autodescription' ), esc_html( $type ) );
279
echo ' ';
280
+ /* translators: %s = Post type name */
281
$this->make_info( sprintf( __( 'This excludes this %s from local on-site search results', 'autodescription' ), $type ) );
282
?>
283
</label>
284
</div>
285
+ <?php endif; ?>
286
+ <?php if ( $can_do_archive_query ) : ?>
287
<div class="tsf-checkbox-wrapper">
288
<label for="autodescription_exclude_from_archive"><input type="checkbox" name="autodescription[exclude_from_archive]" id="autodescription_exclude_from_archive" value="1" <?php checked( $this->get_custom_field( 'exclude_from_archive' ) ); ?> />
289
<?php
290
+ /* translators: %s = Post type name */
291
+ printf( esc_html__( 'Exclude this %s from all archive listings', 'autodescription' ), esc_html( $type ) );
292
echo ' ';
293
+ /* translators: %s = Post type name */
294
$this->make_info( sprintf( __( 'This excludes this %s from on-site archive pages', 'autodescription' ), $type ) );
295
?>
296
</label>
298
<?php endif; ?>
299
</div>
300
</div>
301
+ <?php endif; ?>
302
303
<div class="tsf-flex-setting tsf-flex">
304
<div class="tsf-flex-setting-label tsf-flex">
309
</div>
310
<div>
311
<?php
312
+ $this->make_info(
313
+ __( 'This will force visitors to go to another URL', 'autodescription' ),
314
+ 'https://support.google.com/webmasters/answer/93633?hl=' . $language
315
+ );
316
?>
317
</div>
318
</label>
326
break;
327
328
case 'inpost_social' :
329
//* Fetch image placeholder.
330
$image_placeholder = $this->get_social_image( array( 'post_id' => $post_id, 'disallowed' => array( 'postmeta' ), 'escape' => false ) );
331
335
<div class="tsf-flex-setting-label-inner-wrap tsf-flex">
336
<label for="autodescription_socialimage-url" class="tsf-flex-setting-label-item tsf-flex">
337
<div><strong><?php esc_html_e( 'Custom Social Image URL', 'autodescription' ); ?></strong></div>
338
+ <div>
339
+ <?php
340
+ $this->make_info(
341
+ sprintf(
342
+ /* translators: %s = Post type name */
343
+ __( 'Preferred %s Social Image URL location', 'autodescription' ),
344
+ $type
345
+ ),
346
+ 'https://developers.facebook.com/docs/sharing/best-practices#images'
347
+ );
348
+ ?>
349
+ </div>
350
</label>
351
</div>
352
</div>
354
<input class="large-text" type="text" name="autodescription[_social_image_url]" id="autodescription_socialimage-url" placeholder="<?php echo esc_url( $image_placeholder ); ?>" value="<?php echo esc_url( $this->get_custom_field( '_social_image_url' ) ); ?>" />
355
<div class="hide-if-no-js tsf-social-image-buttons">
356
<?php
357
+ //= Already escaped.
358
echo $this->get_social_image_uploader_form( 'autodescription_socialimage' );
359
?>
360
</div>
inc/views/metaboxes/general-metabox.php CHANGED
@@ -78,34 +78,135 @@ switch ( $instance ) :
78
case 'the_seo_framework_general_metabox_performance' :
79
80
?><h4><?php esc_html_e( 'Performance Settings', 'autodescription' ); ?></h4><?php
81
- $this->description( __(