Merged in feature/314-dev-dev01 (pull request #24)

auto-patch  314-dev-dev01-2024-01-25T04_09_02

* auto-patch  314-dev-dev01-2024-01-25T04_09_02
This commit is contained in:
Tony Volpe
2024-01-25 04:11:47 +00:00
parent 6b67473553
commit 68dbe860e9
540 changed files with 3445 additions and 2131 deletions

View File

@@ -115,32 +115,7 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
$all_dates = [];
if ( $max_pages > 1 ) {
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) );
if ( version_compare( $wpdb->db_version(), '8.0', '>=' ) ) {
$sql = "
WITH ordering AS (SELECT ROW_NUMBER() OVER (ORDER BY post_modified_gmt) AS n, post_modified_gmt
FROM {$wpdb->posts} USE INDEX ( type_status_date )
WHERE post_status IN ('" . implode( "','", $post_statuses ) . "')
AND post_type = %s
ORDER BY post_modified_gmt)
SELECT post_modified_gmt
FROM ordering
WHERE MOD(n, %d) = 0;";
}
else {
$sql = "
SELECT post_modified_gmt
FROM ( SELECT @rownum:=0 ) init
JOIN {$wpdb->posts} USE INDEX( type_status_date )
WHERE post_status IN ('" . implode( "','", $post_statuses ) . "')
AND post_type = %s
AND ( @rownum:=@rownum+1 ) %% %d = 0
ORDER BY post_modified_gmt ASC
";
}
$all_dates = $wpdb->get_col( $wpdb->prepare( $sql, $post_type, $max_entries ) );
$all_dates = version_compare( $wpdb->db_version(), '8.0', '>=' ) ? $this->get_all_dates_using_with_clause( $post_type, $max_entries ) : $this->get_all_dates( $post_type, $max_entries );
}
for ( $page_counter = 0; $page_counter < $max_pages; $page_counter++ ) {
@@ -175,8 +150,9 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
* @param int $max_entries Entries per sitemap.
* @param int $current_page Current page of the sitemap.
*
* @throws OutOfBoundsException When an invalid page is requested.
* @return array
*
* @throws OutOfBoundsException When an invalid page is requested.
*/
public function get_sitemap_links( $type, $max_entries, $current_page ) {
@@ -262,6 +238,8 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
* Check for relevant post type before invalidation.
*
* @param int $post_id Post ID to possibly invalidate for.
*
* @return void
*/
public function save_post( $post_id ) {
@@ -313,7 +291,7 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
/**
* Filter: 'wpseo_exclude_from_sitemap_by_post_ids' - Allow extending and modifying the posts to exclude.
*
* @api array $posts_to_exclude The posts to exclude.
* @param array $posts_to_exclude The posts to exclude.
*/
$excluded_posts_ids = apply_filters( 'wpseo_exclude_from_sitemap_by_post_ids', $excluded_posts_ids );
if ( ! is_array( $excluded_posts_ids ) ) {
@@ -401,6 +379,19 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
$front_page['chf'] = 'daily';
$front_page['pri'] = 1;
$images = [];
/**
* Filter images to be included for the term in XML sitemap.
*
* @param array $images Array of image items.
* @return array $image_list Array of image items.
*/
$image_list = apply_filters( 'wpseo_sitemap_urlimages_front_page', $images );
if ( isset( $image_list ) && is_array( $image_list ) ) {
$front_page['images'] = $image_list;
}
$links[] = $front_page;
}
elseif ( $post_type !== 'page' ) {
@@ -675,4 +666,101 @@ class WPSEO_Post_Type_Sitemap_Provider implements WPSEO_Sitemap_Provider {
return $url;
}
/**
* Get all dates for a post type by using the WITH clause for performance.
*
* @param string $post_type Post type to retrieve dates for.
* @param int $max_entries Maximum number of entries to retrieve.
*
* @return array Array of dates.
*/
private function get_all_dates_using_with_clause( $post_type, $max_entries ) {
global $wpdb;
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) );
$replacements = array_merge(
[
'ordering',
'post_modified_gmt',
$wpdb->posts,
'type_status_date',
'post_status',
],
$post_statuses,
[
'post_type',
$post_type,
'post_modified_gmt',
'post_modified_gmt',
'ordering',
$max_entries,
]
);
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
return $wpdb->get_col(
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
$wpdb->prepare(
'
WITH %i AS (SELECT ROW_NUMBER() OVER (ORDER BY %i) AS n, post_modified_gmt
FROM %i USE INDEX ( %i )
WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ')
AND %i = %s
ORDER BY %i)
SELECT %i
FROM %i
WHERE MOD(n, %d) = 0;
',
$replacements
)
);
}
/**
* Get all dates for a post type.
*
* @param string $post_type Post type to retrieve dates for.
* @param int $max_entries Maximum number of entries to retrieve.
*
* @return array Array of dates.
*/
private function get_all_dates( $post_type, $max_entries ) {
global $wpdb;
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) );
$replacements = array_merge(
[
'post_modified_gmt',
$wpdb->posts,
'type_status_date',
'post_status',
],
$post_statuses,
[
'post_type',
$post_type,
$max_entries,
'post_modified_gmt',
]
);
return $wpdb->get_col(
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
$wpdb->prepare(
'
SELECT %i
FROM ( SELECT @rownum:=0 ) init
JOIN %i USE INDEX( %i )
WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ')
AND %i = %s
AND ( @rownum:=@rownum+1 ) %% %d = 0
ORDER BY %i ASC
',
$replacements
)
);
}
}

View File

@@ -28,6 +28,8 @@ class WPSEO_Sitemap_Cache_Data implements Serializable, WPSEO_Sitemap_Cache_Data
* Set the sitemap XML data
*
* @param string $sitemap XML Content of the sitemap.
*
* @return void
*/
public function set_sitemap( $sitemap ) {

View File

@@ -124,7 +124,10 @@ class WPSEO_Sitemap_Image_Parser {
* @param array $images Array of image items.
* @param int $post_id ID of the post.
*/
$images = apply_filters( 'wpseo_sitemap_urlimages', $images, $post->ID );
$image_list = apply_filters( 'wpseo_sitemap_urlimages', $images, $post->ID );
if ( isset( $image_list ) && is_array( $image_list ) ) {
$images = $image_list;
}
return $images;
}
@@ -147,6 +150,17 @@ class WPSEO_Sitemap_Image_Parser {
];
}
/**
* Filter images to be included for the term in XML sitemap.
*
* @param array $image_list Array of image items.
* @param int $term_id ID of the post.
*/
$image_list = apply_filters( 'wpseo_sitemap_urlimages_term', $images, $term->term_id );
if ( isset( $image_list ) && is_array( $image_list ) ) {
$images = $image_list;
}
return $images;
}

View File

@@ -33,9 +33,11 @@ class WPSEO_Sitemaps_Admin {
* if the post is being published, is a post type that a sitemap is built for
* and is a post that is included in sitemaps.
*
* @param string $new_status New post status.
* @param string $old_status Old post status.
* @param \WP_Post $post Post object.
* @param string $new_status New post status.
* @param string $old_status Old post status.
* @param WP_Post $post Post object.
*
* @return void
*/
public function status_transition( $new_status, $old_status, $post ) {
if ( $new_status !== 'publish' ) {
@@ -71,6 +73,8 @@ class WPSEO_Sitemaps_Admin {
/**
* Notify Google of the updated sitemap.
*
* @return void
*/
public function ping_search_engines() {
@@ -81,7 +85,7 @@ class WPSEO_Sitemaps_Admin {
/**
* Filter: 'wpseo_allow_xml_sitemap_ping' - Check if pinging is not allowed (allowed by default).
*
* @api boolean $allow_ping The boolean that is set to true by default.
* @param bool $allow_ping The boolean that is set to true by default.
*/
if ( apply_filters( 'wpseo_allow_xml_sitemap_ping', true ) === false ) {
return;
@@ -103,9 +107,11 @@ class WPSEO_Sitemaps_Admin {
* When importing is done, if we have a post_type that is saved in the sitemap
* try to ping the search engines.
*
* @param string $new_status New post status.
* @param string $old_status Old post status.
* @param \WP_Post $post Post object.
* @param string $new_status New post status.
* @param string $old_status Old post status.
* @param WP_Post $post Post object.
*
* @return void
*/
private function status_transition_bulk( $new_status, $old_status, $post ) {
$this->importing_post_types[] = get_post_type( $post );
@@ -114,6 +120,8 @@ class WPSEO_Sitemaps_Admin {
/**
* After import finished, walk through imported post_types and update info.
*
* @return void
*/
public function status_transition_bulk_finished() {
if ( ! defined( 'WP_IMPORTING' ) ) {

View File

@@ -17,21 +17,21 @@ class WPSEO_Sitemaps_Cache_Validator {
*
* @var string
*/
const STORAGE_KEY_PREFIX = 'yst_sm_';
public const STORAGE_KEY_PREFIX = 'yst_sm_';
/**
* Name of the option that holds the global validation value.
*
* @var string
*/
const VALIDATION_GLOBAL_KEY = 'wpseo_sitemap_cache_validator_global';
public const VALIDATION_GLOBAL_KEY = 'wpseo_sitemap_cache_validator_global';
/**
* The format which creates the key of the option that holds the type validation value.
*
* @var string
*/
const VALIDATION_TYPE_KEY_FORMAT = 'wpseo_sitemap_%s_cache_validator';
public const VALIDATION_TYPE_KEY_FORMAT = 'wpseo_sitemap_%s_cache_validator';
/**
* Get the cache key for a certain type and page.
@@ -189,8 +189,15 @@ class WPSEO_Sitemaps_Cache_Validator {
$where[] = sprintf( "option_name LIKE '%s'", addcslashes( '_transient_timeout_' . $like, '_' ) );
// Delete transients.
$query = sprintf( 'DELETE FROM %1$s WHERE %2$s', $wpdb->options, implode( ' OR ', $where ) );
$wpdb->query( $query );
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
$wpdb->query(
$wpdb->prepare(
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
'DELETE FROM %i WHERE ' . implode( ' OR', array_fill( 0, count( $where ), '%s' ) ),
array_merge( [ $wpdb->options ], $where )
)
);
wp_cache_delete( 'alloptions', 'options' );
}

View File

@@ -47,22 +47,24 @@ class WPSEO_Sitemaps_Cache {
add_action( 'init', [ $this, 'init' ] );
add_action( 'deleted_term_relationships', [ __CLASS__, 'invalidate' ] );
add_action( 'deleted_term_relationships', [ self::class, 'invalidate' ] );
add_action( 'update_option', [ __CLASS__, 'clear_on_option_update' ] );
add_action( 'update_option', [ self::class, 'clear_on_option_update' ] );
add_action( 'edited_terms', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
add_action( 'clean_term_cache', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
add_action( 'clean_object_term_cache', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
add_action( 'edited_terms', [ self::class, 'invalidate_helper' ], 10, 2 );
add_action( 'clean_term_cache', [ self::class, 'invalidate_helper' ], 10, 2 );
add_action( 'clean_object_term_cache', [ self::class, 'invalidate_helper' ], 10, 2 );
add_action( 'user_register', [ __CLASS__, 'invalidate_author' ] );
add_action( 'delete_user', [ __CLASS__, 'invalidate_author' ] );
add_action( 'user_register', [ self::class, 'invalidate_author' ] );
add_action( 'delete_user', [ self::class, 'invalidate_author' ] );
add_action( 'shutdown', [ __CLASS__, 'clear_queued' ] );
add_action( 'shutdown', [ self::class, 'clear_queued' ] );
}
/**
* Setup context for static calls.
*
* @return void
*/
public function init() {
@@ -294,6 +296,8 @@ class WPSEO_Sitemaps_Cache {
/**
* Invalidate storage for cache types queued to clear.
*
* @return void
*/
public static function clear_queued() {
@@ -320,6 +324,8 @@ class WPSEO_Sitemaps_Cache {
*
* @param string $option Option name.
* @param string $type Sitemap type.
*
* @return void
*/
public static function register_clear_on_option_update( $option, $type = '' ) {

View File

@@ -103,7 +103,7 @@ class WPSEO_Sitemaps_Renderer {
/**
* Filters the `urlset` for a sitemap by type.
*
* @api string $urlset The output for the sitemap's `urlset`.
* @param string $urlset The output for the sitemap's `urlset`.
*/
$xml = apply_filters( "wpseo_sitemap_{$type}_urlset", $urlset );
@@ -166,6 +166,8 @@ class WPSEO_Sitemaps_Renderer {
* Set a custom stylesheet for this sitemap. Set to empty to just remove the default stylesheet.
*
* @param string $stylesheet Full XML-stylesheet declaration.
*
* @return void
*/
public function set_stylesheet( $stylesheet ) {
$this->stylesheet = $stylesheet;
@@ -239,9 +241,8 @@ class WPSEO_Sitemaps_Renderer {
/**
* Filters the output for the sitemap URL tag.
*
* @api string $output The output for the sitemap url tag.
*
* @param array $url The sitemap URL array on which the output is based.
* @param string $output The output for the sitemap url tag.
* @param array $url The sitemap URL array on which the output is based.
*/
return apply_filters( 'wpseo_sitemap_url', $output, $url );
}

View File

@@ -21,24 +21,51 @@ class WPSEO_Sitemaps_Router {
return;
}
add_action( 'init', [ $this, 'init' ], 1 );
add_action( 'yoast_add_dynamic_rewrite_rules', [ $this, 'add_rewrite_rules' ] );
add_filter( 'query_vars', [ $this, 'add_query_vars' ] );
add_filter( 'redirect_canonical', [ $this, 'redirect_canonical' ] );
add_action( 'template_redirect', [ $this, 'template_redirect' ], 0 );
}
/**
* Adds rewrite routes for sitemaps.
*
* @param Yoast_Dynamic_Rewrites $dynamic_rewrites Dynamic rewrites handler instance.
*
* @return void
*/
public function add_rewrite_rules( $dynamic_rewrites ) {
$dynamic_rewrites->add_rule( 'sitemap_index\.xml$', 'index.php?sitemap=1', 'top' );
$dynamic_rewrites->add_rule( '([^/]+?)-sitemap([0-9]+)?\.xml$', 'index.php?sitemap=$matches[1]&sitemap_n=$matches[2]', 'top' );
$dynamic_rewrites->add_rule( '([a-z]+)?-?sitemap\.xsl$', 'index.php?yoast-sitemap-xsl=$matches[1]', 'top' );
}
/**
* Adds query variables for sitemaps.
*
* @param array $query_vars List of query variables to filter.
*
* @return array Filtered query variables.
*/
public function add_query_vars( $query_vars ) {
$query_vars[] = 'sitemap';
$query_vars[] = 'sitemap_n';
$query_vars[] = 'yoast-sitemap-xsl';
return $query_vars;
}
/**
* Sets up rewrite rules.
*
* @deprecated 21.8
* @codeCoverageIgnore
*
* @return void
*/
public function init() {
global $wp;
$wp->add_query_var( 'sitemap' );
$wp->add_query_var( 'sitemap_n' );
$wp->add_query_var( 'yoast-sitemap-xsl' );
add_rewrite_rule( 'sitemap_index\.xml$', 'index.php?sitemap=1', 'top' );
add_rewrite_rule( '([^/]+?)-sitemap([0-9]+)?\.xml$', 'index.php?sitemap=$matches[1]&sitemap_n=$matches[2]', 'top' );
add_rewrite_rule( '([a-z]+)?-?sitemap\.xsl$', 'index.php?yoast-sitemap-xsl=$matches[1]', 'top' );
_deprecated_function( __METHOD__, 'Yoast SEO 21.8' );
}
/**
@@ -59,14 +86,15 @@ class WPSEO_Sitemaps_Router {
/**
* Redirects sitemap.xml to sitemap_index.xml.
*
* @return void
*/
public function template_redirect() {
if ( ! $this->needs_sitemap_index_redirect() ) {
return;
}
wp_safe_redirect( home_url( '/sitemap_index.xml' ), 301, 'Yoast SEO' );
exit;
YoastSEO()->helpers->redirect->do_safe_redirect( home_url( '/sitemap_index.xml' ), 301, 'Yoast SEO' );
}
/**

View File

@@ -17,7 +17,7 @@ class WPSEO_Sitemaps {
*
* @var string
*/
const SITEMAP_INDEX_TYPE = '1';
public const SITEMAP_INDEX_TYPE = '1';
/**
* Content of the sitemap to output.
@@ -115,6 +115,8 @@ class WPSEO_Sitemaps {
* Initialize sitemap providers classes.
*
* @since 5.3
*
* @return void
*/
public function init_sitemaps_providers() {
@@ -135,6 +137,8 @@ class WPSEO_Sitemaps {
/**
* Check the current request URI, if we can determine it's probably an XML sitemap, kill loading the widgets.
*
* @return void
*/
public function reduce_query_load() {
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
@@ -153,11 +157,13 @@ class WPSEO_Sitemaps {
* @param string $name The name of the sitemap.
* @param callback $building_function Function to build your sitemap.
* @param string $rewrite Optional. Regular expression to match your sitemap with.
*
* @return void
*/
public function register_sitemap( $name, $building_function, $rewrite = '' ) {
add_action( 'wpseo_do_sitemap_' . $name, $building_function );
if ( ! empty( $rewrite ) ) {
add_rewrite_rule( $rewrite, 'index.php?sitemap=' . $name, 'top' );
if ( $rewrite ) {
Yoast_Dynamic_Rewrites::instance()->add_rule( $rewrite, 'index.php?sitemap=' . $name, 'top' );
}
}
@@ -169,11 +175,13 @@ class WPSEO_Sitemaps {
* @param string $name The name of the XSL file.
* @param callback $building_function Function to build your XSL file.
* @param string $rewrite Optional. Regular expression to match your sitemap with.
*
* @return void
*/
public function register_xsl( $name, $building_function, $rewrite = '' ) {
add_action( 'wpseo_xsl_' . $name, $building_function );
if ( ! empty( $rewrite ) ) {
add_rewrite_rule( $rewrite, 'index.php?yoast-sitemap-xsl=' . $name, 'top' );
if ( $rewrite ) {
Yoast_Dynamic_Rewrites::instance()->add_rule( $rewrite, 'index.php?yoast-sitemap-xsl=' . $name, 'top' );
}
}
@@ -182,6 +190,8 @@ class WPSEO_Sitemaps {
* in a one-off process.
*
* @param int $current_page The part that should be generated.
*
* @return void
*/
public function set_n( $current_page ) {
if ( is_scalar( $current_page ) && intval( $current_page ) > 0 ) {
@@ -193,6 +203,8 @@ class WPSEO_Sitemaps {
* Set the sitemap content to display after you have generated it.
*
* @param string $sitemap The generated sitemap to output.
*
* @return void
*/
public function set_sitemap( $sitemap ) {
$this->sitemap = $sitemap;
@@ -202,6 +214,8 @@ class WPSEO_Sitemaps {
* Set as true to make the request 404. Used stop the display of empty sitemaps or invalid requests.
*
* @param bool $is_bad Is this a bad request. True or false.
*
* @return void
*/
public function set_bad_sitemap( $is_bad ) {
$this->bad_sitemap = (bool) $is_bad;
@@ -211,6 +225,8 @@ class WPSEO_Sitemaps {
* Prevent stupid plugins from running shutdown scripts when we're obviously not outputting HTML.
*
* @since 1.4.16
*
* @return void
*/
public function sitemap_close() {
remove_all_actions( 'wp_footer' );
@@ -220,7 +236,9 @@ class WPSEO_Sitemaps {
/**
* Hijack requests for potential sitemaps and XSL files.
*
* @param \WP_Query $query Main query instance.
* @param WP_Query $query Main query instance.
*
* @return void
*/
public function redirect( $query ) {
@@ -332,6 +350,8 @@ class WPSEO_Sitemaps {
* Sets $bad_sitemap if this isn't for the root sitemap, a post type or taxonomy.
*
* @param string $type The requested sitemap's identifier.
*
* @return void
*/
public function build_sitemap( $type ) {
@@ -382,6 +402,8 @@ class WPSEO_Sitemaps {
/**
* Build the root sitemap (example.com/sitemap_index.xml) which lists sub-sitemaps for other content types.
*
* @return void
*/
public function build_root_map() {
@@ -415,6 +437,8 @@ class WPSEO_Sitemaps {
* @since 1.4.13
*
* @param string $type Type to output.
*
* @return void
*/
public function xsl_output( $type ) {
@@ -445,6 +469,8 @@ class WPSEO_Sitemaps {
/**
* Spit out the generated sitemap.
*
* @return void
*/
public function output() {
$this->send_headers();
@@ -499,18 +525,41 @@ class WPSEO_Sitemaps {
if ( ! empty( $post_type_names ) ) {
$post_statuses = array_map( 'esc_sql', self::get_post_statuses() );
$replacements = array_merge(
[
'post_type',
'post_modified_gmt',
'date',
$wpdb->posts,
'post_status',
],
$post_statuses,
[ 'post_type' ],
array_keys( $post_type_names ),
[
'post_type',
'date',
]
);
$sql = "
SELECT post_type, MAX(post_modified_gmt) AS date
FROM $wpdb->posts
WHERE post_status IN ('" . implode( "','", $post_statuses ) . "')
AND post_type IN ('" . implode( "','", $post_type_names ) . "')
GROUP BY post_type
ORDER BY date DESC
";
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
$dates = $wpdb->get_results(
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
$wpdb->prepare(
'
SELECT %i, MAX(%i) AS %i
FROM %i
WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ')
AND %i IN (' . implode( ', ', array_fill( 0, count( $post_type_names ), '%s' ) ) . ')
GROUP BY %i
ORDER BY %i DESC
',
$replacements
)
);
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery -- They are prepared on the lines above and a direct query is required.
foreach ( $wpdb->get_results( $sql ) as $obj ) {
foreach ( $dates as $obj ) {
$post_type_dates[ $obj->post_type ] = $obj->date;
}
}
@@ -592,6 +641,8 @@ class WPSEO_Sitemaps {
/**
* Sends all the required HTTP Headers.
*
* @return void
*/
private function send_headers() {
if ( headers_sent() ) {

View File

@@ -94,10 +94,11 @@ class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
$hide_empty_tax = apply_filters( 'wpseo_sitemap_exclude_empty_terms_taxonomy', $hide_empty, $taxonomy_name );
$term_args = [
'taxonomy' => $taxonomy_name,
'hide_empty' => $hide_empty_tax,
'fields' => 'ids',
];
$taxonomy_terms = get_terms( $taxonomy_name, $term_args );
$taxonomy_terms = get_terms( $term_args );
if ( count( $taxonomy_terms ) > 0 ) {
$all_taxonomies[ $taxonomy_name ] = $taxonomy_terms;
@@ -211,24 +212,28 @@ class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
$post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses() );
// Grab last modified date.
$sql = "
SELECT MAX(p.post_modified_gmt) AS lastmod
FROM $wpdb->posts AS p
INNER JOIN $wpdb->term_relationships AS term_rel
ON term_rel.object_id = p.ID
INNER JOIN $wpdb->term_taxonomy AS term_tax
ON term_tax.term_taxonomy_id = term_rel.term_taxonomy_id
AND term_tax.taxonomy = %s
AND term_tax.term_id = %d
WHERE p.post_status IN ('" . implode( "','", $post_statuses ) . "')
AND p.post_password = ''
";
$replacements = array_merge(
[
'post_modified_gmt',
$wpdb->posts,
$wpdb->term_relationships,
'object_id',
'ID',
$wpdb->term_taxonomy,
'term_taxonomy_id',
'term_taxonomy_id',
'taxonomy',
'term_id',
'post_status',
],
$post_statuses,
[ 'post_password' ]
);
/**
* Filter: 'wpseo_exclude_from_sitemap_by_term_ids' - Allow excluding terms by ID.
*
* @api array $terms_to_exclude The terms to exclude.
* @param array $terms_to_exclude The terms to exclude.
*/
$terms_to_exclude = apply_filters( 'wpseo_exclude_from_sitemap_by_term_ids', [] );
@@ -253,7 +258,30 @@ class WPSEO_Taxonomy_Sitemap_Provider implements WPSEO_Sitemap_Provider {
continue;
}
$url['mod'] = $wpdb->get_var( $wpdb->prepare( $sql, $term->taxonomy, $term->term_id ) );
$current_replacements = $replacements;
array_splice( $current_replacements, 9, 0, $term->taxonomy );
array_splice( $current_replacements, 11, 0, $term->term_id );
//phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here.
//phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
$url['mod'] = $wpdb->get_var(
//phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized.
$wpdb->prepare(
'
SELECT MAX(p.%i) AS lastmod
FROM %i AS p
INNER JOIN %i AS term_rel
ON term_rel.%i = p.%i
INNER JOIN %i AS term_tax
ON term_tax.%i = term_rel.%i
AND term_tax.%i = %s
AND term_tax.%i = %d
WHERE p.%i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ")
AND p.%i = ''
",
$current_replacements
)
);
if ( $this->include_images ) {
$url['images'] = $this->get_image_parser()->get_term_images( $term );

View File

@@ -15,21 +15,21 @@ interface WPSEO_Sitemap_Cache_Data_Interface {
*
* @var string
*/
const OK = 'ok';
public const OK = 'ok';
/**
* Status for unusable sitemap.
*
* @var string
*/
const ERROR = 'error';
public const ERROR = 'error';
/**
* Status for unusable sitemap because it cannot be identified.
*
* @var string
*/
const UNKNOWN = 'unknown';
public const UNKNOWN = 'unknown';
/**
* Set the content of the sitemap.