_types(); if ( ! empty( $post_type_names ) ) { $post_statuses = array_map( 'esc_sql', self::get_post_statuses() ); $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: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 ) { $post_type_dates[ $obj->post_type ] = $obj->date; } } } $dates = array_intersect_key( $post_type_dates, array_flip( $post_types ) ); if ( count( $dates ) > 0 ) { if ( $return_all ) { return $dates; } return max( $dates ); } return false; } /** * Get the modification date for the last modified post in the post type. * * @param array $post_types Post types to get the last modification date for. * * @return string */ public function get_last_modified( $post_types ) { return YoastSEO()->helpers->date->format( self::get_last_modified_gmt( $post_types ) ); } // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Argument is kept for documentation purposes. /** * Notify search engines of the updated sitemap. * * @deprecated 19.2 * * @codeCoverageIgnore * * @param string|null $url Optional URL to make the ping for. */ public static function ping_search_engines( $url = null ) { _deprecated_function( __METHOD__, 'Yoast SEO 19.2', 'WPSEO_Sitemaps_Admin::ping_search_engines' ); $admin = new WPSEO_Sitemaps_Admin(); $admin->ping_search_engines(); } // phpcs:enable /** * Get the maximum number of entries per XML sitemap. * * @return int The maximum number of entries. */ protected function get_entries_per_page() { /** * Filter the maximum number of entries per XML sitemap. * * After changing the output of the filter, make sure that you disable and enable the * sitemaps to make sure the value is picked up for the sitemap cache. * * @param int $entries The maximum number of entries per XML sitemap. */ $entries = (int) apply_filters( 'wpseo_sitemap_entries_per_page', 1000 ); return $entries; } /** * Get post statuses for post_type or the root sitemap. * * @since 10.2 * * @param string $type Provide a type for a post_type sitemap, SITEMAP_INDEX_TYPE for the root sitemap. * * @return array List of post statuses. */ public static function get_post_statuses( $type = self::SITEMAP_INDEX_TYPE ) { /** * Filter post status list for sitemap query for the post type. * * @param array $post_statuses Post status list, defaults to array( 'publish' ). * @param string $type Post type or SITEMAP_INDEX_TYPE. */ $post_statuses = apply_filters( 'wpseo_sitemap_post_statuses', [ 'publish' ], $type ); if ( ! is_array( $post_statuses ) || empty( $post_statuses ) ) { $post_statuses = [ 'publish' ]; } if ( ( $type === self::SITEMAP_INDEX_TYPE || $type === 'attachment' ) && ! in_array( 'inherit', $post_statuses, true ) ) { $post_statuses[] = 'inherit'; } return $post_statuses; } /** * Sends all the required HTTP Headers. */ private function send_headers() { if ( headers_sent() ) { return; } $headers = [ $this->http_protocol . ' 200 OK' => 200, // Prevent the search engines from indexing the XML Sitemap. 'X-Robots-Tag: noindex, follow' => '', 'Content-Type: text/xml; charset=' . esc_attr( $this->renderer->get_output_charset() ) => '', ]; /** * Filter the HTTP headers we send before an XML sitemap. * * @param array $headers The HTTP headers we're going to send out. */ $headers = apply_filters( 'wpseo_sitemap_http_headers', $headers ); foreach ( $headers as $header => $status ) { if ( is_numeric( $status ) ) { header( $header, true, $status ); continue; } header( $header, true ); } } }