Version Description
This minor update improves image processing, reducing TSF's load impact by roughly 20% when generating metadata. We also added WordPress 6.0 support for image filesizes, making social sharing even more robust.
Download this release
Release Info
Developer | Cybr |
Plugin | The SEO Framework |
Version | 4.2.4 |
Comparing to | |
See all releases |
Code changes from version 4.2.3 to 4.2.4
- autodescription.php +2 -2
- bootstrap/upgrade.php +0 -1
- inc/classes/admin-init.class.php +3 -3
- inc/classes/bridges/feed.class.php +1 -1
- inc/classes/bridges/ping.class.php +7 -2
- inc/classes/bridges/plugintable.class.php +6 -6
- inc/classes/bridges/sitemap.class.php +2 -2
- inc/classes/builders/robots/args.class.php +3 -8
- inc/classes/builders/robots/query.class.php +7 -16
- inc/classes/builders/scripts.class.php +1 -1
- inc/classes/builders/sitemap/base.class.php +11 -8
- inc/classes/builders/sitemap/main.class.php +4 -4
- inc/classes/core.class.php +26 -13
- inc/classes/detect.class.php +20 -3
- inc/classes/generate-description.class.php +3 -7
- inc/classes/generate-image.class.php +86 -46
- inc/classes/generate-ldjson.class.php +13 -10
- inc/classes/generate-title.class.php +28 -22
- inc/classes/generate-url.class.php +5 -5
- inc/classes/init.class.php +16 -16
- inc/classes/internal/debug.class.php +5 -5
- inc/classes/internal/deprecated.class.php +11 -6
- inc/classes/interpreters/html.class.php +1 -1
- inc/classes/interpreters/markdown.class.php +2 -2
- inc/classes/load.class.php +1 -1
- inc/classes/query.class.php +22 -8
- inc/classes/render.class.php +2 -2
- inc/classes/sanitize.class.php +26 -21
- inc/classes/site-options.class.php +2 -1
- inc/functions/api.php +5 -7
- inc/functions/upgrade-suggestion.php +10 -8
- inc/views/edit/seo-settings-singular.php +2 -2
- inc/views/edit/seo-settings-tt.php +2 -2
- inc/views/settings/metaboxes/general.php +9 -1
- inc/views/settings/metaboxes/homepage.php +2 -2
- inc/views/settings/metaboxes/post-type-archive.php +2 -2
- inc/views/settings/metaboxes/schema.php +19 -12
- inc/views/settings/metaboxes/sitemaps.php +5 -5
- inc/views/settings/metaboxes/title.php +2 -3
- inc/views/settings/wrap.php +40 -12
- inc/views/sitemap/xml-sitemap.php +8 -8
- inc/views/sitemap/xsl-stylesheet.php +1 -1
- inc/views/sitemap/xsl/description.php +2 -2
- lib/css/settings.css +39 -25
- lib/css/settings.min.css +1 -1
- readme.txt +7 -3
autodescription.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: The SEO Framework
|
4 |
* Plugin URI: https://theseoframework.com/
|
5 |
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
|
6 |
-
* Version: 4.2.
|
7 |
* Author: The SEO Framework Team
|
8 |
* Author URI: https://theseoframework.com/
|
9 |
* License: GPLv3
|
@@ -41,7 +41,7 @@ defined( 'ABSPATH' ) or die;
|
|
41 |
*
|
42 |
* @since 2.3.5
|
43 |
*/
|
44 |
-
define( 'THE_SEO_FRAMEWORK_VERSION', '4.2.
|
45 |
|
46 |
/**
|
47 |
* The plugin Database version.
|
3 |
* Plugin Name: The SEO Framework
|
4 |
* Plugin URI: https://theseoframework.com/
|
5 |
* Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for your WordPress website.
|
6 |
+
* Version: 4.2.4
|
7 |
* Author: The SEO Framework Team
|
8 |
* Author URI: https://theseoframework.com/
|
9 |
* License: GPLv3
|
41 |
*
|
42 |
* @since 2.3.5
|
43 |
*/
|
44 |
+
define( 'THE_SEO_FRAMEWORK_VERSION', '4.2.4' );
|
45 |
|
46 |
/**
|
47 |
* The plugin Database version.
|
bootstrap/upgrade.php
CHANGED
@@ -187,7 +187,6 @@ function _do_upgrade() {
|
|
187 |
* @return string $current_version The current database version.
|
188 |
*/
|
189 |
function _downgrade( $previous_version ) { // phpcs:ignore,VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
190 |
-
|
191 |
// We aren't (currently) expecting issues where downgrading causes mayem. 4051 did cause some, though. This was added later; just set to current.
|
192 |
return _set_to_current_version();
|
193 |
}
|
187 |
* @return string $current_version The current database version.
|
188 |
*/
|
189 |
function _downgrade( $previous_version ) { // phpcs:ignore,VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
|
|
190 |
// We aren't (currently) expecting issues where downgrading causes mayem. 4051 did cause some, though. This was added later; just set to current.
|
191 |
return _set_to_current_version();
|
192 |
}
|
inc/classes/admin-init.class.php
CHANGED
@@ -369,6 +369,8 @@ class Admin_Init extends Init {
|
|
369 |
* @since 2.9.3 1. Query arguments work again (regression 2.9.2).
|
370 |
* 2. Now only accepts http and https protocols.
|
371 |
* @since 4.2.0 Now allows query arguments with value 0|'0'.
|
|
|
|
|
372 |
*
|
373 |
* @param string $page Menu slug. This slug must exist, or the redirect will loop back to the current page.
|
374 |
* @param array $query_args Optional. Associative array of query string arguments
|
@@ -398,8 +400,6 @@ class Admin_Init extends Init {
|
|
398 |
|
399 |
// White screen of death for non-debugging users. Let's make it friendlier.
|
400 |
if ( $headers_sent && $target ) {
|
401 |
-
$this->handle_admin_redirect_error( $target );
|
402 |
-
|
403 |
$headers_list = headers_list();
|
404 |
$location = sprintf( 'Location: %s', \wp_sanitize_redirect( $target ) );
|
405 |
|
@@ -539,7 +539,7 @@ class Admin_Init extends Init {
|
|
539 |
* @return bool True on success, false on failure.
|
540 |
*/
|
541 |
public function clear_persistent_notice( $key ) {
|
542 |
-
|
543 |
$notices = $this->get_static_cache( 'persistent_notices', [] );
|
544 |
unset( $notices[ $key ] );
|
545 |
|
369 |
* @since 2.9.3 1. Query arguments work again (regression 2.9.2).
|
370 |
* 2. Now only accepts http and https protocols.
|
371 |
* @since 4.2.0 Now allows query arguments with value 0|'0'.
|
372 |
+
* @TODO Remove failsafe? WP 5.2/5.4 broke it (this method can never run on failure...)
|
373 |
+
* Maybe we should investigate the cause and remove WP's blockade. This is a corner-case, however.
|
374 |
*
|
375 |
* @param string $page Menu slug. This slug must exist, or the redirect will loop back to the current page.
|
376 |
* @param array $query_args Optional. Associative array of query string arguments
|
400 |
|
401 |
// White screen of death for non-debugging users. Let's make it friendlier.
|
402 |
if ( $headers_sent && $target ) {
|
|
|
|
|
403 |
$headers_list = headers_list();
|
404 |
$location = sprintf( 'Location: %s', \wp_sanitize_redirect( $target ) );
|
405 |
|
539 |
* @return bool True on success, false on failure.
|
540 |
*/
|
541 |
public function clear_persistent_notice( $key ) {
|
542 |
+
// TODO We could make a oneliner using array_diff_key?: array_diff_key( cache, [ $key ] )
|
543 |
$notices = $this->get_static_cache( 'persistent_notices', [] );
|
544 |
unset( $notices[ $key ] );
|
545 |
|
inc/classes/bridges/feed.class.php
CHANGED
@@ -128,7 +128,7 @@ final class Feed {
|
|
128 |
}
|
129 |
|
130 |
if ( static::$tsf->get_option( 'source_the_feed' ) ) {
|
131 |
-
$content .=
|
132 |
}
|
133 |
|
134 |
return $content;
|
128 |
}
|
129 |
|
130 |
if ( static::$tsf->get_option( 'source_the_feed' ) ) {
|
131 |
+
$content .= "\n" . $this->get_feed_entry_source_link();
|
132 |
}
|
133 |
|
134 |
return $content;
|
inc/classes/bridges/ping.class.php
CHANGED
@@ -80,7 +80,12 @@ final class Ping {
|
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
-
* Retries pinging the search engines.
|
|
|
|
|
|
|
|
|
|
|
84 |
*
|
85 |
* @since 4.1.2
|
86 |
* @see static::engage_pinging_retry_cron()
|
@@ -96,7 +101,7 @@ final class Ping {
|
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
-
* Pings search engines.
|
100 |
*
|
101 |
* @since 2.2.9
|
102 |
* @since 2.8.0 Only worked when the blog was not public...
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
+
* Retries pinging the search engines for the base sitemap only.
|
84 |
+
*
|
85 |
+
* Devs: If you need to retry pinging another sitemap, please engage a custom scheduler,
|
86 |
+
* first call `engage_pinging_retry_cron( [ 'id' => 'my_sitemap_id' ] )`, then hook
|
87 |
+
* into action `tsf_sitemap_cron_hook_retry` and test `$args['id']` like below.
|
88 |
+
* Alternatively, hitch with `the_seo_framework_ping_search_engines`.
|
89 |
*
|
90 |
* @since 4.1.2
|
91 |
* @see static::engage_pinging_retry_cron()
|
101 |
}
|
102 |
|
103 |
/**
|
104 |
+
* Pings search engines the base sitemap.
|
105 |
*
|
106 |
* @since 2.2.9
|
107 |
* @since 2.8.0 Only worked when the blog was not public...
|
inc/classes/bridges/plugintable.class.php
CHANGED
@@ -59,12 +59,12 @@ final class PluginTable {
|
|
59 |
}
|
60 |
|
61 |
$tsf_links['tsfem'] = sprintf(
|
62 |
-
'<a href="%s" rel="noreferrer noopener" target=
|
63 |
'https://theseoframework.com/extensions/',
|
64 |
\esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
|
65 |
);
|
66 |
$tsf_links['pricing'] = sprintf(
|
67 |
-
'<a href="%s" rel="noreferrer noopener" target=
|
68 |
'https://theseoframework.com/pricing/',
|
69 |
\esc_html_x( 'Pricing', 'Plugin pricing', 'autodescription' )
|
70 |
);
|
@@ -97,28 +97,28 @@ final class PluginTable {
|
|
97 |
$plugin_meta,
|
98 |
[
|
99 |
'support' => vsprintf(
|
100 |
-
'<a href="%s" rel="noreferrer noopener nofollow" target=
|
101 |
[
|
102 |
'https://tsf.fyi/support',
|
103 |
\esc_html__( 'Get support', 'autodescription' ),
|
104 |
]
|
105 |
),
|
106 |
'docs' => vsprintf(
|
107 |
-
'<a href="%s" rel="noreferrer noopener nofollow" target=
|
108 |
[
|
109 |
'https://tsf.fyi/docs',
|
110 |
\esc_html__( 'View documentation', 'autodescription' ),
|
111 |
]
|
112 |
),
|
113 |
'API' => vsprintf(
|
114 |
-
'<a href="%s" rel="noreferrer noopener nofollow" target=
|
115 |
[
|
116 |
'https://tsf.fyi/docs/api',
|
117 |
\esc_html__( 'View API docs', 'autodescription' ),
|
118 |
]
|
119 |
),
|
120 |
'EM' => vsprintf(
|
121 |
-
'<a href="%s" rel="noreferrer noopener nofollow" target=
|
122 |
[
|
123 |
'https://tsf.fyi/extension-manager',
|
124 |
$_get_em
|
59 |
}
|
60 |
|
61 |
$tsf_links['tsfem'] = sprintf(
|
62 |
+
'<a href="%s" rel="noreferrer noopener" target=_blank>%s</a>',
|
63 |
'https://theseoframework.com/extensions/',
|
64 |
\esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
|
65 |
);
|
66 |
$tsf_links['pricing'] = sprintf(
|
67 |
+
'<a href="%s" rel="noreferrer noopener" target=_blank>%s</a>',
|
68 |
'https://theseoframework.com/pricing/',
|
69 |
\esc_html_x( 'Pricing', 'Plugin pricing', 'autodescription' )
|
70 |
);
|
97 |
$plugin_meta,
|
98 |
[
|
99 |
'support' => vsprintf(
|
100 |
+
'<a href="%s" rel="noreferrer noopener nofollow" target=_blank>%s</a>',
|
101 |
[
|
102 |
'https://tsf.fyi/support',
|
103 |
\esc_html__( 'Get support', 'autodescription' ),
|
104 |
]
|
105 |
),
|
106 |
'docs' => vsprintf(
|
107 |
+
'<a href="%s" rel="noreferrer noopener nofollow" target=_blank>%s</a>',
|
108 |
[
|
109 |
'https://tsf.fyi/docs',
|
110 |
\esc_html__( 'View documentation', 'autodescription' ),
|
111 |
]
|
112 |
),
|
113 |
'API' => vsprintf(
|
114 |
+
'<a href="%s" rel="noreferrer noopener nofollow" target=_blank>%s</a>',
|
115 |
[
|
116 |
'https://tsf.fyi/docs/api',
|
117 |
\esc_html__( 'View API docs', 'autodescription' ),
|
118 |
]
|
119 |
),
|
120 |
'EM' => vsprintf(
|
121 |
+
'<a href="%s" rel="noreferrer noopener nofollow" target=_blank>%s</a>',
|
122 |
[
|
123 |
'https://tsf.fyi/extension-manager',
|
124 |
$_get_em
|
inc/classes/bridges/sitemap.class.php
CHANGED
@@ -267,7 +267,7 @@ final class Sitemap {
|
|
267 |
echo 'Sitemap is locked temporarily. Try again later.';
|
268 |
}
|
269 |
|
270 |
-
echo
|
271 |
exit;
|
272 |
}
|
273 |
|
@@ -425,7 +425,7 @@ final class Sitemap {
|
|
425 |
*/
|
426 |
public function output_sitemap_header() {
|
427 |
|
428 |
-
echo '<?xml version="1.0" encoding="UTF-8"?>'
|
429 |
|
430 |
if ( static::$tsf->get_option( 'sitemap_styles' ) ) {
|
431 |
printf(
|
267 |
echo 'Sitemap is locked temporarily. Try again later.';
|
268 |
}
|
269 |
|
270 |
+
echo "\n";
|
271 |
exit;
|
272 |
}
|
273 |
|
425 |
*/
|
426 |
public function output_sitemap_header() {
|
427 |
|
428 |
+
echo '<?xml version="1.0" encoding="UTF-8"?>', "\n";
|
429 |
|
430 |
if ( static::$tsf->get_option( 'sitemap_styles' ) ) {
|
431 |
printf(
|
inc/classes/builders/robots/args.class.php
CHANGED
@@ -56,11 +56,8 @@ final class Args extends Factory {
|
|
56 |
|
57 |
$asserting_noindex = 'noindex' === $type;
|
58 |
|
59 |
-
meta_settings
|
60 |
-
|
61 |
-
if ( static::$options & \The_SEO_Framework\ROBOTS_IGNORE_SETTINGS )
|
62 |
-
goto after_meta_settings;
|
63 |
-
|
64 |
$qubit = null;
|
65 |
|
66 |
if ( $args['taxonomy'] ) {
|
@@ -90,9 +87,8 @@ final class Args extends Factory {
|
|
90 |
yield 'meta_qubit_default' => false;
|
91 |
endswitch;
|
92 |
}
|
93 |
-
after_meta_settings:;
|
94 |
|
95 |
-
globals:
|
96 |
yield 'globals_site' => (bool) $tsf->get_option( "site_$type" );
|
97 |
|
98 |
if ( $args['taxonomy'] ) {
|
@@ -116,7 +112,6 @@ final class Args extends Factory {
|
|
116 |
if ( $args['id'] )
|
117 |
yield 'globals_post_type' => $tsf->is_post_type_robots_set( $type, \get_post_type( $args['id'] ) );
|
118 |
}
|
119 |
-
}
|
120 |
|
121 |
index_protection: if ( $asserting_noindex ) {
|
122 |
// We assert options here for a jump to index_protection might be unaware.
|
56 |
|
57 |
$asserting_noindex = 'noindex' === $type;
|
58 |
|
59 |
+
// We assert options here for a jump to meta_settings might be unaware.
|
60 |
+
meta_settings: if ( ! ( static::$options & \The_SEO_Framework\ROBOTS_IGNORE_SETTINGS ) ) {
|
|
|
|
|
|
|
61 |
$qubit = null;
|
62 |
|
63 |
if ( $args['taxonomy'] ) {
|
87 |
yield 'meta_qubit_default' => false;
|
88 |
endswitch;
|
89 |
}
|
|
|
90 |
|
91 |
+
globals:
|
92 |
yield 'globals_site' => (bool) $tsf->get_option( "site_$type" );
|
93 |
|
94 |
if ( $args['taxonomy'] ) {
|
112 |
if ( $args['id'] )
|
113 |
yield 'globals_post_type' => $tsf->is_post_type_robots_set( $type, \get_post_type( $args['id'] ) );
|
114 |
}
|
|
|
115 |
|
116 |
index_protection: if ( $asserting_noindex ) {
|
117 |
// We assert options here for a jump to index_protection might be unaware.
|
inc/classes/builders/robots/query.class.php
CHANGED
@@ -55,10 +55,8 @@ final class Query extends Factory {
|
|
55 |
|
56 |
$asserting_noindex = 'noindex' === $type;
|
57 |
|
58 |
-
meta_settings
|
59 |
-
|
60 |
-
if ( static::$options & \The_SEO_Framework\ROBOTS_IGNORE_SETTINGS )
|
61 |
-
goto after_meta_settings;
|
62 |
|
63 |
$qubit = null;
|
64 |
|
@@ -89,9 +87,8 @@ final class Query extends Factory {
|
|
89 |
yield 'meta_qubit_default' => false;
|
90 |
endswitch;
|
91 |
}
|
92 |
-
after_meta_settings:;
|
93 |
|
94 |
-
globals:
|
95 |
yield 'globals_site' => (bool) $tsf->get_option( "site_$type" );
|
96 |
|
97 |
if ( $tsf->is_real_front_page() ) {
|
@@ -109,7 +106,7 @@ final class Query extends Factory {
|
|
109 |
if ( $tsf->is_archive() ) {
|
110 |
if ( $tsf->is_author() ) {
|
111 |
yield 'globals_author' => (bool) $tsf->get_option( "author_$type" );
|
112 |
-
} elseif (
|
113 |
yield 'globals_date' => (bool) $tsf->get_option( "date_$type" );
|
114 |
}
|
115 |
} elseif ( $tsf->is_search() ) {
|
@@ -134,13 +131,9 @@ final class Query extends Factory {
|
|
134 |
} elseif ( $tsf->is_singular() ) {
|
135 |
yield 'globals_post_type' => $tsf->is_post_type_robots_set( $type, $tsf->get_current_post_type() );
|
136 |
}
|
137 |
-
}
|
138 |
-
|
139 |
-
index_protection: if ( $asserting_noindex ) {
|
140 |
-
// We assert options here for a jump to index_protection might be unaware.
|
141 |
-
if ( static::$options & \The_SEO_Framework\ROBOTS_IGNORE_PROTECTION )
|
142 |
-
goto after_index_protection;
|
143 |
|
|
|
|
|
144 |
if ( $tsf->is_singular() ) {
|
145 |
// A reiteration of the very same code as above... but, homepage may not always be singular.
|
146 |
// The conditions below MUST overwrite this, too. So, this is the perfect placement.
|
@@ -158,13 +151,11 @@ final class Query extends Factory {
|
|
158 |
yield from static::assert_noindex_query_pass( 'cpage' );
|
159 |
}
|
160 |
}
|
161 |
-
after_index_protection:;
|
162 |
|
163 |
exploit_protection: if ( $tsf->is_query_exploited() ) {
|
164 |
if ( \in_array( $type, [ 'noindex', 'nofollow' ], true ) )
|
165 |
yield 'query_protection' => true;
|
166 |
}
|
167 |
-
after_exploit_protection:;
|
168 |
|
169 |
end:;
|
170 |
}
|
@@ -201,7 +192,7 @@ final class Query extends Factory {
|
|
201 |
* the first page indexable via user-intent only. Concordingly, too
|
202 |
* because we cannot assert this via the administrative dashboard.
|
203 |
*/
|
204 |
-
yield '404' =>
|
205 |
else :
|
206 |
/**
|
207 |
* Check for 404, or if archive is empty: set noindex for those.
|
55 |
|
56 |
$asserting_noindex = 'noindex' === $type;
|
57 |
|
58 |
+
// We assert options here for a jump to meta_settings might be unaware.
|
59 |
+
meta_settings: if ( ! ( static::$options & \The_SEO_Framework\ROBOTS_IGNORE_SETTINGS ) ) {
|
|
|
|
|
60 |
|
61 |
$qubit = null;
|
62 |
|
87 |
yield 'meta_qubit_default' => false;
|
88 |
endswitch;
|
89 |
}
|
|
|
90 |
|
91 |
+
globals:
|
92 |
yield 'globals_site' => (bool) $tsf->get_option( "site_$type" );
|
93 |
|
94 |
if ( $tsf->is_real_front_page() ) {
|
106 |
if ( $tsf->is_archive() ) {
|
107 |
if ( $tsf->is_author() ) {
|
108 |
yield 'globals_author' => (bool) $tsf->get_option( "author_$type" );
|
109 |
+
} elseif ( \is_date() ) {
|
110 |
yield 'globals_date' => (bool) $tsf->get_option( "date_$type" );
|
111 |
}
|
112 |
} elseif ( $tsf->is_search() ) {
|
131 |
} elseif ( $tsf->is_singular() ) {
|
132 |
yield 'globals_post_type' => $tsf->is_post_type_robots_set( $type, $tsf->get_current_post_type() );
|
133 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
+
// We assert options here for a jump to index_protection might be unaware.
|
136 |
+
index_protection: if ( $asserting_noindex && ! ( static::$options & \The_SEO_Framework\ROBOTS_IGNORE_PROTECTION ) ) {
|
137 |
if ( $tsf->is_singular() ) {
|
138 |
// A reiteration of the very same code as above... but, homepage may not always be singular.
|
139 |
// The conditions below MUST overwrite this, too. So, this is the perfect placement.
|
151 |
yield from static::assert_noindex_query_pass( 'cpage' );
|
152 |
}
|
153 |
}
|
|
|
154 |
|
155 |
exploit_protection: if ( $tsf->is_query_exploited() ) {
|
156 |
if ( \in_array( $type, [ 'noindex', 'nofollow' ], true ) )
|
157 |
yield 'query_protection' => true;
|
158 |
}
|
|
|
159 |
|
160 |
end:;
|
161 |
}
|
192 |
* the first page indexable via user-intent only. Concordingly, too
|
193 |
* because we cannot assert this via the administrative dashboard.
|
194 |
*/
|
195 |
+
yield '404' => \is_404();
|
196 |
else :
|
197 |
/**
|
198 |
* Check for 404, or if archive is empty: set noindex for those.
|
inc/classes/builders/scripts.class.php
CHANGED
@@ -114,7 +114,7 @@ final class Scripts {
|
|
114 |
\add_filter( 'admin_body_class', [ $this, '_add_body_class' ] );
|
115 |
\add_action( 'in_admin_header', [ $this, '_print_tsfjs_script' ] );
|
116 |
|
117 |
-
\add_action( 'admin_enqueue_scripts', [ $this, '_prepare_admin_scripts' ], 1 ); // Magic number: likely
|
118 |
\add_action( 'admin_footer', [ $this, '_output_templates' ], 999 ); // Magic number: later is less likely to collide?
|
119 |
}
|
120 |
|
114 |
\add_filter( 'admin_body_class', [ $this, '_add_body_class' ] );
|
115 |
\add_action( 'in_admin_header', [ $this, '_print_tsfjs_script' ] );
|
116 |
|
117 |
+
\add_action( 'admin_enqueue_scripts', [ $this, '_prepare_admin_scripts' ], 1 ); // Magic number: we likely run at priority 0. Add 1.
|
118 |
\add_action( 'admin_footer', [ $this, '_output_templates' ], 999 ); // Magic number: later is less likely to collide?
|
119 |
}
|
120 |
|
inc/classes/builders/sitemap/base.class.php
CHANGED
@@ -312,6 +312,10 @@ class Base extends Main {
|
|
312 |
$content .= $this->build_url_item( $_values );
|
313 |
}
|
314 |
|
|
|
|
|
|
|
|
|
315 |
if ( \has_filter( 'the_seo_framework_sitemap_additional_urls' ) ) {
|
316 |
foreach ( $this->generate_additional_base_urls(
|
317 |
compact( 'show_modified', 'count' ),
|
@@ -322,8 +326,7 @@ class Base extends Main {
|
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
-
*
|
326 |
-
* If you only need to add a few URLs (fewer than 500), then you can safely use this.
|
327 |
*
|
328 |
* @since 2.5.2
|
329 |
* @since 4.0.0 Added $args parameter.
|
@@ -331,7 +334,7 @@ class Base extends Main {
|
|
331 |
* @param string $extend Custom sitemap extension. Must be escaped.
|
332 |
* @param array $args : {
|
333 |
* bool $show_modified : Whether to display modified date.
|
334 |
-
* int $
|
335 |
* }
|
336 |
*/
|
337 |
$extend = (string) \apply_filters_ref_array(
|
@@ -463,9 +466,9 @@ class Base extends Main {
|
|
463 |
* @generator
|
464 |
* @iterator
|
465 |
*
|
466 |
-
* @param
|
467 |
-
* @param array
|
468 |
-
* @param int
|
469 |
* @yield array|void : {
|
470 |
* string loc
|
471 |
* string lastmod
|
@@ -490,8 +493,8 @@ class Base extends Main {
|
|
490 |
yield $_values;
|
491 |
}
|
492 |
|
493 |
-
// Only clean post cache when NOT using
|
494 |
-
|
495 |
}
|
496 |
}
|
497 |
|
312 |
$content .= $this->build_url_item( $_values );
|
313 |
}
|
314 |
|
315 |
+
/**
|
316 |
+
* NOTE to devs: Use this filter if you want to let the generator build the string (lower memory usage).
|
317 |
+
* This filter also keeps track toward the sitemap limit via $count.
|
318 |
+
*/
|
319 |
if ( \has_filter( 'the_seo_framework_sitemap_additional_urls' ) ) {
|
320 |
foreach ( $this->generate_additional_base_urls(
|
321 |
compact( 'show_modified', 'count' ),
|
326 |
}
|
327 |
|
328 |
/**
|
329 |
+
* This filter accepts a simple string, which may strain the memory usage if not generated (via co-routine).
|
|
|
330 |
*
|
331 |
* @since 2.5.2
|
332 |
* @since 4.0.0 Added $args parameter.
|
334 |
* @param string $extend Custom sitemap extension. Must be escaped.
|
335 |
* @param array $args : {
|
336 |
* bool $show_modified : Whether to display modified date.
|
337 |
+
* int $count : The total sitemap items before adding additional URLs.
|
338 |
* }
|
339 |
*/
|
340 |
$extend = (string) \apply_filters_ref_array(
|
466 |
* @generator
|
467 |
* @iterator
|
468 |
*
|
469 |
+
* @param int[] $post_ids The post IDs to go over.
|
470 |
+
* @param array $args The generator arguments.
|
471 |
+
* @param int $count The iteration count. Passed by reference.
|
472 |
* @yield array|void : {
|
473 |
* string loc
|
474 |
* string lastmod
|
493 |
yield $_values;
|
494 |
}
|
495 |
|
496 |
+
// Only clean post cache when NOT using a caching plugin.
|
497 |
+
WP_CACHE or \clean_post_cache( $post );
|
498 |
}
|
499 |
}
|
500 |
|
inc/classes/builders/sitemap/main.class.php
CHANGED
@@ -162,8 +162,8 @@ abstract class Main {
|
|
162 |
*/
|
163 |
final public function is_post_included_in_sitemap( $post_id ) {
|
164 |
|
165 |
-
static $excluded
|
166 |
-
if (
|
167 |
/**
|
168 |
* @since 2.5.2
|
169 |
* @since 2.8.0 No longer accepts '0' as entry.
|
@@ -214,8 +214,8 @@ abstract class Main {
|
|
214 |
*/
|
215 |
final public function is_term_included_in_sitemap( $term_id, $taxonomy ) {
|
216 |
|
217 |
-
static $excluded
|
218 |
-
if (
|
219 |
/**
|
220 |
* @since 4.0.0
|
221 |
* @param int[] $excluded Sequential list of excluded IDs: [ int ...term_id ]
|
162 |
*/
|
163 |
final public function is_post_included_in_sitemap( $post_id ) {
|
164 |
|
165 |
+
static $excluded;
|
166 |
+
if ( ! isset( $excluded ) ) {
|
167 |
/**
|
168 |
* @since 2.5.2
|
169 |
* @since 2.8.0 No longer accepts '0' as entry.
|
214 |
*/
|
215 |
final public function is_term_included_in_sitemap( $term_id, $taxonomy ) {
|
216 |
|
217 |
+
static $excluded;
|
218 |
+
if ( ! isset( $excluded ) ) {
|
219 |
/**
|
220 |
* @since 4.0.0
|
221 |
* @param int[] $excluded Sequential list of excluded IDs: [ int ...term_id ]
|
inc/classes/core.class.php
CHANGED
@@ -579,7 +579,7 @@ class Core {
|
|
579 |
}
|
580 |
|
581 |
/**
|
582 |
-
* Calculates the relative font color according to the background.
|
583 |
*
|
584 |
* @since 2.8.0
|
585 |
* @since 2.9.0 Now adds a little more relative softness based on rel_lum.
|
@@ -609,7 +609,7 @@ class Core {
|
|
609 |
);
|
610 |
|
611 |
$get_relative_luminance = static function( $v ) {
|
612 |
-
// Convert to 0~1
|
613 |
$v /= 0xFF;
|
614 |
|
615 |
if ( $v > .03928 ) {
|
@@ -620,19 +620,20 @@ class Core {
|
|
620 |
return $lum;
|
621 |
};
|
622 |
|
623 |
-
//
|
624 |
-
$rl =
|
625 |
-
+
|
626 |
-
+
|
627 |
|
628 |
-
// Build light greyscale
|
629 |
-
|
630 |
-
|
631 |
-
$
|
|
|
|
|
632 |
|
633 |
-
// Invert
|
634 |
-
if ( $rl <
|
635 |
-
// Build dark greyscale. bitwise operators...
|
636 |
$gr ^= 0xFF;
|
637 |
$gg ^= 0xFF;
|
638 |
$gb ^= 0xFF;
|
@@ -696,4 +697,16 @@ class Core {
|
|
696 |
public function convert_markdown( $text, $convert = [], $args = [] ) {
|
697 |
return Interpreters\Markdown::convert( $text, $convert, $args );
|
698 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
699 |
}
|
579 |
}
|
580 |
|
581 |
/**
|
582 |
+
* Calculates the relative font color according to the background, grayscale.
|
583 |
*
|
584 |
* @since 2.8.0
|
585 |
* @since 2.9.0 Now adds a little more relative softness based on rel_lum.
|
609 |
);
|
610 |
|
611 |
$get_relative_luminance = static function( $v ) {
|
612 |
+
// Convert hex to 0~1 float.
|
613 |
$v /= 0xFF;
|
614 |
|
615 |
if ( $v > .03928 ) {
|
620 |
return $lum;
|
621 |
};
|
622 |
|
623 |
+
// Calc relative Luminance using sRGB.
|
624 |
+
$rl = .2126 * $get_relative_luminance( $r )
|
625 |
+
+ .7152 * $get_relative_luminance( $g )
|
626 |
+
+ .0722 * $get_relative_luminance( $b );
|
627 |
|
628 |
+
// Build light greyscale using relative constrast.
|
629 |
+
// Rounding is required for bitwise operation (PHP8.1+).
|
630 |
+
// printf will round anyway when floats are detected. Diff in #opcodes should be minimal.
|
631 |
+
$gr = round( $r * .2989 / 8 * $rl );
|
632 |
+
$gg = round( $g * .5870 / 8 * $rl );
|
633 |
+
$gb = round( $b * .1140 / 8 * $rl );
|
634 |
|
635 |
+
// Invert grayscela if they hit the relative luminance middle.
|
636 |
+
if ( $rl < .5 ) {
|
|
|
637 |
$gr ^= 0xFF;
|
638 |
$gg ^= 0xFF;
|
639 |
$gb ^= 0xFF;
|
697 |
public function convert_markdown( $text, $convert = [], $args = [] ) {
|
698 |
return Interpreters\Markdown::convert( $text, $convert, $args );
|
699 |
}
|
700 |
+
|
701 |
+
/**
|
702 |
+
* Whether to display Extension Manager suggestions to the user based on several conditions.
|
703 |
+
*
|
704 |
+
* @since 4.2.4
|
705 |
+
* @uses TSF_DISABLE_SUGGESTIONS Set that to true if you don't like us.
|
706 |
+
*
|
707 |
+
* @return bool
|
708 |
+
*/
|
709 |
+
public function _display_extension_suggestions() {
|
710 |
+
return \current_user_can( 'install_plugins' ) && ! ( \defined( 'TSF_DISABLE_SUGGESTIONS' ) && TSF_DISABLE_SUGGESTIONS );
|
711 |
+
}
|
712 |
}
|
inc/classes/detect.class.php
CHANGED
@@ -180,7 +180,7 @@ class Detect extends Render {
|
|
180 |
* @uses $this->detect_plugin_multi()
|
181 |
*
|
182 |
* @param array[] $plugins Array of array for globals, constants, classes
|
183 |
-
*
|
184 |
* @param bool $use_cache Bypasses cache if false
|
185 |
*/
|
186 |
public function can_i_use( $plugins = [], $use_cache = true ) {
|
@@ -576,6 +576,7 @@ class Detect extends Render {
|
|
576 |
* @since 4.0.0
|
577 |
* @since 4.0.2 Now tests for an existing post/term ID when on singular/term pages.
|
578 |
* @since 4.0.3 Can now assert empty categories again by checking for taxonomy support.
|
|
|
579 |
*
|
580 |
* @return bool
|
581 |
*/
|
@@ -585,7 +586,11 @@ class Detect extends Render {
|
|
585 |
if ( null !== $memo = memo() ) return $memo;
|
586 |
|
587 |
switch ( true ) :
|
588 |
-
case
|
|
|
|
|
|
|
|
|
589 |
$supported = false;
|
590 |
break;
|
591 |
|
@@ -604,10 +609,22 @@ class Detect extends Render {
|
|
604 |
$supported = $this->is_taxonomy_supported() && $this->get_the_real_ID();
|
605 |
break;
|
606 |
|
607 |
-
//
|
608 |
default:
|
609 |
$supported = true;
|
610 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
611 |
endswitch;
|
612 |
|
613 |
/**
|
180 |
* @uses $this->detect_plugin_multi()
|
181 |
*
|
182 |
* @param array[] $plugins Array of array for globals, constants, classes
|
183 |
+
* and/or functions to check for plugin existence.
|
184 |
* @param bool $use_cache Bypasses cache if false
|
185 |
*/
|
186 |
public function can_i_use( $plugins = [], $use_cache = true ) {
|
576 |
* @since 4.0.0
|
577 |
* @since 4.0.2 Now tests for an existing post/term ID when on singular/term pages.
|
578 |
* @since 4.0.3 Can now assert empty categories again by checking for taxonomy support.
|
579 |
+
* @since 4.2.4 Added detection for AJAX, Cron, JSON, and REST queries (they're not supported as SEO-able queries).
|
580 |
*
|
581 |
* @return bool
|
582 |
*/
|
586 |
if ( null !== $memo = memo() ) return $memo;
|
587 |
|
588 |
switch ( true ) :
|
589 |
+
case \is_feed():
|
590 |
+
case \wp_doing_ajax():
|
591 |
+
case \wp_doing_cron():
|
592 |
+
case \wp_is_json_request():
|
593 |
+
case \defined( 'REST_REQUEST' ) && REST_REQUEST:
|
594 |
$supported = false;
|
595 |
break;
|
596 |
|
609 |
$supported = $this->is_taxonomy_supported() && $this->get_the_real_ID();
|
610 |
break;
|
611 |
|
612 |
+
// This includes 404.
|
613 |
default:
|
614 |
$supported = true;
|
615 |
break;
|
616 |
+
|
617 |
+
// TODO consider this instead of the current default? (it'd make the AJAX through REST test obsolete)
|
618 |
+
// Every recognized query (aside from $this->is_singular()/is_post_type_archive for we already covered those in full)
|
619 |
+
// case \is_404():
|
620 |
+
// case $this->is_search():
|
621 |
+
// case $this->is_real_front_page():
|
622 |
+
// case $this->is_archive():
|
623 |
+
// $supported = true;
|
624 |
+
// break;
|
625 |
+
// default:
|
626 |
+
// $supported = false;
|
627 |
+
// break;
|
628 |
endswitch;
|
629 |
|
630 |
/**
|
inc/classes/generate-description.class.php
CHANGED
@@ -655,10 +655,8 @@ class Generate_Description extends Generate {
|
|
655 |
|
656 |
$id = $this->get_the_front_page_ID();
|
657 |
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
return $excerpt;
|
662 |
}
|
663 |
|
664 |
/**
|
@@ -851,11 +849,9 @@ class Generate_Description extends Generate {
|
|
851 |
$excerpt = $this->strip_newline_urls( $excerpt );
|
852 |
$excerpt = $this->strip_paragraph_urls( $excerpt );
|
853 |
}
|
854 |
-
} else {
|
855 |
-
$excerpt = '';
|
856 |
}
|
857 |
|
858 |
-
return $excerpt;
|
859 |
}
|
860 |
|
861 |
/**
|
655 |
|
656 |
$id = $this->get_the_front_page_ID();
|
657 |
|
658 |
+
return ( $id ? $this->get_singular_description_excerpt( $id ) : '' )
|
659 |
+
?: $this->get_description_additions( [ 'id' => $id ] );
|
|
|
|
|
660 |
}
|
661 |
|
662 |
/**
|
849 |
$excerpt = $this->strip_newline_urls( $excerpt );
|
850 |
$excerpt = $this->strip_paragraph_urls( $excerpt );
|
851 |
}
|
|
|
|
|
852 |
}
|
853 |
|
854 |
+
return $excerpt ?? '';
|
855 |
}
|
856 |
|
857 |
/**
|
inc/classes/generate-image.class.php
CHANGED
@@ -188,13 +188,15 @@ class Generate_Image extends Generate_Url {
|
|
188 |
*
|
189 |
* @since 4.0.0
|
190 |
* @since 4.2.0 Can now return post type archive images from settings.
|
|
|
191 |
*
|
192 |
* @return array The image details array, sequential: int => {
|
193 |
-
* string url:
|
194 |
-
* int id:
|
195 |
-
* int width:
|
196 |
-
* int height:
|
197 |
-
* string alt:
|
|
|
198 |
* }
|
199 |
*/
|
200 |
protected function get_custom_field_image_details_from_query() {
|
@@ -256,14 +258,16 @@ class Generate_Image extends Generate_Url {
|
|
256 |
*
|
257 |
* @since 4.0.0
|
258 |
* @since 4.2.0 Now supports the `$args['pta']` index.
|
|
|
259 |
*
|
260 |
* @param array $args The query arguments. Must have 'id' and 'taxonomy'.
|
261 |
* @return array The image details array, sequential: int => {
|
262 |
-
* string url:
|
263 |
-
* int id:
|
264 |
-
* int width:
|
265 |
-
* int height:
|
266 |
-
* string alt:
|
|
|
267 |
* }
|
268 |
*/
|
269 |
protected function get_custom_field_image_details_from_args( $args ) {
|
@@ -327,7 +331,7 @@ class Generate_Image extends Generate_Url {
|
|
327 |
* @param string $context The filter context. Default 'social'.
|
328 |
* May be (for example) 'breadcrumb' or 'article' for structured data.
|
329 |
* @return array The image generation parameters, associative: {
|
330 |
-
* string size: The image size,
|
331 |
* boolean multi: Whether multiple images may be returned,
|
332 |
* array cbs: An array of image generation callbacks, in order of most important to least.
|
333 |
* When 'multi' (or $single input) parameter is "false", it will use the first found.
|
@@ -424,17 +428,19 @@ class Generate_Image extends Generate_Url {
|
|
424 |
* Generates image details.
|
425 |
*
|
426 |
* @since 4.0.0
|
|
|
427 |
*
|
428 |
* @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
|
429 |
* Leave null to autodetermine query.
|
430 |
* @param bool $single Whether to fetch one image, or multiple.
|
431 |
* @param string $context The context of the image generation, albeit 'social', 'schema', etc.
|
432 |
* @return array The image details array, sequential: int => {
|
433 |
-
* string url:
|
434 |
-
* int id:
|
435 |
-
* int width:
|
436 |
-
* int height:
|
437 |
-
* string alt:
|
|
|
438 |
* }
|
439 |
*/
|
440 |
protected function generate_image_details( $args, $single = true, $context = 'social' ) {
|
@@ -452,18 +458,20 @@ class Generate_Image extends Generate_Url {
|
|
452 |
* Processes image detail callbacks.
|
453 |
*
|
454 |
* @since 4.0.0
|
|
|
455 |
*
|
456 |
-
* @param
|
457 |
* @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
|
458 |
* Leave null to autodetermine query.
|
459 |
* @param string $size The image size to use.
|
460 |
* @param bool $single Whether to fetch one image, or multiple.
|
461 |
* @return array The image details array, sequential: int => {
|
462 |
-
* string url:
|
463 |
-
* int id:
|
464 |
-
* int width:
|
465 |
-
* int height:
|
466 |
-
* string alt:
|
|
|
467 |
* }
|
468 |
*/
|
469 |
protected function process_image_cbs( $cbs, $args, $size, $single ) {
|
@@ -489,6 +497,8 @@ class Generate_Image extends Generate_Url {
|
|
489 |
* Adds image dimension and alt parameters to the input details, if any.
|
490 |
*
|
491 |
* @since 4.0.0
|
|
|
|
|
492 |
*
|
493 |
* @param array $details The image details array, associative: {
|
494 |
* string url: The image URL,
|
@@ -501,57 +511,66 @@ class Generate_Image extends Generate_Url {
|
|
501 |
* int width: The image width in pixels,
|
502 |
* int height: The image height in pixels,
|
503 |
* string alt: The image alt tag,
|
|
|
504 |
* }
|
505 |
*/
|
506 |
public function merge_extra_image_details( $details, $size = 'full' ) {
|
507 |
|
508 |
-
|
509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
|
511 |
return $details;
|
512 |
}
|
513 |
|
514 |
/**
|
515 |
-
*
|
516 |
*
|
|
|
517 |
* @since 4.0.0
|
|
|
|
|
518 |
*
|
519 |
* @param int $src_id The source ID of the image.
|
520 |
-
* @param string $
|
521 |
* @param string $size The size of the image used.
|
522 |
* @return array The image dimensions, associative: {
|
523 |
* int width: The image width in pixels,
|
524 |
* int height: The image height in pixels,
|
525 |
* }
|
526 |
*/
|
527 |
-
public function get_image_dimensions( $src_id, $
|
528 |
|
529 |
-
|
|
|
|
|
|
|
|
|
530 |
|
531 |
$dimensions = [
|
532 |
'width' => 0,
|
533 |
'height' => 0,
|
534 |
];
|
535 |
|
536 |
-
if ( $
|
537 |
-
[
|
538 |
-
|
539 |
-
$test_src = \esc_url_raw( $this->set_url_scheme( $src, 'https' ), [ 'https', 'http' ] );
|
540 |
-
$test_url = \esc_url_raw( $this->set_url_scheme( $url, 'https' ), [ 'https', 'http' ] );
|
541 |
-
|
542 |
-
if ( $test_src === $test_url ) {
|
543 |
-
$dimensions = [
|
544 |
-
'width' => $width,
|
545 |
-
'height' => $height,
|
546 |
-
];
|
547 |
-
}
|
548 |
}
|
549 |
|
550 |
return $dimensions;
|
551 |
}
|
552 |
|
553 |
/**
|
554 |
-
*
|
555 |
*
|
556 |
* @since 4.0.0
|
557 |
*
|
@@ -563,26 +582,47 @@ class Generate_Image extends Generate_Url {
|
|
563 |
return $src_id ? trim( strip_tags( \get_post_meta( $src_id, '_wp_attachment_image_alt', true ) ) ) : '';
|
564 |
}
|
565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
566 |
/**
|
567 |
* Returns the largest acceptable image size's details.
|
|
|
568 |
*
|
569 |
* @since 4.0.2
|
|
|
570 |
*
|
571 |
-
* @param int $id
|
572 |
-
* @param int $max_size
|
|
|
573 |
* @return false|array Returns an array (url, width, height, is_intermediate), or false, if no image is available.
|
574 |
*/
|
575 |
-
public function get_largest_acceptable_image_src( $id, $max_size = 4096 ) {
|
576 |
|
577 |
// Imply there's a correct ID set. When there's not, the loop won't run.
|
578 |
-
$
|
579 |
-
$sizes = ! empty( $meta['sizes'] ) && \is_array( $meta['sizes'] ) ? $meta['sizes'] : [];
|
580 |
|
581 |
// law = largest accepted width.
|
582 |
$law = 0;
|
583 |
$size = '';
|
584 |
|
585 |
foreach ( $sizes as $_s => $_d ) {
|
|
|
|
|
|
|
586 |
if ( isset( $_d['width'], $_d['height'] ) ) {
|
587 |
if ( $_d['width'] <= $max_size && $_d['height'] <= $max_size && $_d['width'] > $law ) {
|
588 |
$law = $_d['width'];
|
188 |
*
|
189 |
* @since 4.0.0
|
190 |
* @since 4.2.0 Can now return post type archive images from settings.
|
191 |
+
* @since 4.2.4 Now returns filesizes under index `filesize`.
|
192 |
*
|
193 |
* @return array The image details array, sequential: int => {
|
194 |
+
* string url: The image URL,
|
195 |
+
* int id: The image ID,
|
196 |
+
* int width: The image width in pixels,
|
197 |
+
* int height: The image height in pixels,
|
198 |
+
* string alt: The image alt tag,
|
199 |
+
* int filesize: The image filesize in bytes,
|
200 |
* }
|
201 |
*/
|
202 |
protected function get_custom_field_image_details_from_query() {
|
258 |
*
|
259 |
* @since 4.0.0
|
260 |
* @since 4.2.0 Now supports the `$args['pta']` index.
|
261 |
+
* @since 4.2.4 Now returns filesizes under index `filesize`.
|
262 |
*
|
263 |
* @param array $args The query arguments. Must have 'id' and 'taxonomy'.
|
264 |
* @return array The image details array, sequential: int => {
|
265 |
+
* string url: The image URL,
|
266 |
+
* int id: The image ID,
|
267 |
+
* int width: The image width in pixels,
|
268 |
+
* int height: The image height in pixels,
|
269 |
+
* string alt: The image alt tag,
|
270 |
+
* int filesize: The image filesize in bytes,
|
271 |
* }
|
272 |
*/
|
273 |
protected function get_custom_field_image_details_from_args( $args ) {
|
331 |
* @param string $context The filter context. Default 'social'.
|
332 |
* May be (for example) 'breadcrumb' or 'article' for structured data.
|
333 |
* @return array The image generation parameters, associative: {
|
334 |
+
* string size: The image size by name,
|
335 |
* boolean multi: Whether multiple images may be returned,
|
336 |
* array cbs: An array of image generation callbacks, in order of most important to least.
|
337 |
* When 'multi' (or $single input) parameter is "false", it will use the first found.
|
428 |
* Generates image details.
|
429 |
*
|
430 |
* @since 4.0.0
|
431 |
+
* @since 4.2.4 Now returns filesizes under index `filesize`.
|
432 |
*
|
433 |
* @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
|
434 |
* Leave null to autodetermine query.
|
435 |
* @param bool $single Whether to fetch one image, or multiple.
|
436 |
* @param string $context The context of the image generation, albeit 'social', 'schema', etc.
|
437 |
* @return array The image details array, sequential: int => {
|
438 |
+
* string url: The image URL,
|
439 |
+
* int id: The image ID,
|
440 |
+
* int width: The image width in pixels,
|
441 |
+
* int height: The image height in pixels,
|
442 |
+
* string alt: The image alt tag,
|
443 |
+
* int filesize: The image filesize in bytes,
|
444 |
* }
|
445 |
*/
|
446 |
protected function generate_image_details( $args, $single = true, $context = 'social' ) {
|
458 |
* Processes image detail callbacks.
|
459 |
*
|
460 |
* @since 4.0.0
|
461 |
+
* @since 4.2.4 Now returns filesizes under index `filesize`.
|
462 |
*
|
463 |
+
* @param callable[] $cbs The callbacks to parse. Ideally be generators, so we can halt early.
|
464 |
* @param array|null $args The query arguments. Accepts 'id', 'taxonomy', and 'pta'.
|
465 |
* Leave null to autodetermine query.
|
466 |
* @param string $size The image size to use.
|
467 |
* @param bool $single Whether to fetch one image, or multiple.
|
468 |
* @return array The image details array, sequential: int => {
|
469 |
+
* string url: The image URL,
|
470 |
+
* int id: The image ID,
|
471 |
+
* int width: The image width in pixels,
|
472 |
+
* int height: The image height in pixels,
|
473 |
+
* string alt: The image alt tag,
|
474 |
+
* int filesize: The image filesize in bytes,
|
475 |
* }
|
476 |
*/
|
477 |
protected function process_image_cbs( $cbs, $args, $size, $single ) {
|
497 |
* Adds image dimension and alt parameters to the input details, if any.
|
498 |
*
|
499 |
* @since 4.0.0
|
500 |
+
* @since 4.2.4 1. Now returns filesizes under index `filesize`.
|
501 |
+
* 2. No longer processes details when no `id` is given in `$details`.
|
502 |
*
|
503 |
* @param array $details The image details array, associative: {
|
504 |
* string url: The image URL,
|
511 |
* int width: The image width in pixels,
|
512 |
* int height: The image height in pixels,
|
513 |
* string alt: The image alt tag,
|
514 |
+
* int filesize: The image filesize in bytes,
|
515 |
* }
|
516 |
*/
|
517 |
public function merge_extra_image_details( $details, $size = 'full' ) {
|
518 |
|
519 |
+
if ( $details['id'] ) {
|
520 |
+
$details += $this->get_image_dimensions( $details['id'], $details['url'], $size );
|
521 |
+
$details += [ 'alt' => $this->get_image_alt_tag( $details['id'] ) ];
|
522 |
+
$details += [ 'filesize' => $this->get_image_filesize( $details['id'], $details['url'], $size ) ];
|
523 |
+
} else {
|
524 |
+
$details += [
|
525 |
+
'width' => 0,
|
526 |
+
'height' => 0,
|
527 |
+
'url' => '',
|
528 |
+
'filesize' => 0,
|
529 |
+
];
|
530 |
+
}
|
531 |
|
532 |
return $details;
|
533 |
}
|
534 |
|
535 |
/**
|
536 |
+
* Fetches image dimensions.
|
537 |
*
|
538 |
+
* @TODO shift parametes and deprecate using the third one.
|
539 |
* @since 4.0.0
|
540 |
+
* @since 4.2.4 1. No longer relies on `$url` to fetch the correct dimensions, improving performance significantly.
|
541 |
+
* 2. Renamed `$url` to `$depr`, without a deprecation notice added.
|
542 |
*
|
543 |
* @param int $src_id The source ID of the image.
|
544 |
+
* @param string $depr Deprecated. Used to be the source URL of the image.
|
545 |
* @param string $size The size of the image used.
|
546 |
* @return array The image dimensions, associative: {
|
547 |
* int width: The image width in pixels,
|
548 |
* int height: The image height in pixels,
|
549 |
* }
|
550 |
*/
|
551 |
+
public function get_image_dimensions( $src_id, $depr, $size ) {
|
552 |
|
553 |
+
// PHP 7.4+, major version API change.
|
554 |
+
// $size ??= $depr;
|
555 |
+
|
556 |
+
$data = \wp_get_attachment_metadata( $src_id ) ?? [];
|
557 |
+
$data = $data['sizes'][ $size ] ?? $data;
|
558 |
|
559 |
$dimensions = [
|
560 |
'width' => 0,
|
561 |
'height' => 0,
|
562 |
];
|
563 |
|
564 |
+
if ( isset( $data['width'], $data['height'] ) ) {
|
565 |
+
$dimensions['width'] = $data['width'];
|
566 |
+
$dimensions['height'] = $data['height'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
}
|
568 |
|
569 |
return $dimensions;
|
570 |
}
|
571 |
|
572 |
/**
|
573 |
+
* Fetches image dimensions.
|
574 |
*
|
575 |
* @since 4.0.0
|
576 |
*
|
582 |
return $src_id ? trim( strip_tags( \get_post_meta( $src_id, '_wp_attachment_image_alt', true ) ) ) : '';
|
583 |
}
|
584 |
|
585 |
+
/**
|
586 |
+
* Fetches image filesize in bytes. Requires an image (re)generated in WP 6.0 or later.
|
587 |
+
*
|
588 |
+
* @since 4.2.4
|
589 |
+
*
|
590 |
+
* @param int $src_id The source ID of the image.
|
591 |
+
* @param string $size The size of the image used.
|
592 |
+
* @return int The image filesize in bytes. Returns 0 for unprocessed/unprocessable image.
|
593 |
+
*/
|
594 |
+
public function get_image_filesize( $src_id, $size ) {
|
595 |
+
|
596 |
+
$data = \wp_get_attachment_metadata( $src_id ) ?? [];
|
597 |
+
|
598 |
+
return ( $data['sizes'][ $size ]['filesize'] ?? $data['filesize'] ?? 0 ) ?: 0;
|
599 |
+
}
|
600 |
+
|
601 |
/**
|
602 |
* Returns the largest acceptable image size's details.
|
603 |
+
* Skips the original image, which may also be acceptable.
|
604 |
*
|
605 |
* @since 4.0.2
|
606 |
+
* @since 4.2.4 Added parameter `$max_filesize` that filters images larger than it.
|
607 |
*
|
608 |
+
* @param int $id The image ID.
|
609 |
+
* @param int $max_size The largest acceptable dimension in pixels. Accounts for both width and height.
|
610 |
+
* @param int $max_filesize The largest acceptable filesize in bytes. Default 5MB (5242880).
|
611 |
* @return false|array Returns an array (url, width, height, is_intermediate), or false, if no image is available.
|
612 |
*/
|
613 |
+
public function get_largest_acceptable_image_src( $id, $max_size = 4096, $max_filesize = 5242880 ) {
|
614 |
|
615 |
// Imply there's a correct ID set. When there's not, the loop won't run.
|
616 |
+
$sizes = \wp_get_attachment_metadata( $id )['sizes'] ?? [];
|
|
|
617 |
|
618 |
// law = largest accepted width.
|
619 |
$law = 0;
|
620 |
$size = '';
|
621 |
|
622 |
foreach ( $sizes as $_s => $_d ) {
|
623 |
+
if ( ( $_d['filesize'] ?? 0 ) > $max_filesize )
|
624 |
+
continue;
|
625 |
+
|
626 |
if ( isset( $_d['width'], $_d['height'] ) ) {
|
627 |
if ( $_d['width'] <= $max_size && $_d['height'] <= $max_size && $_d['width'] > $law ) {
|
628 |
$law = $_d['width'];
|
inc/classes/generate-ldjson.class.php
CHANGED
@@ -166,6 +166,7 @@ class Generate_Ldjson extends Generate_Image {
|
|
166 |
* @since 2.9.3
|
167 |
* @since 3.0.0 This whole functions now only listens to the searchbox option.
|
168 |
* @since 4.1.2 Now properly slashes the search URL.
|
|
|
169 |
*
|
170 |
* @return string escaped LD+JSON Search and Sitename script.
|
171 |
*/
|
@@ -210,7 +211,10 @@ class Generate_Ldjson extends Generate_Image {
|
|
210 |
'potentialAction' => [
|
211 |
'@type' => 'SearchAction',
|
212 |
// not properly sanitized; however, search_term_string is inert.
|
213 |
-
'target' =>
|
|
|
|
|
|
|
214 |
'query-input' => sprintf( 'required name=%s', $action_name ),
|
215 |
],
|
216 |
];
|
@@ -221,7 +225,7 @@ class Generate_Ldjson extends Generate_Image {
|
|
221 |
$json = $this->receive_json_data( $key );
|
222 |
|
223 |
if ( $json )
|
224 |
-
return '<script type="application/ld+json">' . $json . '</script>' . "\
|
225 |
|
226 |
return '';
|
227 |
}
|
@@ -294,7 +298,7 @@ class Generate_Ldjson extends Generate_Image {
|
|
294 |
$json = $this->receive_json_data( $key );
|
295 |
|
296 |
if ( $json )
|
297 |
-
return '<script type="application/ld+json">' . $json . '</script>' . "\
|
298 |
|
299 |
return '';
|
300 |
}
|
@@ -329,6 +333,7 @@ class Generate_Ldjson extends Generate_Image {
|
|
329 |
* Generates LD+JSON Breadcrumbs script.
|
330 |
*
|
331 |
* @since 2.9.3
|
|
|
332 |
*
|
333 |
* @return string LD+JSON Breadcrumbs script.
|
334 |
*/
|
@@ -340,11 +345,10 @@ class Generate_Ldjson extends Generate_Image {
|
|
340 |
$output = '';
|
341 |
|
342 |
if ( $this->is_singular() && ! $this->is_real_front_page() ) {
|
343 |
-
|
344 |
-
if ( $this->is_single() ) {
|
345 |
-
$output = $this->get_ld_json_breadcrumbs_post();
|
346 |
-
} else {
|
347 |
$output = $this->get_ld_json_breadcrumbs_page();
|
|
|
|
|
348 |
}
|
349 |
}
|
350 |
|
@@ -415,7 +419,7 @@ class Generate_Ldjson extends Generate_Image {
|
|
415 |
|
416 |
$post_id = $this->get_the_real_ID();
|
417 |
$post_type = \get_post_type( $post_id );
|
418 |
-
$taxonomies = $this->get_hierarchical_taxonomies_as( 'names',
|
419 |
|
420 |
/**
|
421 |
* @since 3.0.0
|
@@ -543,7 +547,6 @@ class Generate_Ldjson extends Generate_Image {
|
|
543 |
?: $this->get_static_untitled_title();
|
544 |
}
|
545 |
|
546 |
-
// Store in cache.
|
547 |
$items[] = [
|
548 |
'@type' => 'ListItem',
|
549 |
'position' => $position,
|
@@ -757,7 +760,7 @@ class Generate_Ldjson extends Generate_Image {
|
|
757 |
$it++;
|
758 |
|
759 |
if ( $json )
|
760 |
-
return '<script type="application/ld+json">' . $json . '</script>' . "\
|
761 |
|
762 |
return '';
|
763 |
}
|
166 |
* @since 2.9.3
|
167 |
* @since 3.0.0 This whole functions now only listens to the searchbox option.
|
168 |
* @since 4.1.2 Now properly slashes the search URL.
|
169 |
+
* @since 4.2.4 Added EntryPoint definition (from implied to implicit)
|
170 |
*
|
171 |
* @return string escaped LD+JSON Search and Sitename script.
|
172 |
*/
|
211 |
'potentialAction' => [
|
212 |
'@type' => 'SearchAction',
|
213 |
// not properly sanitized; however, search_term_string is inert.
|
214 |
+
'target' => [
|
215 |
+
'@type' => 'EntryPoint',
|
216 |
+
'urlTemplate' => sprintf( $pattern, \esc_url( $search_url ), $action_name ),
|
217 |
+
],
|
218 |
'query-input' => sprintf( 'required name=%s', $action_name ),
|
219 |
],
|
220 |
];
|
225 |
$json = $this->receive_json_data( $key );
|
226 |
|
227 |
if ( $json )
|
228 |
+
return '<script type="application/ld+json">' . $json . '</script>' . "\n";
|
229 |
|
230 |
return '';
|
231 |
}
|
298 |
$json = $this->receive_json_data( $key );
|
299 |
|
300 |
if ( $json )
|
301 |
+
return '<script type="application/ld+json">' . $json . '</script>' . "\n";
|
302 |
|
303 |
return '';
|
304 |
}
|
333 |
* Generates LD+JSON Breadcrumbs script.
|
334 |
*
|
335 |
* @since 2.9.3
|
336 |
+
* @since 4.2.4 Exchanged "is_single" test for "is_post_type_hierarchical".
|
337 |
*
|
338 |
* @return string LD+JSON Breadcrumbs script.
|
339 |
*/
|
345 |
$output = '';
|
346 |
|
347 |
if ( $this->is_singular() && ! $this->is_real_front_page() ) {
|
348 |
+
if ( \is_post_type_hierarchical( $this->get_post_type_real_ID() ) ) {
|
|
|
|
|
|
|
349 |
$output = $this->get_ld_json_breadcrumbs_page();
|
350 |
+
} else {
|
351 |
+
$output = $this->get_ld_json_breadcrumbs_post();
|
352 |
}
|
353 |
}
|
354 |
|
419 |
|
420 |
$post_id = $this->get_the_real_ID();
|
421 |
$post_type = \get_post_type( $post_id );
|
422 |
+
$taxonomies = $this->get_hierarchical_taxonomies_as( 'names', $post_type );
|
423 |
|
424 |
/**
|
425 |
* @since 3.0.0
|
547 |
?: $this->get_static_untitled_title();
|
548 |
}
|
549 |
|
|
|
550 |
$items[] = [
|
551 |
'@type' => 'ListItem',
|
552 |
'position' => $position,
|
760 |
$it++;
|
761 |
|
762 |
if ( $json )
|
763 |
+
return '<script type="application/ld+json">' . $json . '</script>' . "\n";
|
764 |
|
765 |
return '';
|
766 |
}
|
inc/classes/generate-title.class.php
CHANGED
@@ -713,6 +713,7 @@ class Generate_Title extends Generate_Description {
|
|
713 |
*
|
714 |
* @since 3.1.0
|
715 |
* @since 4.2.0 Flipped order of query tests.
|
|
|
716 |
* @internal
|
717 |
* @see $this->get_raw_generated_title()
|
718 |
*
|
@@ -720,9 +721,7 @@ class Generate_Title extends Generate_Description {
|
|
720 |
*/
|
721 |
protected function generate_title_from_query() {
|
722 |
|
723 |
-
|
724 |
-
|
725 |
-
if ( $this->is_404() ) {
|
726 |
$title = $this->get_static_404_title();
|
727 |
} elseif ( $this->is_search() ) {
|
728 |
$title = $this->get_generated_search_query_title();
|
@@ -734,7 +733,7 @@ class Generate_Title extends Generate_Description {
|
|
734 |
$title = $this->get_generated_archive_title();
|
735 |
}
|
736 |
|
737 |
-
return $title;
|
738 |
}
|
739 |
|
740 |
/**
|
@@ -750,8 +749,6 @@ class Generate_Title extends Generate_Description {
|
|
750 |
*/
|
751 |
protected function generate_title_from_args( $args ) {
|
752 |
|
753 |
-
$title = '';
|
754 |
-
|
755 |
if ( $args['taxonomy'] ) {
|
756 |
$title = $this->get_generated_archive_title( \get_term( $args['id'], $args['taxonomy'] ) );
|
757 |
} elseif ( $args['pta'] ) {
|
@@ -930,14 +927,14 @@ class Generate_Title extends Generate_Description {
|
|
930 |
} elseif ( $this->is_author() ) {
|
931 |
$title = \get_queried_object()->display_name ?? '';
|
932 |
$prefix = \_x( 'Author:', 'author archive title prefix', 'default' );
|
933 |
-
} elseif (
|
934 |
-
if (
|
935 |
$title = \get_the_date( \_x( 'Y', 'yearly archives date format', 'default' ) );
|
936 |
$prefix = \_x( 'Year:', 'date archive title prefix', 'default' );
|
937 |
-
} elseif (
|
938 |
$title = \get_the_date( \_x( 'F Y', 'monthly archives date format', 'default' ) );
|
939 |
$prefix = \_x( 'Month:', 'date archive title prefix', 'default' );
|
940 |
-
} elseif (
|
941 |
$title = \get_the_date( \_x( 'F j, Y', 'daily archives date format', 'default' ) );
|
942 |
$prefix = \_x( 'Day:', 'date archive title prefix', 'default' );
|
943 |
}
|
@@ -1165,6 +1162,7 @@ class Generate_Title extends Generate_Description {
|
|
1165 |
* @return string The untitled title.
|
1166 |
*/
|
1167 |
public function get_static_untitled_title() {
|
|
|
1168 |
return \__( 'Untitled', 'default' );
|
1169 |
}
|
1170 |
|
@@ -1293,7 +1291,7 @@ class Generate_Title extends Generate_Description {
|
|
1293 |
if ( $paged >= 2 || $page >= 2 ) {
|
1294 |
$sep = $this->get_title_separator();
|
1295 |
|
1296 |
-
|
1297 |
$paging = sprintf( \__( 'Page %s', 'default' ), max( $paged, $page ) );
|
1298 |
|
1299 |
if ( \is_rtl() ) {
|
@@ -1311,6 +1309,7 @@ class Generate_Title extends Generate_Description {
|
|
1311 |
* @since 3.1.2 Added strict taxonomical checks for title protection.
|
1312 |
* @since 3.1.3 Fixed conditional logic.
|
1313 |
* @since 4.2.0 Now supports the `$args['pta']` index.
|
|
|
1314 |
* @see $this->merge_title_prefixes()
|
1315 |
*
|
1316 |
* @param string $title The title. Passed by reference.
|
@@ -1321,19 +1320,23 @@ class Generate_Title extends Generate_Description {
|
|
1321 |
public function merge_title_protection( &$title, $args = null ) {
|
1322 |
|
1323 |
if ( null === $args ) {
|
1324 |
-
$id
|
1325 |
-
$
|
1326 |
} else {
|
1327 |
$this->fix_generation_args( $args );
|
1328 |
-
$id
|
1329 |
-
$
|
1330 |
}
|
1331 |
|
1332 |
-
if ( $
|
1333 |
|
1334 |
$post = $id ? \get_post( $id ) : null;
|
1335 |
|
1336 |
-
if (
|
|
|
|
|
|
|
|
|
1337 |
/**
|
1338 |
* Filters the text prepended to the post title of private posts.
|
1339 |
*
|
@@ -1345,10 +1348,13 @@ class Generate_Title extends Generate_Description {
|
|
1345 |
* Default 'Private: %s'.
|
1346 |
* @param WP_Post $post Current post object.
|
1347 |
*/
|
1348 |
-
|
1349 |
-
$protected_title_format = (string) \apply_filters( 'protected_title_format', \__( 'Protected: %s', 'default' ), $post );
|
1350 |
$title = sprintf( $protected_title_format, $title );
|
1351 |
} elseif ( isset( $post->post_status ) && 'private' === $post->post_status ) {
|
|
|
|
|
|
|
|
|
1352 |
/**
|
1353 |
* Filters the text prepended to the post title of private posts.
|
1354 |
*
|
@@ -1360,8 +1366,8 @@ class Generate_Title extends Generate_Description {
|
|
1360 |
* Default 'Private: %s'.
|
1361 |
* @param WP_Post $post Current post object.
|
1362 |
*/
|
1363 |
-
|
1364 |
-
$private_title_format = (string) \apply_filters( 'private_title_format',
|
1365 |
$title = sprintf( $private_title_format, $title );
|
1366 |
}
|
1367 |
}
|
@@ -1454,7 +1460,7 @@ class Generate_Title extends Generate_Description {
|
|
1454 |
|
1455 |
//? Only add pagination if the query is autodetermined, and on a real page.
|
1456 |
if ( null === $args ) {
|
1457 |
-
if (
|
1458 |
$use = false;
|
1459 |
} else {
|
1460 |
$use = true;
|
713 |
*
|
714 |
* @since 3.1.0
|
715 |
* @since 4.2.0 Flipped order of query tests.
|
716 |
+
* @since 4.3.0 Added failover filter for failed queries.
|
717 |
* @internal
|
718 |
* @see $this->get_raw_generated_title()
|
719 |
*
|
721 |
*/
|
722 |
protected function generate_title_from_query() {
|
723 |
|
724 |
+
if ( \is_404() ) {
|
|
|
|
|
725 |
$title = $this->get_static_404_title();
|
726 |
} elseif ( $this->is_search() ) {
|
727 |
$title = $this->get_generated_search_query_title();
|
733 |
$title = $this->get_generated_archive_title();
|
734 |
}
|
735 |
|
736 |
+
return $title ?? '';
|
737 |
}
|
738 |
|
739 |
/**
|
749 |
*/
|
750 |
protected function generate_title_from_args( $args ) {
|
751 |
|
|
|
|
|
752 |
if ( $args['taxonomy'] ) {
|
753 |
$title = $this->get_generated_archive_title( \get_term( $args['id'], $args['taxonomy'] ) );
|
754 |
} elseif ( $args['pta'] ) {
|
927 |
} elseif ( $this->is_author() ) {
|
928 |
$title = \get_queried_object()->display_name ?? '';
|
929 |
$prefix = \_x( 'Author:', 'author archive title prefix', 'default' );
|
930 |
+
} elseif ( \is_date() ) {
|
931 |
+
if ( \is_year() ) {
|
932 |
$title = \get_the_date( \_x( 'Y', 'yearly archives date format', 'default' ) );
|
933 |
$prefix = \_x( 'Year:', 'date archive title prefix', 'default' );
|
934 |
+
} elseif ( \is_month() ) {
|
935 |
$title = \get_the_date( \_x( 'F Y', 'monthly archives date format', 'default' ) );
|
936 |
$prefix = \_x( 'Month:', 'date archive title prefix', 'default' );
|
937 |
+
} elseif ( \is_day() ) {
|
938 |
$title = \get_the_date( \_x( 'F j, Y', 'daily archives date format', 'default' ) );
|
939 |
$prefix = \_x( 'Day:', 'date archive title prefix', 'default' );
|
940 |
}
|
1162 |
* @return string The untitled title.
|
1163 |
*/
|
1164 |
public function get_static_untitled_title() {
|
1165 |
+
// FIXME: WordPress no longer outputs 'Untitled' for the title. It still actively holds this translation, but other context (Widget).
|
1166 |
return \__( 'Untitled', 'default' );
|
1167 |
}
|
1168 |
|
1291 |
if ( $paged >= 2 || $page >= 2 ) {
|
1292 |
$sep = $this->get_title_separator();
|
1293 |
|
1294 |
+
/* translators: %s: Page number. */
|
1295 |
$paging = sprintf( \__( 'Page %s', 'default' ), max( $paged, $page ) );
|
1296 |
|
1297 |
if ( \is_rtl() ) {
|
1309 |
* @since 3.1.2 Added strict taxonomical checks for title protection.
|
1310 |
* @since 3.1.3 Fixed conditional logic.
|
1311 |
* @since 4.2.0 Now supports the `$args['pta']` index.
|
1312 |
+
* @since 4.2.4 Resolved regression where $run-test was reversed (renamed to $merge).
|
1313 |
* @see $this->merge_title_prefixes()
|
1314 |
*
|
1315 |
* @param string $title The title. Passed by reference.
|
1320 |
public function merge_title_protection( &$title, $args = null ) {
|
1321 |
|
1322 |
if ( null === $args ) {
|
1323 |
+
$id = $this->get_the_real_ID();
|
1324 |
+
$merge = $this->is_singular();
|
1325 |
} else {
|
1326 |
$this->fix_generation_args( $args );
|
1327 |
+
$id = $args['id'];
|
1328 |
+
$merge = ! $args['taxonomy'] && ! $args['pta'];
|
1329 |
}
|
1330 |
|
1331 |
+
if ( ! $merge ) return;
|
1332 |
|
1333 |
$post = $id ? \get_post( $id ) : null;
|
1334 |
|
1335 |
+
if ( ! empty( $post->post_password ) ) {
|
1336 |
+
|
1337 |
+
/* translators: %s: Protected post title. */
|
1338 |
+
$prepend = \__( 'Protected: %s', 'default' );
|
1339 |
+
|
1340 |
/**
|
1341 |
* Filters the text prepended to the post title of private posts.
|
1342 |
*
|
1348 |
* Default 'Private: %s'.
|
1349 |
* @param WP_Post $post Current post object.
|
1350 |
*/
|
1351 |
+
$protected_title_format = (string) \apply_filters( 'protected_title_format', $prepend, $post );
|
|
|
1352 |
$title = sprintf( $protected_title_format, $title );
|
1353 |
} elseif ( isset( $post->post_status ) && 'private' === $post->post_status ) {
|
1354 |
+
|
1355 |
+
/* translators: %s: Private post title. */
|
1356 |
+
$prepend = \__( 'Private: %s', 'default' );
|
1357 |
+
|
1358 |
/**
|
1359 |
* Filters the text prepended to the post title of private posts.
|
1360 |
*
|
1366 |
* Default 'Private: %s'.
|
1367 |
* @param WP_Post $post Current post object.
|
1368 |
*/
|
1369 |
+
/* translators: %s: Private post title. */
|
1370 |
+
$private_title_format = (string) \apply_filters( 'private_title_format', $prepend, $post );
|
1371 |
$title = sprintf( $private_title_format, $title );
|
1372 |
}
|
1373 |
}
|
1460 |
|
1461 |
//? Only add pagination if the query is autodetermined, and on a real page.
|
1462 |
if ( null === $args ) {
|
1463 |
+
if ( \is_404() || \is_admin() ) {
|
1464 |
$use = false;
|
1465 |
} else {
|
1466 |
$use = true;
|
inc/classes/generate-url.class.php
CHANGED
@@ -269,12 +269,12 @@ class Generate_Url extends Generate_Title {
|
|
269 |
?: $this->get_post_type_archive_canonical_url();
|
270 |
} elseif ( $this->is_author() ) {
|
271 |
$url = $this->get_author_canonical_url();
|
272 |
-
} elseif (
|
273 |
-
if (
|
274 |
$url = $this->get_date_canonical_url( \get_query_var( 'year' ), \get_query_var( 'monthnum' ), \get_query_var( 'day' ) );
|
275 |
-
} elseif (
|
276 |
$url = $this->get_date_canonical_url( \get_query_var( 'year' ), \get_query_var( 'monthnum' ) );
|
277 |
-
} elseif (
|
278 |
$url = $this->get_date_canonical_url( \get_query_var( 'year' ) );
|
279 |
}
|
280 |
}
|
@@ -866,7 +866,7 @@ class Generate_Url extends Generate_Title {
|
|
866 |
$url = \add_query_arg( [ 'cat' => $id ], $home );
|
867 |
} elseif ( $this->is_tag() ) {
|
868 |
$url = \add_query_arg( [ 'post_tag' => $id ], $home );
|
869 |
-
} elseif (
|
870 |
// FIXME: Core Report: WP doesn't accept paged parameters w/ date parameters. It'll lead to the homepage.
|
871 |
$_query = $GLOBALS['wp_query']->query;
|
872 |
$_date = [
|
269 |
?: $this->get_post_type_archive_canonical_url();
|
270 |
} elseif ( $this->is_author() ) {
|
271 |
$url = $this->get_author_canonical_url();
|
272 |
+
} elseif ( \is_date() ) {
|
273 |
+
if ( \is_day() ) {
|
274 |
$url = $this->get_date_canonical_url( \get_query_var( 'year' ), \get_query_var( 'monthnum' ), \get_query_var( 'day' ) );
|
275 |
+
} elseif ( \is_month() ) {
|
276 |
$url = $this->get_date_canonical_url( \get_query_var( 'year' ), \get_query_var( 'monthnum' ) );
|
277 |
+
} elseif ( \is_year() ) {
|
278 |
$url = $this->get_date_canonical_url( \get_query_var( 'year' ) );
|
279 |
}
|
280 |
}
|
866 |
$url = \add_query_arg( [ 'cat' => $id ], $home );
|
867 |
} elseif ( $this->is_tag() ) {
|
868 |
$url = \add_query_arg( [ 'post_tag' => $id ], $home );
|
869 |
+
} elseif ( \is_date() && isset( $GLOBALS['wp_query']->query ) ) {
|
870 |
// FIXME: Core Report: WP doesn't accept paged parameters w/ date parameters. It'll lead to the homepage.
|
871 |
$_query = $GLOBALS['wp_query']->query;
|
872 |
$_date = [
|
inc/classes/init.class.php
CHANGED
@@ -329,7 +329,7 @@ class Init extends Query {
|
|
329 |
* @since 2.4.1
|
330 |
* @param bool $overwrite_titles Whether to enable legacy title overwriting.
|
331 |
*
|
332 |
-
* TODO remove this block? -- it's been
|
333 |
* <https://make.wordpress.org/core/2015/10/20/document-title-in-4-4/>
|
334 |
*/
|
335 |
if ( \apply_filters( 'the_seo_framework_manipulate_title', true ) ) {
|
@@ -483,7 +483,7 @@ class Init extends Query {
|
|
483 |
*/
|
484 |
public function html_output() {
|
485 |
|
486 |
-
if ( $this->is_preview() ||
|
487 |
|
488 |
/**
|
489 |
* @since 2.6.0
|
@@ -503,7 +503,7 @@ class Init extends Query {
|
|
503 |
$init_start = microtime( true );
|
504 |
|
505 |
// phpcs:disable, WordPress.Security.EscapeOutput -- Output is escaped.
|
506 |
-
echo
|
507 |
|
508 |
$this->do_meta_output();
|
509 |
|
@@ -511,7 +511,7 @@ class Init extends Query {
|
|
511 |
'after',
|
512 |
microtime( true ) - $init_start,
|
513 |
$bootstrap_timer
|
514 |
-
),
|
515 |
// phpcs:enable, WordPress.Security.EscapeOutput
|
516 |
|
517 |
/**
|
@@ -557,7 +557,7 @@ class Init extends Query {
|
|
557 |
'pint_site_output',
|
558 |
]
|
559 |
);
|
560 |
-
elseif (
|
561 |
array_push(
|
562 |
$get,
|
563 |
...[
|
@@ -635,7 +635,7 @@ class Init extends Query {
|
|
635 |
*/
|
636 |
public function _init_custom_field_redirect() {
|
637 |
|
638 |
-
if ( $this->is_preview() ||
|
639 |
|
640 |
$url = $this->get_redirect_url();
|
641 |
|
@@ -767,26 +767,26 @@ class Init extends Query {
|
|
767 |
/**
|
768 |
* @since 2.5.0
|
769 |
* @param string $pre The output before this plugin's output.
|
770 |
-
* Don't forget to add line breaks ( "\
|
771 |
*/
|
772 |
$output = (string) \apply_filters( 'the_seo_framework_robots_txt_pre', '' );
|
773 |
|
774 |
// Output defaults
|
775 |
-
$output .= "User-agent: *\
|
776 |
-
$output .= "Disallow: $site_path/wp-admin/\
|
777 |
-
$output .= "Allow: $site_path/wp-admin/admin-ajax.php\
|
778 |
|
779 |
/**
|
780 |
* @since 2.5.0
|
781 |
* @param bool $disallow Whether to disallow robots queries.
|
782 |
*/
|
783 |
if ( \apply_filters( 'the_seo_framework_robots_disallow_queries', false ) )
|
784 |
-
$output .= "Disallow: /*?*\
|
785 |
|
786 |
/**
|
787 |
* @since 2.5.0
|
788 |
* @param string $pro The output after this plugin's output.
|
789 |
-
* Don't forget to add line breaks ( "\
|
790 |
*/
|
791 |
$output .= (string) \apply_filters( 'the_seo_framework_robots_txt_pro', '' );
|
792 |
|
@@ -797,9 +797,9 @@ class Init extends Query {
|
|
797 |
|
798 |
foreach ( $sitemaps->get_sitemap_endpoint_list() as $id => $data )
|
799 |
if ( ! empty( $data['robots'] ) )
|
800 |
-
$output .= sprintf( "\
|
801 |
|
802 |
-
$output .= "\
|
803 |
} elseif ( ! $this->detect_sitemap_plugin() ) { // detect_sitemap_plugin() temp backward compat.
|
804 |
if ( $this->use_core_sitemaps() ) {
|
805 |
$wp_sitemaps_server = \wp_sitemaps_get_server();
|
@@ -820,7 +820,7 @@ class Init extends Query {
|
|
820 |
// Simple test for invalid directory depth. Even //robots.txt is an invalid location.
|
821 |
if ( strrpos( $raw_uri, '/' ) > 0 ) {
|
822 |
$error = sprintf(
|
823 |
-
"%s\
|
824 |
'# This is an invalid robots.txt location.',
|
825 |
'# Please visit: ' . \esc_url( \trailingslashit( $this->set_preferred_url_scheme( $this->get_home_host() ) ) . 'robots.txt' )
|
826 |
);
|
@@ -860,7 +860,7 @@ class Init extends Query {
|
|
860 |
*/
|
861 |
public function _init_robots_headers() {
|
862 |
|
863 |
-
$noindex =
|
864 |
|
865 |
/**
|
866 |
* @since 4.0.5
|
329 |
* @since 2.4.1
|
330 |
* @param bool $overwrite_titles Whether to enable legacy title overwriting.
|
331 |
*
|
332 |
+
* TODO remove this block? -- it's been 7 years...
|
333 |
* <https://make.wordpress.org/core/2015/10/20/document-title-in-4-4/>
|
334 |
*/
|
335 |
if ( \apply_filters( 'the_seo_framework_manipulate_title', true ) ) {
|
483 |
*/
|
484 |
public function html_output() {
|
485 |
|
486 |
+
if ( $this->is_preview() || \is_customize_preview() || ! $this->query_supports_seo() ) return;
|
487 |
|
488 |
/**
|
489 |
* @since 2.6.0
|
503 |
$init_start = microtime( true );
|
504 |
|
505 |
// phpcs:disable, WordPress.Security.EscapeOutput -- Output is escaped.
|
506 |
+
echo "\n", $this->get_plugin_indicator( 'before' );
|
507 |
|
508 |
$this->do_meta_output();
|
509 |
|
511 |
'after',
|
512 |
microtime( true ) - $init_start,
|
513 |
$bootstrap_timer
|
514 |
+
), "\n";
|
515 |
// phpcs:enable, WordPress.Security.EscapeOutput
|
516 |
|
517 |
/**
|
557 |
'pint_site_output',
|
558 |
]
|
559 |
);
|
560 |
+
elseif ( \is_404() ) :
|
561 |
array_push(
|
562 |
$get,
|
563 |
...[
|
635 |
*/
|
636 |
public function _init_custom_field_redirect() {
|
637 |
|
638 |
+
if ( $this->is_preview() || \is_customize_preview() || ! $this->query_supports_seo() ) return;
|
639 |
|
640 |
$url = $this->get_redirect_url();
|
641 |
|
767 |
/**
|
768 |
* @since 2.5.0
|
769 |
* @param string $pre The output before this plugin's output.
|
770 |
+
* Don't forget to add line breaks ( "\n" )!
|
771 |
*/
|
772 |
$output = (string) \apply_filters( 'the_seo_framework_robots_txt_pre', '' );
|
773 |
|
774 |
// Output defaults
|
775 |
+
$output .= "User-agent: *\n";
|
776 |
+
$output .= "Disallow: $site_path/wp-admin/\n";
|
777 |
+
$output .= "Allow: $site_path/wp-admin/admin-ajax.php\n";
|
778 |
|
779 |
/**
|
780 |
* @since 2.5.0
|
781 |
* @param bool $disallow Whether to disallow robots queries.
|
782 |
*/
|
783 |
if ( \apply_filters( 'the_seo_framework_robots_disallow_queries', false ) )
|
784 |
+
$output .= "Disallow: /*?*\n";
|
785 |
|
786 |
/**
|
787 |
* @since 2.5.0
|
788 |
* @param string $pro The output after this plugin's output.
|
789 |
+
* Don't forget to add line breaks ( "\n" )!
|
790 |
*/
|
791 |
$output .= (string) \apply_filters( 'the_seo_framework_robots_txt_pro', '' );
|
792 |
|
797 |
|
798 |
foreach ( $sitemaps->get_sitemap_endpoint_list() as $id => $data )
|
799 |
if ( ! empty( $data['robots'] ) )
|
800 |
+
$output .= sprintf( "\nSitemap: %s", \esc_url( $sitemaps->get_expected_sitemap_endpoint_url( $id ) ) );
|
801 |
|
802 |
+
$output .= "\n";
|
803 |
} elseif ( ! $this->detect_sitemap_plugin() ) { // detect_sitemap_plugin() temp backward compat.
|
804 |
if ( $this->use_core_sitemaps() ) {
|
805 |
$wp_sitemaps_server = \wp_sitemaps_get_server();
|
820 |
// Simple test for invalid directory depth. Even //robots.txt is an invalid location.
|
821 |
if ( strrpos( $raw_uri, '/' ) > 0 ) {
|
822 |
$error = sprintf(
|
823 |
+
"%s\n%s\n\n",
|
824 |
'# This is an invalid robots.txt location.',
|
825 |
'# Please visit: ' . \esc_url( \trailingslashit( $this->set_preferred_url_scheme( $this->get_home_host() ) ) . 'robots.txt' )
|
826 |
);
|
860 |
*/
|
861 |
public function _init_robots_headers() {
|
862 |
|
863 |
+
$noindex = \is_robots() || ( ! $this->get_option( 'index_the_feed' ) && \is_feed() );
|
864 |
|
865 |
/**
|
866 |
* @since 4.0.5
|
inc/classes/internal/debug.class.php
CHANGED
@@ -359,7 +359,7 @@ final class Debug {
|
|
359 |
$_message = "'<span><strong>$type:</strong> $message";
|
360 |
$_message .= $file ? " In $file" : '';
|
361 |
$_message .= $line ? " on line $line" : '';
|
362 |
-
$_message .=
|
363 |
|
364 |
return $_message;
|
365 |
}
|
@@ -419,7 +419,7 @@ final class Debug {
|
|
419 |
$title = '<div style="display:inline-block;width:100%;padding:20px;margin:0 auto;border-bottom:1px solid #ccc;"><h2 style="font-family:unset;color:#ddd;font-size:22px;padding:0;margin:0">' . $title . '</h2></div>';
|
420 |
|
421 |
// Escape it, replace EOL with breaks, and style everything between quotes (which are ending with space).
|
422 |
-
$output = str_replace(
|
423 |
$output = preg_replace( '/(".*?")(\s|&nbps;)/', '<font color="arnoldschwarzenegger">$1</font> ', $output );
|
424 |
|
425 |
$output = '<div style="display:inline-block;width:100%;padding:20px;font-family:Consolas,Monaco,monospace;font-size:14px;">' . $output . '</div>';
|
@@ -569,7 +569,7 @@ final class Debug {
|
|
569 |
|
570 |
$value = '<font color="harrisonford">' . "$type $value" . '</font>';
|
571 |
$out = \esc_html( $name ) . ' => ' . $value;
|
572 |
-
$output .=
|
573 |
}
|
574 |
|
575 |
foreach ( $not_current as $name => $value ) {
|
@@ -584,7 +584,7 @@ final class Debug {
|
|
584 |
$value = '<font color="harrisonford">' . "$type $value" . '</font>';
|
585 |
$out = \esc_html( $name ) . ' => ' . $value;
|
586 |
|
587 |
-
$output .= $out
|
588 |
}
|
589 |
|
590 |
if ( 'yup' === $cache_version ) {
|
@@ -593,7 +593,7 @@ final class Debug {
|
|
593 |
$title = \is_admin() ? 'Expected Front-end WordPress Query' : 'Current WordPress Query';
|
594 |
}
|
595 |
|
596 |
-
$output = str_replace(
|
597 |
$output = sprintf(
|
598 |
'<div style="display:block;width:100%%;background:#fafafa;color:#333;border-bottom:1px solid #666">%s%s%s</div>',
|
599 |
sprintf(
|
359 |
$_message = "'<span><strong>$type:</strong> $message";
|
360 |
$_message .= $file ? " In $file" : '';
|
361 |
$_message .= $line ? " on line $line" : '';
|
362 |
+
$_message .= "</span><br>\n";
|
363 |
|
364 |
return $_message;
|
365 |
}
|
419 |
$title = '<div style="display:inline-block;width:100%;padding:20px;margin:0 auto;border-bottom:1px solid #ccc;"><h2 style="font-family:unset;color:#ddd;font-size:22px;padding:0;margin:0">' . $title . '</h2></div>';
|
420 |
|
421 |
// Escape it, replace EOL with breaks, and style everything between quotes (which are ending with space).
|
422 |
+
$output = str_replace( [ "\r\n", "\r", "\n" ], "<br>\n", \esc_html( str_replace( str_repeat( ' ', 4 ), str_repeat( ' ', 4 ), $output ) ) );
|
423 |
$output = preg_replace( '/(".*?")(\s|&nbps;)/', '<font color="arnoldschwarzenegger">$1</font> ', $output );
|
424 |
|
425 |
$output = '<div style="display:inline-block;width:100%;padding:20px;font-family:Consolas,Monaco,monospace;font-size:14px;">' . $output . '</div>';
|
569 |
|
570 |
$value = '<font color="harrisonford">' . "$type $value" . '</font>';
|
571 |
$out = \esc_html( $name ) . ' => ' . $value;
|
572 |
+
$output .= "<span style=background:#dadada>$out</span>\n";
|
573 |
}
|
574 |
|
575 |
foreach ( $not_current as $name => $value ) {
|
584 |
$value = '<font color="harrisonford">' . "$type $value" . '</font>';
|
585 |
$out = \esc_html( $name ) . ' => ' . $value;
|
586 |
|
587 |
+
$output .= "$out\n";
|
588 |
}
|
589 |
|
590 |
if ( 'yup' === $cache_version ) {
|
593 |
$title = \is_admin() ? 'Expected Front-end WordPress Query' : 'Current WordPress Query';
|
594 |
}
|
595 |
|
596 |
+
$output = str_replace( [ "\r\n", "\r", "\n" ], "<br>\n", $output );
|
597 |
$output = sprintf(
|
598 |
'<div style="display:block;width:100%%;background:#fafafa;color:#333;border-bottom:1px solid #666">%s%s%s</div>',
|
599 |
sprintf(
|
inc/classes/internal/deprecated.class.php
CHANGED
@@ -144,7 +144,7 @@ final class Deprecated {
|
|
144 |
. $tsf->yandex_site_output()
|
145 |
. $tsf->baidu_site_output()
|
146 |
. $tsf->pint_site_output();
|
147 |
-
elseif (
|
148 |
$output = $tsf->theme_color()
|
149 |
. $tsf->google_site_output()
|
150 |
. $tsf->bing_site_output()
|
@@ -153,7 +153,7 @@ final class Deprecated {
|
|
153 |
. $tsf->pint_site_output();
|
154 |
elseif ( $tsf->is_query_exploited() ) :
|
155 |
// aqp = advanced query protection
|
156 |
-
$output = '<meta name="tsf:aqp" value="1" />' .
|
157 |
else :
|
158 |
// Inefficient concatenation is inefficient. Improve this?
|
159 |
$output = $tsf->the_description()
|
@@ -1504,13 +1504,17 @@ final class Deprecated {
|
|
1504 |
* @since 3.2.2 Removed SEO settings page check. This now returns false on that page.
|
1505 |
* @since 4.2.0 1. No longer casts input $id to integer.
|
1506 |
* 2. Deprecated.
|
|
|
1507 |
* @deprecated
|
1508 |
*
|
1509 |
* @param int $id The page ID, required. Can be 0.
|
1510 |
* @return bool True if ID if for the homepage.
|
1511 |
*/
|
1512 |
public function is_front_page_by_id( $id ) {
|
1513 |
-
|
|
|
|
|
|
|
1514 |
|
1515 |
$pof = (int) \get_option( 'page_on_front' );
|
1516 |
|
@@ -1521,13 +1525,13 @@ final class Deprecated {
|
|
1521 |
|
1522 |
case 'posts':
|
1523 |
$is_front_page =
|
1524 |
-
( 0 === $pof && $
|
1525 |
|| $pof === $id;
|
1526 |
break;
|
1527 |
|
1528 |
default:
|
1529 |
// Elegant Themes's Extra support
|
1530 |
-
$is_front_page = 0 === $id && $
|
1531 |
break;
|
1532 |
endswitch;
|
1533 |
|
@@ -1578,6 +1582,7 @@ final class Deprecated {
|
|
1578 |
* @since 4.0.5 1. The shop ID is now handled via the filter.
|
1579 |
* 2. The question ID (AnsPress) is no longer called. This should work out-of-the-box since AnsPress 4.1.
|
1580 |
* @since 4.2.0 Deprecated
|
|
|
1581 |
* @deprecated
|
1582 |
*
|
1583 |
* @return int The admin ID.
|
@@ -1592,7 +1597,7 @@ final class Deprecated {
|
|
1592 |
*/
|
1593 |
return (int) \apply_filters(
|
1594 |
'the_seo_framework_real_id',
|
1595 |
-
|
1596 |
);
|
1597 |
}
|
1598 |
|
144 |
. $tsf->yandex_site_output()
|
145 |
. $tsf->baidu_site_output()
|
146 |
. $tsf->pint_site_output();
|
147 |
+
elseif ( \is_404() ) :
|
148 |
$output = $tsf->theme_color()
|
149 |
. $tsf->google_site_output()
|
150 |
. $tsf->bing_site_output()
|
153 |
. $tsf->pint_site_output();
|
154 |
elseif ( $tsf->is_query_exploited() ) :
|
155 |
// aqp = advanced query protection
|
156 |
+
$output = '<meta name="tsf:aqp" value="1" />' . "\n";
|
157 |
else :
|
158 |
// Inefficient concatenation is inefficient. Improve this?
|
159 |
$output = $tsf->the_description()
|
1504 |
* @since 3.2.2 Removed SEO settings page check. This now returns false on that page.
|
1505 |
* @since 4.2.0 1. No longer casts input $id to integer.
|
1506 |
* 2. Deprecated.
|
1507 |
+
* @since 4.2.4 No longer causes a fatal error.
|
1508 |
* @deprecated
|
1509 |
*
|
1510 |
* @param int $id The page ID, required. Can be 0.
|
1511 |
* @return bool True if ID if for the homepage.
|
1512 |
*/
|
1513 |
public function is_front_page_by_id( $id ) {
|
1514 |
+
|
1515 |
+
$tsf = \tsf();
|
1516 |
+
|
1517 |
+
$tsf->_deprecated_function( 'tsf()->is_front_page_by_id()', '4.2.0', 'tsf()->is_real_front_page_by_id()' );
|
1518 |
|
1519 |
$pof = (int) \get_option( 'page_on_front' );
|
1520 |
|
1525 |
|
1526 |
case 'posts':
|
1527 |
$is_front_page =
|
1528 |
+
( 0 === $pof && $tsf->is_home() )
|
1529 |
|| $pof === $id;
|
1530 |
break;
|
1531 |
|
1532 |
default:
|
1533 |
// Elegant Themes's Extra support
|
1534 |
+
$is_front_page = 0 === $id && $tsf->is_home();
|
1535 |
break;
|
1536 |
endswitch;
|
1537 |
|
1582 |
* @since 4.0.5 1. The shop ID is now handled via the filter.
|
1583 |
* 2. The question ID (AnsPress) is no longer called. This should work out-of-the-box since AnsPress 4.1.
|
1584 |
* @since 4.2.0 Deprecated
|
1585 |
+
* @since 4.2.4 No longer causes a fatal error.
|
1586 |
* @deprecated
|
1587 |
*
|
1588 |
* @return int The admin ID.
|
1597 |
*/
|
1598 |
return (int) \apply_filters(
|
1599 |
'the_seo_framework_real_id',
|
1600 |
+
\is_feed() ? \get_the_ID() : 0
|
1601 |
);
|
1602 |
}
|
1603 |
|
inc/classes/interpreters/html.class.php
CHANGED
@@ -188,7 +188,7 @@ final class HTML {
|
|
188 |
public static function wrap_fields( $input = '', $echo = false ) {
|
189 |
|
190 |
if ( \is_array( $input ) )
|
191 |
-
$input = implode(
|
192 |
|
193 |
$output = "<div class=tsf-fields>$input</div>";
|
194 |
|
188 |
public static function wrap_fields( $input = '', $echo = false ) {
|
189 |
|
190 |
if ( \is_array( $input ) )
|
191 |
+
$input = implode( "\n", $input );
|
192 |
|
193 |
$output = "<div class=tsf-fields>$input</div>";
|
194 |
|
inc/classes/interpreters/markdown.class.php
CHANGED
@@ -58,11 +58,11 @@ final class Markdown {
|
|
58 |
public static function convert( $text, $convert = [], $args = [] ) {
|
59 |
|
60 |
// preprocess
|
61 |
-
$text = str_replace( "\r\n", "\n", $text );
|
62 |
$text = str_replace( "\t", ' ', $text );
|
63 |
$text = trim( $text );
|
64 |
|
65 |
-
// You need 3 chars to make a markdown: *m*
|
66 |
if ( \strlen( $text ) < 3 )
|
67 |
return '';
|
68 |
|
58 |
public static function convert( $text, $convert = [], $args = [] ) {
|
59 |
|
60 |
// preprocess
|
61 |
+
$text = str_replace( [ "\r\n", "\r" ], "\n", $text );
|
62 |
$text = str_replace( "\t", ' ', $text );
|
63 |
$text = trim( $text );
|
64 |
|
65 |
+
// You need at least 3 chars to make a markdown: *m*
|
66 |
if ( \strlen( $text ) < 3 )
|
67 |
return '';
|
68 |
|
inc/classes/load.class.php
CHANGED
@@ -61,7 +61,7 @@ final class Load extends Cache {
|
|
61 |
/**
|
62 |
* @since 4.1.4
|
63 |
* @access protected
|
64 |
-
* DO NOT OVERWRITE.
|
65 |
* Feel free to read.
|
66 |
* Use constant `THE_SEO_FRAMEWORK_HEADLESS` instead.
|
67 |
* @var bool|array $is_headless Whether headless TSF is enabled.
|
61 |
/**
|
62 |
* @since 4.1.4
|
63 |
* @access protected
|
64 |
+
* DO NOT OVERWRITE, it should be 'immutable'. <https://wiki.php.net/rfc/immutability>
|
65 |
* Feel free to read.
|
66 |
* Use constant `THE_SEO_FRAMEWORK_HEADLESS` instead.
|
67 |
* @var bool|array $is_headless Whether headless TSF is enabled.
|
inc/classes/query.class.php
CHANGED
@@ -195,7 +195,7 @@ class Query extends Core {
|
|
195 |
*/
|
196 |
$id = \apply_filters(
|
197 |
'the_seo_framework_real_id',
|
198 |
-
|
199 |
);
|
200 |
}
|
201 |
|
@@ -309,6 +309,8 @@ class Query extends Core {
|
|
309 |
* Detects 404.
|
310 |
*
|
311 |
* @since 2.6.0
|
|
|
|
|
312 |
*
|
313 |
* @return bool
|
314 |
*/
|
@@ -320,6 +322,8 @@ class Query extends Core {
|
|
320 |
* Detects admin screen.
|
321 |
*
|
322 |
* @since 2.6.0
|
|
|
|
|
323 |
*
|
324 |
* @return bool
|
325 |
*/
|
@@ -590,6 +594,8 @@ class Query extends Core {
|
|
590 |
* in `\WP_Customize_Manager::setup_theme()`.
|
591 |
*
|
592 |
* @since 4.0.0
|
|
|
|
|
593 |
*
|
594 |
* @return bool
|
595 |
*/
|
@@ -601,6 +607,8 @@ class Query extends Core {
|
|
601 |
* Detects date archives.
|
602 |
*
|
603 |
* @since 2.6.0
|
|
|
|
|
604 |
*
|
605 |
* @return bool
|
606 |
*/
|
@@ -612,7 +620,8 @@ class Query extends Core {
|
|
612 |
* Detects day archives.
|
613 |
*
|
614 |
* @since 2.6.0
|
615 |
-
* @
|
|
|
616 |
*
|
617 |
* @return bool
|
618 |
*/
|
@@ -624,6 +633,8 @@ class Query extends Core {
|
|
624 |
* Detects feed.
|
625 |
*
|
626 |
* @since 2.6.0
|
|
|
|
|
627 |
*
|
628 |
* @param string|array $feeds Optional feed types to check.
|
629 |
* @return bool
|
@@ -679,6 +690,8 @@ class Query extends Core {
|
|
679 |
* Detects month archives.
|
680 |
*
|
681 |
* @since 2.6.0
|
|
|
|
|
682 |
*
|
683 |
* @return bool
|
684 |
*/
|
@@ -815,18 +828,14 @@ class Query extends Core {
|
|
815 |
* @since 2.5.2
|
816 |
* @since 3.1.0 Now passes $post_types parameter in admin screens, only when it's an integer.
|
817 |
* @since 4.0.0 No longer processes integers as input.
|
|
|
818 |
* @uses $this->is_singular_admin()
|
819 |
*
|
820 |
-
* @param string|
|
821 |
* @return bool Post Type is singular
|
822 |
*/
|
823 |
public function is_singular( $post_types = '' ) {
|
824 |
|
825 |
-
if ( \is_int( $post_types ) ) {
|
826 |
-
// Integers are no longer accepted.
|
827 |
-
$post_types = '';
|
828 |
-
}
|
829 |
-
|
830 |
// WP_Query functions require loop, do alternative check.
|
831 |
if ( \is_admin() )
|
832 |
return $this->is_singular_admin();
|
@@ -863,6 +872,7 @@ class Query extends Core {
|
|
863 |
*/
|
864 |
public function is_static_frontpage( $id = 0 ) {
|
865 |
|
|
|
866 |
$front_id = umemo( __METHOD__ )
|
867 |
?? umemo(
|
868 |
__METHOD__,
|
@@ -993,6 +1003,8 @@ class Query extends Core {
|
|
993 |
* Detects year archives.
|
994 |
*
|
995 |
* @since 2.6.0
|
|
|
|
|
996 |
*
|
997 |
* @return bool
|
998 |
*/
|
@@ -1235,6 +1247,8 @@ class Query extends Core {
|
|
1235 |
* Determines whether we're on the robots.txt file output.
|
1236 |
*
|
1237 |
* @since 2.9.2
|
|
|
|
|
1238 |
*
|
1239 |
* @return bool
|
1240 |
*/
|
195 |
*/
|
196 |
$id = \apply_filters(
|
197 |
'the_seo_framework_real_id',
|
198 |
+
\is_feed() ? \get_the_ID() : 0
|
199 |
);
|
200 |
}
|
201 |
|
309 |
* Detects 404.
|
310 |
*
|
311 |
* @since 2.6.0
|
312 |
+
* @ignore unused.
|
313 |
+
* @todo deprecate
|
314 |
*
|
315 |
* @return bool
|
316 |
*/
|
322 |
* Detects admin screen.
|
323 |
*
|
324 |
* @since 2.6.0
|
325 |
+
* @ignore unused.
|
326 |
+
* @todo deprecate
|
327 |
*
|
328 |
* @return bool
|
329 |
*/
|
594 |
* in `\WP_Customize_Manager::setup_theme()`.
|
595 |
*
|
596 |
* @since 4.0.0
|
597 |
+
* @ignore unused.
|
598 |
+
* @todo deprecate
|
599 |
*
|
600 |
* @return bool
|
601 |
*/
|
607 |
* Detects date archives.
|
608 |
*
|
609 |
* @since 2.6.0
|
610 |
+
* @ignore unused.
|
611 |
+
* @todo deprecate
|
612 |
*
|
613 |
* @return bool
|
614 |
*/
|
620 |
* Detects day archives.
|
621 |
*
|
622 |
* @since 2.6.0
|
623 |
+
* @ignore unused.
|
624 |
+
* @todo deprecate
|
625 |
*
|
626 |
* @return bool
|
627 |
*/
|
633 |
* Detects feed.
|
634 |
*
|
635 |
* @since 2.6.0
|
636 |
+
* @ignore unused.
|
637 |
+
* @todo deprecate
|
638 |
*
|
639 |
* @param string|array $feeds Optional feed types to check.
|
640 |
* @return bool
|
690 |
* Detects month archives.
|
691 |
*
|
692 |
* @since 2.6.0
|
693 |
+
* @ignore unused.
|
694 |
+
* @todo deprecate
|
695 |
*
|
696 |
* @return bool
|
697 |
*/
|
828 |
* @since 2.5.2
|
829 |
* @since 3.1.0 Now passes $post_types parameter in admin screens, only when it's an integer.
|
830 |
* @since 4.0.0 No longer processes integers as input.
|
831 |
+
* @since 4.2.4 No longer tests type of $post_types.
|
832 |
* @uses $this->is_singular_admin()
|
833 |
*
|
834 |
+
* @param string|string[] $post_types Optional. Post type or array of post types. Default empty string.
|
835 |
* @return bool Post Type is singular
|
836 |
*/
|
837 |
public function is_singular( $post_types = '' ) {
|
838 |
|
|
|
|
|
|
|
|
|
|
|
839 |
// WP_Query functions require loop, do alternative check.
|
840 |
if ( \is_admin() )
|
841 |
return $this->is_singular_admin();
|
872 |
*/
|
873 |
public function is_static_frontpage( $id = 0 ) {
|
874 |
|
875 |
+
// Memo this slow part seperately; memo_query() would cache the whole method, which isn't necessary.
|
876 |
$front_id = umemo( __METHOD__ )
|
877 |
?? umemo(
|
878 |
__METHOD__,
|
1003 |
* Detects year archives.
|
1004 |
*
|
1005 |
* @since 2.6.0
|
1006 |
+
* @ignore unused.
|
1007 |
+
* @todo deprecate
|
1008 |
*
|
1009 |
* @return bool
|
1010 |
*/
|
1247 |
* Determines whether we're on the robots.txt file output.
|
1248 |
*
|
1249 |
* @since 2.9.2
|
1250 |
+
* @ignore unused.
|
1251 |
+
* @todo deprecate
|
1252 |
*
|
1253 |
* @return bool
|
1254 |
*/
|
inc/classes/render.class.php
CHANGED
@@ -75,7 +75,7 @@ class Render extends Admin_Init {
|
|
75 |
* @since 4.0.0 Removed extraneous, unused parameters.
|
76 |
* @see $this->get_title()
|
77 |
*
|
78 |
-
* @param string $title
|
79 |
* @return string $title
|
80 |
*/
|
81 |
public function get_wp_title( $title = '' ) {
|
@@ -212,7 +212,7 @@ class Render extends Admin_Init {
|
|
212 |
);
|
213 |
}
|
214 |
|
215 |
-
return $el . ( $new_line ?
|
216 |
}
|
217 |
|
218 |
/**
|
75 |
* @since 4.0.0 Removed extraneous, unused parameters.
|
76 |
* @see $this->get_title()
|
77 |
*
|
78 |
+
* @param string $title The filterable title.
|
79 |
* @return string $title
|
80 |
*/
|
81 |
public function get_wp_title( $title = '' ) {
|
212 |
);
|
213 |
}
|
214 |
|
215 |
+
return $el . ( $new_line ? "\n" : '' );
|
216 |
}
|
217 |
|
218 |
/**
|
inc/classes/sanitize.class.php
CHANGED
@@ -1640,7 +1640,7 @@ class Sanitize extends Admin_Pages {
|
|
1640 |
* @since 4.0.0 1. Removed rudimentary relative URL testing.
|
1641 |
* 2. Removed input transformation filters, and with that, removed redundant multisite spam protection.
|
1642 |
* 3. Now allows all protocols. Enjoy!
|
1643 |
-
* 4. Now no longer lets through double-absolute URLs (e.g. `https://
|
1644 |
* when filter `the_seo_framework_allow_external_redirect` is set to false.
|
1645 |
*
|
1646 |
* @param string $new_value String with potentially unwanted redirect URL.
|
@@ -1994,15 +1994,17 @@ class Sanitize extends Admin_Pages {
|
|
1994 |
* @since 4.0.5 Now faults images with filename extensions APNG, BMP, ICO, TIFF, or SVG.
|
1995 |
* @since 4.1.4 Fixed theoretical issue where a different image could be set when width
|
1996 |
* and height are supplied and either over 4K, but no ID is given.
|
|
|
1997 |
* @NOTE If the input details are in an associative array, they'll be converted to sequential.
|
1998 |
*
|
1999 |
* @param array $details The image details, either associative (see $defaults) or sequential.
|
2000 |
* @return array The image details array, sequential: int => {
|
2001 |
-
* string url:
|
2002 |
-
* int id:
|
2003 |
-
* int width:
|
2004 |
-
* int height:
|
2005 |
-
* string alt:
|
|
|
2006 |
* }
|
2007 |
*/
|
2008 |
public function s_image_details( $details ) {
|
@@ -2011,14 +2013,15 @@ class Sanitize extends Admin_Pages {
|
|
2011 |
return $this->s_image_details_deep( $details );
|
2012 |
|
2013 |
$defaults = [
|
2014 |
-
'url'
|
2015 |
-
'id'
|
2016 |
-
'width'
|
2017 |
-
'height'
|
2018 |
-
'alt'
|
|
|
2019 |
];
|
2020 |
|
2021 |
-
[ $url, $id, $width, $height, $alt ] = array_values( array_merge( $defaults, $details ) );
|
2022 |
|
2023 |
if ( ! $url ) return $defaults;
|
2024 |
|
@@ -2036,7 +2039,7 @@ class Sanitize extends Admin_Pages {
|
|
2036 |
*
|
2037 |
* Tested with Facebook; they ignore them too. There's no documentation available.
|
2038 |
* TODO Should we even test for this here, or at the image generators' type?
|
2039 |
-
* It seems, however, that
|
2040 |
*/
|
2041 |
if ( \in_array(
|
2042 |
strtolower( strtok( pathinfo( $url, PATHINFO_EXTENSION ), '?' ) ),
|
@@ -2050,8 +2053,8 @@ class Sanitize extends Admin_Pages {
|
|
2050 |
if ( ! $width || ! $height )
|
2051 |
$width = $height = 0;
|
2052 |
|
2053 |
-
if ( $id && ( $width > 4096 || $height > 4096 ) ) {
|
2054 |
-
$new_image = $this->get_largest_acceptable_image_src( $id, 4096 );
|
2055 |
$url = $new_image ? $this->s_url_relative_to_current_scheme( $new_image[0] ) : '';
|
2056 |
|
2057 |
if ( ! $url ) return $defaults;
|
@@ -2068,21 +2071,23 @@ class Sanitize extends Admin_Pages {
|
|
2068 |
$alt = \strlen( $alt ) > 420 ? $this->trim_excerpt( $alt, 0, 420 ) : $alt;
|
2069 |
}
|
2070 |
|
2071 |
-
return compact( 'url', 'id', 'width', 'height', 'alt' );
|
2072 |
}
|
2073 |
|
2074 |
/**
|
2075 |
* Iterates over and cleans known parameters from image details. Also strips out duplicates.
|
2076 |
*
|
2077 |
* @since 4.0.0
|
|
|
2078 |
*
|
2079 |
* @param array $details_array The image details, preferably sequential.
|
2080 |
* @return array The image details array, sequential: int => {
|
2081 |
-
* string url:
|
2082 |
-
* int id:
|
2083 |
-
* int width:
|
2084 |
-
* int height:
|
2085 |
-
* string alt:
|
|
|
2086 |
* }
|
2087 |
*/
|
2088 |
public function s_image_details_deep( $details_array ) {
|
1640 |
* @since 4.0.0 1. Removed rudimentary relative URL testing.
|
1641 |
* 2. Removed input transformation filters, and with that, removed redundant multisite spam protection.
|
1642 |
* 3. Now allows all protocols. Enjoy!
|
1643 |
+
* 4. Now no longer lets through double-absolute URLs (e.g. `https://example.com/https://example.com/path/to/file/`)
|
1644 |
* when filter `the_seo_framework_allow_external_redirect` is set to false.
|
1645 |
*
|
1646 |
* @param string $new_value String with potentially unwanted redirect URL.
|
1994 |
* @since 4.0.5 Now faults images with filename extensions APNG, BMP, ICO, TIFF, or SVG.
|
1995 |
* @since 4.1.4 Fixed theoretical issue where a different image could be set when width
|
1996 |
* and height are supplied and either over 4K, but no ID is given.
|
1997 |
+
* @since 4.2.4 Now accepts, processes, and returns filesizes under index `filesize`.
|
1998 |
* @NOTE If the input details are in an associative array, they'll be converted to sequential.
|
1999 |
*
|
2000 |
* @param array $details The image details, either associative (see $defaults) or sequential.
|
2001 |
* @return array The image details array, sequential: int => {
|
2002 |
+
* string url: The image URL,
|
2003 |
+
* int id: The image ID,
|
2004 |
+
* int width: The image width in pixels,
|
2005 |
+
* int height: The image height in pixels,
|
2006 |
+
* string alt: The image alt tag,
|
2007 |
+
* int filesize: The image filesize in bytes,
|
2008 |
* }
|
2009 |
*/
|
2010 |
public function s_image_details( $details ) {
|
2013 |
return $this->s_image_details_deep( $details );
|
2014 |
|
2015 |
$defaults = [
|
2016 |
+
'url' => '',
|
2017 |
+
'id' => 0,
|
2018 |
+
'width' => 0,
|
2019 |
+
'height' => 0,
|
2020 |
+
'alt' => '',
|
2021 |
+
'filesize' => 0,
|
2022 |
];
|
2023 |
|
2024 |
+
[ $url, $id, $width, $height, $alt, $filesize ] = array_values( array_merge( $defaults, $details ) );
|
2025 |
|
2026 |
if ( ! $url ) return $defaults;
|
2027 |
|
2039 |
*
|
2040 |
* Tested with Facebook; they ignore them too. There's no documentation available.
|
2041 |
* TODO Should we even test for this here, or at the image generators' type?
|
2042 |
+
* It seems, however, that _all_ services we want to communicate with ignore these types, anyway.
|
2043 |
*/
|
2044 |
if ( \in_array(
|
2045 |
strtolower( strtok( pathinfo( $url, PATHINFO_EXTENSION ), '?' ) ),
|
2053 |
if ( ! $width || ! $height )
|
2054 |
$width = $height = 0;
|
2055 |
|
2056 |
+
if ( $id && ( $width > 4096 || $height > 4096 || $filesize > 5 * MB_IN_BYTES ) ) {
|
2057 |
+
$new_image = $this->get_largest_acceptable_image_src( $id, 4096, 5 * MB_IN_BYTES );
|
2058 |
$url = $new_image ? $this->s_url_relative_to_current_scheme( $new_image[0] ) : '';
|
2059 |
|
2060 |
if ( ! $url ) return $defaults;
|
2071 |
$alt = \strlen( $alt ) > 420 ? $this->trim_excerpt( $alt, 0, 420 ) : $alt;
|
2072 |
}
|
2073 |
|
2074 |
+
return compact( 'url', 'id', 'width', 'height', 'alt', 'filesize' );
|
2075 |
}
|
2076 |
|
2077 |
/**
|
2078 |
* Iterates over and cleans known parameters from image details. Also strips out duplicates.
|
2079 |
*
|
2080 |
* @since 4.0.0
|
2081 |
+
* @since 4.2.4 Now accepts, processes, and returns filesizes under index `filesize`.
|
2082 |
*
|
2083 |
* @param array $details_array The image details, preferably sequential.
|
2084 |
* @return array The image details array, sequential: int => {
|
2085 |
+
* string url: The image URL,
|
2086 |
+
* int id: The image ID,
|
2087 |
+
* int width: The image width in pixels,
|
2088 |
+
* int height: The image height in pixels,
|
2089 |
+
* string alt: The image alt tag,
|
2090 |
+
* int filesize: The image filesize in bytes,
|
2091 |
* }
|
2092 |
*/
|
2093 |
public function s_image_details_deep( $details_array ) {
|
inc/classes/site-options.class.php
CHANGED
@@ -50,6 +50,7 @@ class Site_Options extends Sanitize {
|
|
50 |
* @since 2.6.0
|
51 |
* @since 3.1.0 Now applies filters 'the_seo_framework_default_site_options'
|
52 |
* @since 4.0.0 `home_title_location` is now switched from right to left, or vice-versa.
|
|
|
53 |
*
|
54 |
* @return array Default site options.
|
55 |
*/
|
@@ -147,7 +148,7 @@ class Site_Options extends Sanitize {
|
|
147 |
// Robots copyright.
|
148 |
'set_copyright_directives' => 1, // Allow copyright directive settings.
|
149 |
'max_snippet_length' => -1, // Max text-snippet length. -1 = unlimited, 0 = disabled, R>0 = characters.
|
150 |
-
'max_image_preview' => '
|
151 |
'max_video_preview' => -1, // Max video-preview size. -1 = unlimited, 0 = disabled, R>0 = seconds.
|
152 |
|
153 |
// Robots home.
|
50 |
* @since 2.6.0
|
51 |
* @since 3.1.0 Now applies filters 'the_seo_framework_default_site_options'
|
52 |
* @since 4.0.0 `home_title_location` is now switched from right to left, or vice-versa.
|
53 |
+
* @since 4.2.4 `max_image_preview` now defaults to `large`, from `standard`, matching WordPress's default.
|
54 |
*
|
55 |
* @return array Default site options.
|
56 |
*/
|
148 |
// Robots copyright.
|
149 |
'set_copyright_directives' => 1, // Allow copyright directive settings.
|
150 |
'max_snippet_length' => -1, // Max text-snippet length. -1 = unlimited, 0 = disabled, R>0 = characters.
|
151 |
+
'max_image_preview' => 'large', // Max image-preview size. 'none', 'standard', 'large'.
|
152 |
'max_video_preview' => -1, // Max video-preview size. -1 = unlimited, 0 = disabled, R>0 = seconds.
|
153 |
|
154 |
// Robots home.
|
inc/functions/api.php
CHANGED
@@ -282,14 +282,12 @@ namespace The_SEO_Framework {
|
|
282 |
+ debug_backtrace( 0, 2 )[1]
|
283 |
);
|
284 |
|
285 |
-
//
|
286 |
-
if ( isset( $memo[ $hash ] ) )
|
287 |
-
|
|
|
|
|
288 |
|
289 |
-
// Store the result of the function. If that's null/void, store hash.
|
290 |
-
$memo[ $hash ] = \call_user_func( $fn ) ?? $hash;
|
291 |
-
|
292 |
-
// If the hash is stored, return null back to the caller.
|
293 |
return $memo[ $hash ] === $hash ? null : $memo[ $hash ];
|
294 |
}
|
295 |
}
|
282 |
+ debug_backtrace( 0, 2 )[1]
|
283 |
);
|
284 |
|
285 |
+
// Normally, I try to avoid NOTs for they add (tiny) overhead. Here, I chose readability over performance.
|
286 |
+
if ( ! isset( $memo[ $hash ] ) ) {
|
287 |
+
// Store the result of the function. If that's null/void, store hash.
|
288 |
+
$memo[ $hash ] = \call_user_func( $fn ) ?? $hash;
|
289 |
+
}
|
290 |
|
|
|
|
|
|
|
|
|
291 |
return $memo[ $hash ] === $hash ? null : $memo[ $hash ];
|
292 |
}
|
293 |
}
|
inc/functions/upgrade-suggestion.php
CHANGED
@@ -72,14 +72,16 @@ function _prepare( $previous_version, $current_version ) {
|
|
72 |
//? 2
|
73 |
if ( ! \is_main_site() ) return;
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
83 |
|
84 |
//? 3a
|
85 |
if ( \defined( 'TSF_EXTENSION_MANAGER_VERSION' ) ) return;
|
72 |
//? 2
|
73 |
if ( ! \is_main_site() ) return;
|
74 |
|
75 |
+
// phpcs:disable -- There is no sale, leftover code.
|
76 |
+
// $show_sale = true;
|
77 |
+
// if ( \function_exists( '\\tsf_extension_manager' ) && method_exists( \tsf_extension_manager(), 'is_connected_user' ) ) {
|
78 |
+
// $show_sale = ! \tsf_extension_manager()->is_connected_user();
|
79 |
+
// }
|
80 |
+
// if ( $show_sale ) {
|
81 |
+
// // phpcs:ignore, TSF.Performance.Opcodes.ShouldHaveNamespaceEscape
|
82 |
+
// _suggest_temp_sale( $previous_version, $current_version );
|
83 |
+
// }
|
84 |
+
// phpcs:enable
|
85 |
|
86 |
//? 3a
|
87 |
if ( \defined( 'TSF_EXTENSION_MANAGER_VERSION' ) ) return;
|
inc/views/edit/seo-settings-singular.php
CHANGED
@@ -119,7 +119,7 @@ switch ( $this->get_view_instance( 'inpost', $instance ) ) :
|
|
119 |
<?php
|
120 |
HTML::make_info(
|
121 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
122 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
123 |
);
|
124 |
?>
|
125 |
</div>
|
@@ -189,7 +189,7 @@ switch ( $this->get_view_instance( 'inpost', $instance ) ) :
|
|
189 |
<?php
|
190 |
HTML::make_info(
|
191 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
192 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
193 |
);
|
194 |
?>
|
195 |
</div>
|
119 |
<?php
|
120 |
HTML::make_info(
|
121 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
122 |
+
'https://developers.google.com/search/docs/advanced/appearance/title-link'
|
123 |
);
|
124 |
?>
|
125 |
</div>
|
189 |
<?php
|
190 |
HTML::make_info(
|
191 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
192 |
+
'https://developers.google.com/search/docs/advanced/appearance/snippet'
|
193 |
);
|
194 |
?>
|
195 |
</div>
|
inc/views/edit/seo-settings-tt.php
CHANGED
@@ -120,7 +120,7 @@ $robots_settings = [
|
|
120 |
echo ' ';
|
121 |
HTML::make_info(
|
122 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
123 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
124 |
);
|
125 |
?>
|
126 |
</label>
|
@@ -171,7 +171,7 @@ $robots_settings = [
|
|
171 |
echo ' ';
|
172 |
HTML::make_info(
|
173 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
174 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
175 |
);
|
176 |
?>
|
177 |
</label>
|
120 |
echo ' ';
|
121 |
HTML::make_info(
|
122 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
123 |
+
'https://developers.google.com/search/docs/advanced/appearance/title-link'
|
124 |
);
|
125 |
?>
|
126 |
</label>
|
171 |
echo ' ';
|
172 |
HTML::make_info(
|
173 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
174 |
+
'https://developers.google.com/search/docs/advanced/appearance/snippet'
|
175 |
);
|
176 |
?>
|
177 |
</label>
|
inc/views/settings/metaboxes/general.php
CHANGED
@@ -267,8 +267,16 @@ switch ( $this->get_view_instance( 'general', $instance ) ) :
|
|
267 |
'https' => 'HTTPS',
|
268 |
]
|
269 |
);
|
|
|
270 |
foreach ( $scheme_types as $value => $name )
|
271 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
?>
|
273 |
</select>
|
274 |
|
267 |
'https' => 'HTTPS',
|
268 |
]
|
269 |
);
|
270 |
+
$_current = $this->get_option( 'canonical_scheme' );
|
271 |
foreach ( $scheme_types as $value => $name )
|
272 |
+
vprintf(
|
273 |
+
'<option value="%s" %s>%s</option>',
|
274 |
+
[
|
275 |
+
esc_attr( $value ),
|
276 |
+
selected( $_current, esc_attr( $value ), false ),
|
277 |
+
esc_html( $name ),
|
278 |
+
]
|
279 |
+
);
|
280 |
?>
|
281 |
</select>
|
282 |
|
inc/views/settings/metaboxes/homepage.php
CHANGED
@@ -68,7 +68,7 @@ switch ( $this->get_view_instance( 'homepage', $instance ) ) :
|
|
68 |
echo ' ';
|
69 |
HTML::make_info(
|
70 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
71 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
72 |
);
|
73 |
?>
|
74 |
</label>
|
@@ -135,7 +135,7 @@ switch ( $this->get_view_instance( 'homepage', $instance ) ) :
|
|
135 |
echo ' ';
|
136 |
HTML::make_info(
|
137 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
138 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
139 |
);
|
140 |
?>
|
141 |
</label>
|
68 |
echo ' ';
|
69 |
HTML::make_info(
|
70 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
71 |
+
'https://developers.google.com/search/docs/advanced/appearance/title-link'
|
72 |
);
|
73 |
?>
|
74 |
</label>
|
135 |
echo ' ';
|
136 |
HTML::make_info(
|
137 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
138 |
+
'https://developers.google.com/search/docs/advanced/appearance/snippet'
|
139 |
);
|
140 |
?>
|
141 |
</label>
|
inc/views/settings/metaboxes/post-type-archive.php
CHANGED
@@ -154,7 +154,7 @@ switch ( $this->get_view_instance( 'post_type_archive', $instance ) ) :
|
|
154 |
echo ' ';
|
155 |
HTML::make_info(
|
156 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
157 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
158 |
);
|
159 |
?>
|
160 |
</label>
|
@@ -223,7 +223,7 @@ switch ( $this->get_view_instance( 'post_type_archive', $instance ) ) :
|
|
223 |
echo ' ';
|
224 |
HTML::make_info(
|
225 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
226 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
227 |
);
|
228 |
?>
|
229 |
</label>
|
154 |
echo ' ';
|
155 |
HTML::make_info(
|
156 |
__( 'The meta title can be used to determine the title used on search engine result pages.', 'autodescription' ),
|
157 |
+
'https://developers.google.com/search/docs/advanced/appearance/title-link'
|
158 |
);
|
159 |
?>
|
160 |
</label>
|
223 |
echo ' ';
|
224 |
HTML::make_info(
|
225 |
__( 'The meta description can be used to determine the text used under the title on search engine results pages.', 'autodescription' ),
|
226 |
+
'https://developers.google.com/search/docs/advanced/appearance/snippet'
|
227 |
);
|
228 |
?>
|
229 |
</label>
|
inc/views/settings/metaboxes/schema.php
CHANGED
@@ -62,7 +62,7 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
62 |
|
63 |
$info = HTML::make_info(
|
64 |
__( 'Learn how this data is used.', 'autodescription' ),
|
65 |
-
'https://developers.google.com/search/docs/data
|
66 |
false
|
67 |
);
|
68 |
HTML::wrap_fields(
|
@@ -82,7 +82,7 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
82 |
|
83 |
$info = HTML::make_info(
|
84 |
__( 'Learn how this data is used.', 'autodescription' ),
|
85 |
-
'https://developers.google.com/search/docs/data
|
86 |
false
|
87 |
);
|
88 |
HTML::wrap_fields(
|
@@ -101,7 +101,7 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
101 |
|
102 |
$info = HTML::make_info(
|
103 |
__( 'Learn how this data is used.', 'autodescription' ),
|
104 |
-
'https://developers.google.com/search/docs/
|
105 |
false
|
106 |
);
|
107 |
HTML::wrap_fields(
|
@@ -127,9 +127,16 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
127 |
'person' => __( 'A Person', 'autodescription' ),
|
128 |
]
|
129 |
);
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
?>
|
134 |
</select>
|
135 |
</p>
|
@@ -148,7 +155,7 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
148 |
HTML::description( esc_html__( 'These options are used when this site represents an organization. When no logo is outputted, search engine will look elsewhere.', 'autodescription' ) );
|
149 |
$info = HTML::make_info(
|
150 |
__( 'Learn how this data is used.', 'autodescription' ),
|
151 |
-
'https://developers.google.com/search/docs/data
|
152 |
false
|
153 |
);
|
154 |
HTML::wrap_fields(
|
@@ -178,10 +185,10 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
178 |
'id' => 'knowledge_logo',
|
179 |
'data' => [
|
180 |
'inputType' => 'logo',
|
181 |
-
'width' => 512,
|
182 |
-
'height' => 512,
|
183 |
-
'minWidth' => 112,
|
184 |
-
'minHeight' => 112,
|
185 |
'flex' => true,
|
186 |
],
|
187 |
'i18n' => [
|
@@ -289,7 +296,7 @@ switch ( $this->get_view_instance( 'schema', $instance ) ) :
|
|
289 |
sprintf(
|
290 |
/* translators: %s = Learn more URL. Markdown! */
|
291 |
esc_html__( 'These settings are marked for removal. When you clear a field, it will be hidden forever. [Learn more](%s).', 'autodescription' ),
|
292 |
-
'https://
|
293 |
),
|
294 |
[ 'a' ],
|
295 |
[ 'a_internal' => false ]
|
62 |
|
63 |
$info = HTML::make_info(
|
64 |
__( 'Learn how this data is used.', 'autodescription' ),
|
65 |
+
'https://developers.google.com/search/docs/advanced/structured-data/breadcrumb',
|
66 |
false
|
67 |
);
|
68 |
HTML::wrap_fields(
|
82 |
|
83 |
$info = HTML::make_info(
|
84 |
__( 'Learn how this data is used.', 'autodescription' ),
|
85 |
+
'https://developers.google.com/search/docs/advanced/structured-data/sitelinks-searchbox',
|
86 |
false
|
87 |
);
|
88 |
HTML::wrap_fields(
|
101 |
|
102 |
$info = HTML::make_info(
|
103 |
__( 'Learn how this data is used.', 'autodescription' ),
|
104 |
+
'https://developers.google.com/search/docs/beginner/establish-business-details',
|
105 |
false
|
106 |
);
|
107 |
HTML::wrap_fields(
|
127 |
'person' => __( 'A Person', 'autodescription' ),
|
128 |
]
|
129 |
);
|
130 |
+
$_current = $this->get_option( 'knowledge_type' );
|
131 |
+
foreach ( $knowledge_type as $value => $name )
|
132 |
+
vprintf(
|
133 |
+
'<option value="%s" %s>%s</option>',
|
134 |
+
[
|
135 |
+
esc_attr( $value ),
|
136 |
+
selected( $_current, esc_attr( $value ), false ),
|
137 |
+
esc_html( $name ),
|
138 |
+
]
|
139 |
+
);
|
140 |
?>
|
141 |
</select>
|
142 |
</p>
|
155 |
HTML::description( esc_html__( 'These options are used when this site represents an organization. When no logo is outputted, search engine will look elsewhere.', 'autodescription' ) );
|
156 |
$info = HTML::make_info(
|
157 |
__( 'Learn how this data is used.', 'autodescription' ),
|
158 |
+
'https://developers.google.com/search/docs/advanced/structured-data/logo',
|
159 |
false
|
160 |
);
|
161 |
HTML::wrap_fields(
|
185 |
'id' => 'knowledge_logo',
|
186 |
'data' => [
|
187 |
'inputType' => 'logo',
|
188 |
+
'width' => 512, // Magic number -> Google requirement? "MAGIC::GOOGLE->LOGO_MAX"?
|
189 |
+
'height' => 512, // Magic number
|
190 |
+
'minWidth' => 112, // Magic number -> Google requirement? "MAGIC::GOOGLE->LOGO_MIN"?
|
191 |
+
'minHeight' => 112, // Magic number
|
192 |
'flex' => true,
|
193 |
],
|
194 |
'i18n' => [
|
296 |
sprintf(
|
297 |
/* translators: %s = Learn more URL. Markdown! */
|
298 |
esc_html__( 'These settings are marked for removal. When you clear a field, it will be hidden forever. [Learn more](%s).', 'autodescription' ),
|
299 |
+
'https://support.google.com/knowledgepanel/answer/7534842'
|
300 |
),
|
301 |
[ 'a' ],
|
302 |
[ 'a_internal' => false ]
|
inc/views/settings/metaboxes/sitemaps.php
CHANGED
@@ -361,7 +361,7 @@ switch ( $this->get_view_instance( 'sitemaps', $instance ) ) :
|
|
361 |
);
|
362 |
|
363 |
$ph_id = get_theme_mod( 'custom_logo' ) ?: 0;
|
364 |
-
$ph_src = $ph_id ? wp_get_attachment_image_src( $ph_id, [ 29, 29 ] ) : [];
|
365 |
|
366 |
$logo_placeholder = ! empty( $ph_src[0] ) ? $ph_src[0] : '';
|
367 |
?>
|
@@ -383,10 +383,10 @@ switch ( $this->get_view_instance( 'sitemaps', $instance ) ) :
|
|
383 |
'id' => 'sitemap_logo',
|
384 |
'data' => [
|
385 |
'inputType' => 'logo',
|
386 |
-
'width' => 512,
|
387 |
-
'height' => 512,
|
388 |
-
'minWidth' => 64,
|
389 |
-
'minHeight' => 64,
|
390 |
'flex' => true,
|
391 |
],
|
392 |
'i18n' => [
|
361 |
);
|
362 |
|
363 |
$ph_id = get_theme_mod( 'custom_logo' ) ?: 0;
|
364 |
+
$ph_src = $ph_id ? wp_get_attachment_image_src( $ph_id, [ 29, 29 ] ) : []; // TODO magic number "SITEMAP_LOGO_PX"
|
365 |
|
366 |
$logo_placeholder = ! empty( $ph_src[0] ) ? $ph_src[0] : '';
|
367 |
?>
|
383 |
'id' => 'sitemap_logo',
|
384 |
'data' => [
|
385 |
'inputType' => 'logo',
|
386 |
+
'width' => 512, // Magic number "CUSTOMIZER_LOGO_MAX" (should be defined in WP?)
|
387 |
+
'height' => 512, // Magic number
|
388 |
+
'minWidth' => 64, // Magic number "CUSTOMIZER_LOGO_MIN" (should be defined in WP?)
|
389 |
+
'minHeight' => 64, // Magic number
|
390 |
'flex' => true,
|
391 |
],
|
392 |
'i18n' => [
|
inc/views/settings/metaboxes/title.php
CHANGED
@@ -104,10 +104,9 @@ switch ( $this->get_view_instance( 'title', $instance ) ) :
|
|
104 |
<hr>
|
105 |
<?php
|
106 |
if (
|
107 |
-
|
108 |
&& ! current_theme_supports( 'title-tag' )
|
109 |
&& ! defined( 'TSFEM_E_TITLE_FIX' )
|
110 |
-
&& current_user_can( 'install_plugins' )
|
111 |
) {
|
112 |
?>
|
113 |
<h4>
|
@@ -283,7 +282,7 @@ switch ( $this->get_view_instance( 'title', $instance ) ) :
|
|
283 |
<?php
|
284 |
$info = HTML::make_info(
|
285 |
__( 'Always brand your titles. Search engines may ignore your titles with this feature enabled.', 'autodescription' ),
|
286 |
-
'https://developers.google.com/search/docs/advanced/appearance/
|
287 |
false
|
288 |
);
|
289 |
|
104 |
<hr>
|
105 |
<?php
|
106 |
if (
|
107 |
+
$this->_display_extension_suggestions()
|
108 |
&& ! current_theme_supports( 'title-tag' )
|
109 |
&& ! defined( 'TSFEM_E_TITLE_FIX' )
|
|
|
110 |
) {
|
111 |
?>
|
112 |
<h4>
|
282 |
<?php
|
283 |
$info = HTML::make_info(
|
284 |
__( 'Always brand your titles. Search engines may ignore your titles with this feature enabled.', 'autodescription' ),
|
285 |
+
'https://developers.google.com/search/docs/advanced/appearance/title-link',
|
286 |
false
|
287 |
);
|
288 |
|
inc/views/settings/wrap.php
CHANGED
@@ -12,18 +12,38 @@ use The_SEO_Framework\Interpreters\HTML,
|
|
12 |
|
13 |
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) and tsf()->_verify_include_secret( $_secret ) or die;
|
14 |
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
-
$_save_button
|
18 |
__( 'Save Settings', 'autodescription' ),
|
19 |
-
'primary',
|
20 |
'submit',
|
21 |
false,
|
22 |
[ 'id' => '' ] // we ouput this twice, don't set ID.
|
23 |
);
|
|
|
|
|
24 |
$_reset_button = get_submit_button(
|
25 |
__( 'Reset Settings', 'autodescription' ),
|
26 |
-
'secondary',
|
27 |
Input::get_field_name( 'tsf-settings-reset' ),
|
28 |
false,
|
29 |
[
|
@@ -41,12 +61,12 @@ $_reset_button = get_submit_button(
|
|
41 |
|
42 |
<div class=tsf-top-wrap>
|
43 |
<h1><?= esc_html( get_admin_page_title() ) ?></h1>
|
44 |
-
<
|
45 |
<?php
|
46 |
// phpcs:ignore, WordPress.Security.EscapeOutput.OutputNotEscaped -- submit_button() escapes (mostly...)
|
47 |
-
echo $_save_button, $_reset_button;
|
48 |
?>
|
49 |
-
</
|
50 |
</div>
|
51 |
|
52 |
<hr class=wp-header-end>
|
@@ -61,11 +81,19 @@ $_reset_button = get_submit_button(
|
|
61 |
do_action( "{$this->seo_settings_page_hook}_settings_page_boxes", $this->seo_settings_page_hook );
|
62 |
?>
|
63 |
|
64 |
-
<div class=tsf-bottom-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
</div>
|
70 |
</form>
|
71 |
</div>
|
12 |
|
13 |
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) and tsf()->_verify_include_secret( $_secret ) or die;
|
14 |
|
15 |
+
if ( function_exists( 'tsf_extension_manager' )
|
16 |
+
&& in_array(
|
17 |
+
tsf_extension_manager()->seo_extensions_page_slug ?? null,
|
18 |
+
array_column( $GLOBALS['submenu'][ $this->seo_settings_page_slug ] ?? [], 2 ),
|
19 |
+
true
|
20 |
+
)
|
21 |
+
) {
|
22 |
+
$_extensions_button = sprintf(
|
23 |
+
'<a href="%s" class="button">%s</a>',
|
24 |
+
menu_page_url( tsf_extension_manager()->seo_extensions_page_slug, false ),
|
25 |
+
esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
|
26 |
+
);
|
27 |
+
} else {
|
28 |
+
$_extensions_button = $this->_display_extension_suggestions() ? sprintf(
|
29 |
+
'<a href="%s" class="button" rel="noreferrer noopener" target=_blank>%s</a>',
|
30 |
+
'https://theseoframework.com/?p=3599',
|
31 |
+
esc_html_x( 'Extensions', 'Plugin extensions', 'autodescription' )
|
32 |
+
) : '';
|
33 |
+
}
|
34 |
|
35 |
+
$_save_button = get_submit_button(
|
36 |
__( 'Save Settings', 'autodescription' ),
|
37 |
+
[ 'primary' ],
|
38 |
'submit',
|
39 |
false,
|
40 |
[ 'id' => '' ] // we ouput this twice, don't set ID.
|
41 |
);
|
42 |
+
|
43 |
+
$_ays_reset = esc_js( __( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ) );
|
44 |
$_reset_button = get_submit_button(
|
45 |
__( 'Reset Settings', 'autodescription' ),
|
46 |
+
[ 'secondary' ],
|
47 |
Input::get_field_name( 'tsf-settings-reset' ),
|
48 |
false,
|
49 |
[
|
61 |
|
62 |
<div class=tsf-top-wrap>
|
63 |
<h1><?= esc_html( get_admin_page_title() ) ?></h1>
|
64 |
+
<div class="tsf-top-buttons tsf-end">
|
65 |
<?php
|
66 |
// phpcs:ignore, WordPress.Security.EscapeOutput.OutputNotEscaped -- submit_button() escapes (mostly...)
|
67 |
+
echo $_save_button, $_reset_button, $_extensions_button;
|
68 |
?>
|
69 |
+
</div>
|
70 |
</div>
|
71 |
|
72 |
<hr class=wp-header-end>
|
81 |
do_action( "{$this->seo_settings_page_hook}_settings_page_boxes", $this->seo_settings_page_hook );
|
82 |
?>
|
83 |
|
84 |
+
<div class=tsf-bottom-wrap>
|
85 |
+
<div class="tsf-bottom-buttons tsf-start">
|
86 |
+
<?php
|
87 |
+
// phpcs:ignore, WordPress.Security.EscapeOutput.OutputNotEscaped -- submit_button() escapes (mostly...)
|
88 |
+
echo $_extensions_button;
|
89 |
+
?>
|
90 |
+
</div>
|
91 |
+
<div class="tsf-bottom-buttons tsf-end">
|
92 |
+
<?php
|
93 |
+
// phpcs:ignore, WordPress.Security.EscapeOutput.OutputNotEscaped -- submit_button() escapes (mostly...)
|
94 |
+
echo $_save_button;
|
95 |
+
?>
|
96 |
+
</div>
|
97 |
</div>
|
98 |
</form>
|
99 |
</div>
|
inc/views/sitemap/xml-sitemap.php
CHANGED
@@ -16,8 +16,8 @@ $sitemap_bridge = The_SEO_Framework\Bridges\Sitemap::get_instance();
|
|
16 |
$sitemap_bridge->output_sitemap_header();
|
17 |
|
18 |
if ( $this->the_seo_framework_debug ) {
|
19 |
-
echo '<!-- Site estimated peak usage prior to generation: ' . number_format( memory_get_peak_usage() /
|
20 |
-
echo '<!-- System estimated peak usage prior to generation: ' . number_format( memory_get_peak_usage( true ) /
|
21 |
}
|
22 |
|
23 |
$sitemap_bridge->output_sitemap_urlset_open_tag();
|
@@ -34,15 +34,15 @@ if ( $sitemap_base->base_is_regenerated ) {
|
|
34 |
echo "\n" . '<!-- ' . esc_html__( 'Sitemap is served from cache', 'autodescription' ) . ' -->';
|
35 |
}
|
36 |
|
37 |
-
//
|
38 |
$sitemap_base = null;
|
39 |
|
40 |
if ( $this->the_seo_framework_debug ) {
|
41 |
-
echo "\n" . '<!-- Site estimated current usage: ' . number_format( memory_get_usage() /
|
42 |
-
echo "\n" . '<!-- System estimated current usage: ' . number_format( memory_get_usage( true ) /
|
43 |
-
echo "\n" . '<!-- Site estimated peak usage: ' . number_format( memory_get_peak_usage() /
|
44 |
-
echo "\n" . '<!-- System estimated peak usage: ' . number_format( memory_get_peak_usage( true ) /
|
45 |
-
echo "\n" . '<!-- Freed memory prior to generation: ' . number_format( $sitemap_bridge->get_freed_memory( true ) /
|
46 |
echo "\n" . '<!-- Sitemap generation time: ' . number_format( microtime( true ) - $timer_start, 6 ) . ' seconds -->';
|
47 |
echo "\n" . '<!-- Sitemap caching enabled: ' . ( $this->get_option( 'cache_sitemap' ) ? 'yes' : 'no' ) . ' -->';
|
48 |
echo "\n" . '<!-- Sitemap transient key: ' . esc_html( $this->get_sitemap_transient_name() ) . ' -->';
|
16 |
$sitemap_bridge->output_sitemap_header();
|
17 |
|
18 |
if ( $this->the_seo_framework_debug ) {
|
19 |
+
echo '<!-- Site estimated peak usage prior to generation: ' . number_format( memory_get_peak_usage() / MB_IN_BYTES, 3 ) . ' MB -->' . "\n";
|
20 |
+
echo '<!-- System estimated peak usage prior to generation: ' . number_format( memory_get_peak_usage( true ) / MB_IN_BYTES, 3 ) . ' MB -->' . "\n";
|
21 |
}
|
22 |
|
23 |
$sitemap_bridge->output_sitemap_urlset_open_tag();
|
34 |
echo "\n" . '<!-- ' . esc_html__( 'Sitemap is served from cache', 'autodescription' ) . ' -->';
|
35 |
}
|
36 |
|
37 |
+
// Destruct class.
|
38 |
$sitemap_base = null;
|
39 |
|
40 |
if ( $this->the_seo_framework_debug ) {
|
41 |
+
echo "\n" . '<!-- Site estimated current usage: ' . number_format( memory_get_usage() / MB_IN_BYTES, 3 ) . ' MB -->';
|
42 |
+
echo "\n" . '<!-- System estimated current usage: ' . number_format( memory_get_usage( true ) / MB_IN_BYTES, 3 ) . ' MB -->';
|
43 |
+
echo "\n" . '<!-- Site estimated peak usage: ' . number_format( memory_get_peak_usage() / MB_IN_BYTES, 3 ) . ' MB -->';
|
44 |
+
echo "\n" . '<!-- System estimated peak usage: ' . number_format( memory_get_peak_usage( true ) / MB_IN_BYTES, 3 ) . ' MB -->';
|
45 |
+
echo "\n" . '<!-- Freed memory prior to generation: ' . number_format( $sitemap_bridge->get_freed_memory( true ) / KB_IN_BYTES, 3 ) . ' kB -->';
|
46 |
echo "\n" . '<!-- Sitemap generation time: ' . number_format( microtime( true ) - $timer_start, 6 ) . ' seconds -->';
|
47 |
echo "\n" . '<!-- Sitemap caching enabled: ' . ( $this->get_option( 'cache_sitemap' ) ? 'yes' : 'no' ) . ' -->';
|
48 |
echo "\n" . '<!-- Sitemap transient key: ' . esc_html( $this->get_sitemap_transient_name() ) . ' -->';
|
inc/views/sitemap/xsl-stylesheet.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) and tsf()->_verify_include_secret( $_secret ) or die;
|
11 |
|
12 |
// echo here, otherwise XML closes PHP...
|
13 |
-
echo '<?xml version="1.0" encoding="UTF-8"?>',
|
14 |
|
15 |
?>
|
16 |
<xsl:stylesheet version="2.0"
|
10 |
defined( 'THE_SEO_FRAMEWORK_PRESENT' ) and tsf()->_verify_include_secret( $_secret ) or die;
|
11 |
|
12 |
// echo here, otherwise XML closes PHP...
|
13 |
+
echo '<?xml version="1.0" encoding="UTF-8"?>', "\n";
|
14 |
|
15 |
?>
|
16 |
<xsl:stylesheet version="2.0"
|
inc/views/sitemap/xsl/description.php
CHANGED
@@ -13,12 +13,12 @@ $logo = '';
|
|
13 |
if ( $this->get_option( 'sitemap_logo' ) ) {
|
14 |
|
15 |
$id = $this->get_option( 'sitemap_logo_id' ) ?: 0;
|
16 |
-
$_src = $id ? wp_get_attachment_image_src( $id, [ 29, 29 ] ) : [];
|
17 |
|
18 |
// Fallback to theme mod.
|
19 |
if ( ! $_src ) {
|
20 |
$id = get_theme_mod( 'custom_logo' ) ?: 0;
|
21 |
-
$_src = $id ? wp_get_attachment_image_src( $id, [ 29, 29 ] ) : [];
|
22 |
}
|
23 |
|
24 |
/**
|
13 |
if ( $this->get_option( 'sitemap_logo' ) ) {
|
14 |
|
15 |
$id = $this->get_option( 'sitemap_logo_id' ) ?: 0;
|
16 |
+
$_src = $id ? wp_get_attachment_image_src( $id, [ 29, 29 ] ) : []; // Magic number "SITEMAP_LOGO_PX"
|
17 |
|
18 |
// Fallback to theme mod.
|
19 |
if ( ! $_src ) {
|
20 |
$id = get_theme_mod( 'custom_logo' ) ?: 0;
|
21 |
+
$_src = $id ? wp_get_attachment_image_src( $id, [ 29, 29 ] ) : []; // Magic number "SITEMAP_LOGO_PX"
|
22 |
}
|
23 |
|
24 |
/**
|
lib/css/settings.css
CHANGED
@@ -5,42 +5,57 @@
|
|
5 |
}
|
6 |
|
7 |
.tsf-top-wrap {
|
8 |
-
|
9 |
-
|
10 |
-
vertical-align: top;
|
11 |
-
}
|
12 |
-
|
13 |
-
.tsf-top-wrap > h1 {
|
14 |
-
float: left;
|
15 |
-
}
|
16 |
-
|
17 |
-
body.rtl .tsf-top-wrap > h1 {
|
18 |
-
float: right;
|
19 |
}
|
20 |
|
21 |
-
.tsf-
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
|
|
25 |
.tsf-top-buttons {
|
26 |
-
|
27 |
}
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
|
37 |
-
|
38 |
-
|
|
|
39 |
}
|
40 |
|
41 |
-
.tsf-metaboxes .
|
42 |
-
|
43 |
-
margin-left: 10px;
|
44 |
}
|
45 |
|
46 |
#tsf-title-separator {
|
@@ -182,7 +197,6 @@ body.rtl .tsf-bottom-buttons {
|
|
182 |
font-weight: 600;
|
183 |
border-radius: 3px 3px 0 0;
|
184 |
}
|
185 |
-
|
186 |
body.rtl .tsf-nav-tab-label {
|
187 |
float: right;
|
188 |
margin-left: 0;
|
5 |
}
|
6 |
|
7 |
.tsf-top-wrap {
|
8 |
+
/* About half of notification height */
|
9 |
+
margin-bottom: 8px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
}
|
11 |
|
12 |
+
.tsf-top-wrap,
|
13 |
+
.tsf-bottom-wrap {
|
14 |
+
width: 100%;
|
15 |
+
display: flex;
|
16 |
+
justify-content: space-between;
|
17 |
+
flex: 1 1 100%;
|
18 |
+
flex-flow: row wrap;
|
19 |
+
gap: 10px;
|
20 |
}
|
21 |
|
22 |
+
/* Matches .wrap h1 */
|
23 |
.tsf-top-buttons {
|
24 |
+
padding: 9px 0 4px;
|
25 |
}
|
26 |
+
.tsf-top-buttons,
|
27 |
+
.tsf-bottom-buttons {
|
28 |
+
display: flex;
|
29 |
+
flex: 1 1 auto;
|
30 |
+
justify-content: start;
|
31 |
+
flex-flow: row wrap;
|
32 |
+
gap: 10px;
|
33 |
+
}
|
34 |
+
.tsf-top-buttons.tsf-end,
|
35 |
+
.tsf-bottom-buttons.tsf-end {
|
36 |
+
justify-content: flex-end;
|
37 |
}
|
38 |
|
39 |
+
@media screen and (max-width: 782px) {
|
40 |
+
.tsf-top-wrap,
|
41 |
+
.tsf-bottom-wrap,
|
42 |
+
.tsf-top-buttons.tsf-end,
|
43 |
+
.tsf-bottom-buttons.tsf-end {
|
44 |
+
justify-content: start;
|
45 |
+
}
|
46 |
+
.tsf-top-buttons,
|
47 |
+
.tsf-bottom-buttons {
|
48 |
+
width: 100%;
|
49 |
+
}
|
50 |
}
|
51 |
|
52 |
+
.tsf-metaboxes .tsf-top-buttons > *,
|
53 |
+
.tsf-metaboxes .tsf-bottom-buttons > * {
|
54 |
+
text-align: center;
|
55 |
}
|
56 |
|
57 |
+
.tsf-metaboxes .metabox-holder {
|
58 |
+
clear: both;
|
|
|
59 |
}
|
60 |
|
61 |
#tsf-title-separator {
|
197 |
font-weight: 600;
|
198 |
border-radius: 3px 3px 0 0;
|
199 |
}
|
|
|
200 |
body.rtl .tsf-nav-tab-label {
|
201 |
float: right;
|
202 |
margin-left: 0;
|
lib/css/settings.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tsf-metaboxes{box-sizing:border-box;max-width:740px;padding-bottom:20px}.tsf-top-wrap{width:100%;display:
|
1 |
+
.tsf-metaboxes{box-sizing:border-box;max-width:740px;padding-bottom:20px}.tsf-top-wrap{margin-bottom:8px}.tsf-bottom-wrap,.tsf-top-wrap{width:100%;display:flex;justify-content:space-between;flex:1 1 100%;flex-flow:row wrap;gap:10px}.tsf-top-buttons{padding:9px 0 4px}.tsf-bottom-buttons,.tsf-top-buttons{display:flex;flex:1 1 auto;justify-content:start;flex-flow:row wrap;gap:10px}.tsf-bottom-buttons.tsf-end,.tsf-top-buttons.tsf-end{justify-content:flex-end}@media screen and (max-width:782px){.tsf-bottom-buttons.tsf-end,.tsf-bottom-wrap,.tsf-top-buttons.tsf-end,.tsf-top-wrap{justify-content:start}.tsf-bottom-buttons,.tsf-top-buttons{width:100%}}.tsf-metaboxes .tsf-bottom-buttons>*,.tsf-metaboxes .tsf-top-buttons>*{text-align:center}.tsf-metaboxes .metabox-holder{clear:both}#tsf-title-separator{display:table;width:100%;border-collapse:collapse;border-spacing:0}#tsf-title-separator input{position:absolute;width:0;height:0;opacity:0;margin:0;padding:0;border:0;z-index:-1;-webkit-appearance:none;-moz-appearance:none;appearance:none}#tsf-title-separator label{display:inline-block;width:auto;min-width:28px;min-height:28px;margin:3px;-moz-margin-end:1.5px;-moz-margin-start:1.5px;padding:0 4px;border:1px solid #ccc;line-height:28px;text-align:center;cursor:pointer;box-shadow:-1px -1px 1px #aaa inset;font-size:16px}#tsf-title-separator label:hover{box-shadow:1px 1px 1px #aaa inset;background-color:#fff}#tsf-title-separator input:checked+label{box-shadow:1px 1px 1px #333 inset;background-color:#fff}#tsf-title-separator input:focus+label:not(.tsf-no-focus-ring){box-shadow:0 0 1px 1px #333 inset}#tsf-home-title-location,#tsf-title-location{display:block}#tsf-home-title-location label>span,#tsf-title-location label>span{display:inline-block;min-width:60px;vertical-align:baseline}.tsf-title-additions-example-left code,.tsf-title-additions-example-right code,.tsf-title-additions-js{white-space:pre-wrap}.tsf-title-additions-location-hidden,.tsf-title-tax-prefix-hidden{display:none}#tsf-post-type-archive-header-wrap{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:center;vertical-align:top;gap:1.625em 4ch}#tsf-post-type-archive-select-wrap{display:flex;flex-flow:row wrap;gap:1em;align-items:center}#tsf-post-type-archive-select-wrap label{font-weight:600}#tsf-post-type-archive-header-wrap h4{margin:0}.tsf-post-type-archive-link{display:inline-block}.tsf-post-type-archive-if-excluded p:last-of-type{margin-bottom:0}.tsf-select-block>select:last-of-type{margin-bottom:14px}.tsf-nav-tab-no-js,.tsf-nav-tab-wrapper{position:relative;clear:both;width:100%;display:inline-block;border-bottom:1px solid #ccc;line-height:inherit;padding:8px 12px 0;margin:-4px -12px}.tsf-nav-tab-label{float:left;border:1px solid #ccc;margin-left:.5em;margin-bottom:-1px;padding:1ch 2ch;font-size:12px;background:#f1f1f1;color:#555;font-weight:600;border-radius:3px 3px 0 0}body.rtl .tsf-nav-tab-label{float:right;margin-left:0;margin-right:.5em}.tsf-nav-desktop{margin-left:7px}.tsf-dashicons-tabs{font-size:initial;display:inline;vertical-align:text-bottom}input.tsf-nav-tab-radio{position:absolute;width:0;height:0;opacity:0;margin:0;padding:0;border:0;z-index:-1;-webkit-appearance:none;-moz-appearance:none;appearance:none}.tsf-nav-tab-active,.tsf-nav-tab-radio:checked+label{background-color:inherit;border-bottom-color:#fff;color:#000}.tsf-nav-tab-radio:focus+label:not(.tsf-no-focus-ring){box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);border-color:#fff}.tsf-nav-tab-content{margin:1.33em auto 0}.tsf-nav-tab-content select{width:100%;max-width:max-content;text-overflow:ellipsis}.tsf-nav-tab-content-no-js{margin:1.33em auto}body.js .tsf-nav-tab-content{display:none}body.js .tsf-nav-tab-content.tsf-nav-tab-content-active{display:block}
|
readme.txt
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
=== The SEO Framework – Automated, Effortless
|
2 |
Contributors: Cybr
|
3 |
Donate link: https://github.com/sponsors/sybrew
|
4 |
Tags: seo, xml sitemap, google search, open graph, schema.org, twitter card, performance, headless
|
5 |
Requires at least: 5.5.0
|
6 |
-
Tested up to:
|
7 |
Requires PHP: 7.2.0
|
8 |
-
Stable tag: 4.2.
|
9 |
License: GPLv3
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -247,6 +247,10 @@ If you wish to display breadcrumbs, then your theme should provide this. Alterna
|
|
247 |
|
248 |
== Changelog ==
|
249 |
|
|
|
|
|
|
|
|
|
250 |
= 4.2.3 =
|
251 |
|
252 |
This minor update addresses a regression where the singular-archive canonical URLs always [pointed to the first page](https://theseoframework.com/?p=3858).
|
1 |
+
=== The SEO Framework – Fast, Automated, Effortless. ===
|
2 |
Contributors: Cybr
|
3 |
Donate link: https://github.com/sponsors/sybrew
|
4 |
Tags: seo, xml sitemap, google search, open graph, schema.org, twitter card, performance, headless
|
5 |
Requires at least: 5.5.0
|
6 |
+
Tested up to: 6.0
|
7 |
Requires PHP: 7.2.0
|
8 |
+
Stable tag: 4.2.4
|
9 |
License: GPLv3
|
10 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
247 |
|
248 |
== Changelog ==
|
249 |
|
250 |
+
= 4.2.4 =
|
251 |
+
|
252 |
+
This minor update improves image processing, reducing TSF's load impact by roughly 20% when generating metadata. We also added WordPress 6.0 support for image filesizes, making social sharing [even more robust](https://theseoframework.com/?p=3903).
|
253 |
+
|
254 |
= 4.2.3 =
|
255 |
|
256 |
This minor update addresses a regression where the singular-archive canonical URLs always [pointed to the first page](https://theseoframework.com/?p=3858).
|