class Recent_Content_Indexable_Collector {
/**
* The indexable repository.
*
* @var Indexable_Repository
*/
private $indexable_repository;
/**
* The SEO score groups repository.
*
* @var SEO_Score_Groups_Repository
*/
private $seo_score_groups_repository;
/**
* The readability score groups repository.
*
* @var Readability_Score_Groups_Repository
*/
private $readability_score_groups_repository;
/**
* The constructor.
*
* @param Indexable_Repository $indexable_repository The indexable repository.
* @param SEO_Score_Groups_Repository $seo_score_groups_repository The SEO score groups repository.
* @param Readability_Score_Groups_Repository $readability_score_groups_repository The readability score groups repository.
*/
public function __construct(
Indexable_Repository $indexable_repository,
SEO_Score_Groups_Repository $seo_score_groups_repository,
Readability_Score_Groups_Repository $readability_score_groups_repository
) {
$this->indexable_repository = $indexable_repository;
$this->seo_score_groups_repository = $seo_score_groups_repository;
$this->readability_score_groups_repository = $readability_score_groups_repository;
}
/**
* Gets recent content items with SEO scores for the given post type.
*
* @param string $post_type The post type to query.
* @param string $date_limit The date limit (content modified after this date).
* @param int|null $limit Optional. Maximum number of items to retrieve.
*
* @return Content_Item_Score_Data[] Array of content item score data value objects.
*/
public function get_recent_content_with_seo_scores( string $post_type, string $date_limit, ?int $limit = null ): array {
$raw_results = $this->indexable_repository->get_recent_posts_with_keywords_for_post_type(
$post_type,
$limit,
$date_limit,
);
return $this->map_to_seo_score_data( $raw_results, $post_type );
}
/**
* Gets recent content items with readability scores for the given post type.
*
* @param string $post_type The post type to query.
* @param string $date_limit The date limit (content modified after this date).
* @param int|null $limit Optional. Maximum number of items to retrieve.
*
* @return Content_Item_Score_Data[] Array of content item score data value objects.
*/
public function get_recent_content_with_readability_scores( string $post_type, string $date_limit, ?int $limit = null ): array {
$raw_results = $this->indexable_repository->get_recent_posts_with_readability_scores_for_post_type(
$post_type,
$limit,
$date_limit,
);
return $this->map_to_readability_score_data( $raw_results, $post_type );
}
/**
* Gets recent content items for the meta descriptions task for the given post type.
*
* @param string $post_type The post type to query.
* @param string $date_limit The date limit (content modified after this date).
* @param int|null $limit Optional. Maximum number of items to retrieve.
*
* @return Meta_Description_Content_Item_Data[] Array of content item data value objects.
*/
public function get_recent_content_for_meta_descriptions( string $post_type, string $date_limit, ?int $limit = null ): array {
$raw_results = $this->indexable_repository->get_recent_posts_for_post_type(
$post_type,
$limit,
$date_limit,
);
if ( ! \is_array( $raw_results ) ) {
return [];
}
$content_items = [];
foreach ( $raw_results as $result ) {
$content_items[] = new Meta_Description_Content_Item_Data(
(int) $result['object_id'],
$result['breadcrumb_title'],
(string) $result['description'] !== '',
);
}
return $content_items;
}
/**
* Maps raw database results to Content_Item_Score_Data value objects for SEO scores.
*
* @param array<array<string, string>> $raw_results The raw results from the repository.
* @param string $post_type The post type.
*
* @return Content_Item_Score_Data[] Array of content item score data value objects.
*/
private function map_to_seo_score_data( array $raw_results, string $post_type ): array {
$content_items = [];
foreach ( $raw_results as $result ) {
$seo_score_group = $this->seo_score_groups_repository->get_score_group( (int) $result['primary_focus_keyword_score'] );
$content_items[] = new Content_Item_Score_Data(
(int) $result['object_id'],
$result['breadcrumb_title'],
$seo_score_group->get_name(),
$post_type,
);
}
return $content_items;
}
/**
* Maps raw database results to Content_Item_Score_Data value objects for readability scores.
*
* @param array<array<string, string>> $raw_results The raw results from the repository.
* @param string $post_type The post type.
*
* @return Content_Item_Score_Data[] Array of content item score data value objects.
*/
private function map_to_readability_score_data( array $raw_results, string $post_type ): array {
$content_items = [];
foreach ( $raw_results as $result ) {
// @TODO: Instead of this inline quick fix, let's properly handle the case where readability_score is 0 in the repository method, and return 'bad' directly from there (SEO scores having a different logic might make this a bit harder).
// Also read as: The refactoring of https://github.com/Yoast/wordpress-seo/pull/22947 was not quite right.
if ( (int) $result['readability_score'] === 0 ) {
$score_name = 'bad';
}
else {
$readability_score_group = $this->readability_score_groups_repository->get_score_group( (int) $result['readability_score'] );
$score_name = $readability_score_group->get_name();
}
$content_items[] = new Content_Item_Score_Data(
(int) $result['object_id'],
$result['breadcrumb_title'],
$score_name,
$post_type,
);
}
return $content_items;
}
}