Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions inc/class-upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public function __construct() {
'20.2-RC0' => 'upgrade_202',
'20.5-RC0' => 'upgrade_205',
'20.7-RC0' => 'upgrade_207',
'20.8-RC0' => 'upgrade_208',
];

array_walk( $routines, [ $this, 'run_upgrade_routine' ], $version );
Expand Down Expand Up @@ -997,11 +998,26 @@ private function upgrade_205() {
/**
* Performs the 20.7 upgrade routine.
* Removes the metadata related to the settings page introduction modal for all the users.
* Also, schedules another cleanup scheduled action.
*/
private function upgrade_207() {
Comment thread
thijsoo marked this conversation as resolved.
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
}

add_action( 'shutdown', [ $this, 'delete_user_introduction_meta' ] );
}

/**
* Performs the 20.8 upgrade routine.
* Schedules another cleanup scheduled action.
*/
private function upgrade_208() {
if ( ! \wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) {
\wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK );
}
}

/**
* Sets the home_url option for the 15.1 upgrade routine.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
class Indexable_Post_Type_Archive_Indexation_Action implements Indexation_Action_Interface, Limited_Indexing_Action_Interface {


/**
* The transient cache key.
*/
Expand Down Expand Up @@ -52,9 +53,9 @@ class Indexable_Post_Type_Archive_Indexation_Action implements Indexation_Action
* Indexation_Post_Type_Archive_Action constructor.
*
* @param Indexable_Repository $repository The indexable repository.
* @param Indexable_Builder $builder The indexable builder.
* @param Post_Type_Helper $post_type The post type helper.
* @param Indexable_Builder_Versions $versions The current versions of all indexable builders.
* @param Indexable_Builder $builder The indexable builder.
* @param Post_Type_Helper $post_type The post type helper.
* @param Indexable_Builder_Versions $versions The current versions of all indexable builders.
*/
public function __construct(
Indexable_Repository $repository,
Expand Down Expand Up @@ -164,8 +165,7 @@ protected function get_unindexed_post_type_archives( $limit = false ) {
*/
protected function get_post_types_with_archive_pages() {
// We only want to index archive pages of public post types that have them.
$public_post_types = $this->post_type->get_public_post_types( 'object' );
$post_types_with_archive = \array_filter( $public_post_types, [ $this->post_type, 'has_archive' ] );
$post_types_with_archive = $this->post_type->get_indexable_post_archives();

// We only need the post type names, not the objects.
$post_types = [];
Expand Down
33 changes: 25 additions & 8 deletions src/builders/indexable-post-type-archive-builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace Yoast\WP\SEO\Builders;

use wpdb;
use Yoast\WP\SEO\Exceptions\Indexable\Post_Type_Not_Built_Exception;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Helpers\Post_Helper;
use Yoast\WP\SEO\Helpers\Post_Type_Helper;
use Yoast\WP\SEO\Models\Indexable;
use Yoast\WP\SEO\Values\Indexables\Indexable_Builder_Versions;

Expand All @@ -30,12 +32,19 @@ class Indexable_Post_Type_Archive_Builder {
protected $version;

/**
* Holds the taxonomy helper instance.
* Holds the post helper instance.
*
* @var Post_Helper
*/
protected $post_helper;

/**
* Holds the post type helper instance.
*
* @var Post_Type_Helper
*/
protected $post_type_helper;

/**
* The WPDB instance.
*
Expand All @@ -46,21 +55,24 @@ class Indexable_Post_Type_Archive_Builder {
/**
* Indexable_Post_Type_Archive_Builder constructor.
*
* @param Options_Helper $options The options helper.
* @param Indexable_Builder_Versions $versions The latest version of each Indexable builder.
* @param Options_Helper $options The options helper.
* @param Indexable_Builder_Versions $versions The latest version of each Indexable builder.
* @param Post_Helper $post_helper The post helper.
* @param wpdb $wpdb The WPDB instance.
* @param Post_Type_Helper $post_type_helper The post type helper.
* @param wpdb $wpdb The WPDB instance.
*/
public function __construct(
Options_Helper $options,
Indexable_Builder_Versions $versions,
Post_Helper $post_helper,
Post_Type_Helper $post_type_helper,
wpdb $wpdb
) {
$this->options = $options;
$this->version = $versions->get_latest_version_for_type( 'post-type-archive' );
$this->post_helper = $post_helper;
$this->wpdb = $wpdb;
$this->options = $options;
$this->version = $versions->get_latest_version_for_type( 'post-type-archive' );
$this->post_helper = $post_helper;
$this->post_type_helper = $post_type_helper;
$this->wpdb = $wpdb;
}

/**
Expand All @@ -70,8 +82,13 @@ public function __construct(
* @param Indexable $indexable The indexable to format.
*
* @return Indexable The extended indexable.
* @throws \Yoast\WP\SEO\Exceptions\Indexable\Post_Type_Not_Built_Exception Throws exception if the post type is excluded.
*/
public function build( $post_type, Indexable $indexable ) {
if ( ! $this->post_type_helper->is_post_type_archive_indexable( $post_type ) ) {
throw Post_Type_Not_Built_Exception::because_not_indexable( $post_type );
}

$indexable->object_type = 'post-type-archive';
$indexable->object_sub_type = $post_type;
$indexable->title = $this->options->get( 'title-ptarchive-' . $post_type );
Expand Down
22 changes: 22 additions & 0 deletions src/exceptions/indexable/post-type-not-built-exception.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Yoast\WP\SEO\Exceptions\Indexable;

/**
* Exception that is thrown whenever a post type could not be built
* in the context of the indexables.
*/
class Post_Type_Not_Built_Exception extends Not_Built_Exception {

/**
* Throws an exception if the post is not indexable.
*
* @param string $post_type The post type.
*
* @throws Post_Type_Not_Built_Exception When the post type is not indexable.
*/
public static function because_not_indexable( $post_type ) {
/* translators: %s: expands to the post type */
return new Post_Type_Not_Built_Exception( \sprintf( \__( 'The post type %s could not be indexed because it does not meet indexing requirements.', 'wordpress-seo' ), $post_type ) );
}
}
6 changes: 3 additions & 3 deletions src/helpers/post-helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ public function update_has_public_posts_on_attachments( $post_parent, $has_publi
*/
public function is_post_indexable( $post_id ) {
// Don't index posts which are not public (i.e. viewable).
$post_type = \get_post_type( $post_id );
$public_types = $this->post_type->get_indexable_post_types();
if ( ! \in_array( $post_type, $public_types, true ) ) {
$post_type = \get_post_type( $post_id );

if ( ! $this->post_type->is_of_indexable_post_type( $post_type ) ) {
return false;
}

Expand Down
44 changes: 44 additions & 0 deletions src/helpers/post-type-helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@ public function get_indexable_post_types() {
return $this->filter_included_post_types( $included_post_types );
}

/**
* Returns all indexable post types with archive pages.
*
* @return array All post types which are indexable and have archive pages.
*/
public function get_indexable_post_archives() {
return \array_filter( $this->get_indexable_post_type_objects(), [ $this, 'has_archive' ] );
}

/**
* Filters the post types that are included to be indexed.
*
Expand Down Expand Up @@ -187,6 +196,41 @@ protected function filter_included_post_types( $included_post_types ) {
return \array_values( $filtered_included_post_types );
}

/**
* Checks if the given post type should be indexed.
*
* @param string $post_type The post type that is checked.
*
* @return bool
*/
public function is_of_indexable_post_type( $post_type ) {
$public_types = $this->get_indexable_post_types();
if ( ! \in_array( $post_type, $public_types, true ) ) {
return false;
}

return true;
}

/**
* Checks if the archive of a post type is indexable.
*
* @param string $post_type The post type to check.
*
* @return bool if the archive is indexable.
*/
public function is_post_type_archive_indexable( $post_type ) {
$public_type_objects = $this->get_indexable_post_archives();
$public_types = \array_map(
static function ( $post_type_object ) {
return $post_type_object->name;
},
$public_type_objects
);

return \in_array( $post_type, $public_types, true );
}

/**
* Returns an array of complete post type objects for all indexable post types.
*
Expand Down
4 changes: 4 additions & 0 deletions src/integrations/cleanup-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Yoast\WP\SEO\Integrations;

use Closure;
use Yoast\WP\Lib\Model;
use Yoast\WP\SEO\Repositories\Indexable_Cleanup_Repository;

/**
Expand Down Expand Up @@ -112,6 +113,9 @@ public function get_cleanup_tasks() {
'clean_indexables_for_non_publicly_viewable_taxonomies' => function ( $limit ) {
return $this->cleanup_repository->clean_indexables_for_non_publicly_viewable_taxonomies( $limit );
},
'clean_indexables_for_non_publicly_viewable_post_type_archive_pages' => function ( $limit ) {
return $this->cleanup_repository->clean_indexables_for_non_publicly_viewable_post_type_archive_pages( $limit );
},
'clean_indexables_for_authors_archive_disabled' => function ( $limit ) {
return $this->cleanup_repository->clean_indexables_for_authors_archive_disabled( $limit );
},
Expand Down
48 changes: 48 additions & 0 deletions src/repositories/indexable-cleanup-repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,54 @@ public function clean_indexables_for_non_publicly_viewable_taxonomies( $limit )
// phpcs:enable
}

/**
* Cleans up any indexables that belong to post type archive page that are not/no longer publicly viewable.
*
* @param int $limit The limit we'll apply to the queries.
*
* @return bool|int The number of deleted rows, false if the query fails.
*/
public function clean_indexables_for_non_publicly_viewable_post_type_archive_pages( $limit ) {
global $wpdb;
$indexable_table = Model::get_table_name( 'Indexable' );

$included_post_types = $this->post_type->get_indexable_post_archives();

$post_archives = [];

foreach ( $included_post_types as $post_type ) {
$post_archives[] = $post_type->name;
}
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
if ( empty( $post_archives ) ) {
$delete_query = $wpdb->prepare(
"DELETE FROM $indexable_table
WHERE object_type = 'post-type-archive'
AND object_sub_type IS NOT NULL
LIMIT %d",
$limit
);
}
else {
// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber -- Reason: we're passing an array instead.
$delete_query = $wpdb->prepare(
"DELETE FROM $indexable_table
WHERE object_type = 'post-type-archive'
AND object_sub_type IS NOT NULL
AND object_sub_type NOT IN ( " . \implode( ', ', \array_fill( 0, \count( $post_archives ), '%s' ) ) . ' )
LIMIT %d',
\array_merge( $post_archives, [ $limit ] )
);
}
// phpcs:enable

// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches.
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
return $wpdb->query( $delete_query );
// phpcs:enable
}

/**
* Counts indexables for non publicly viewable taxonomies.
*
Expand Down
Loading