8000 Create API endpoints for SEO and readability scores by leonidasmi · Pull Request #21847 · Yoast/wordpress-seo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Create API endpoints for SEO and readability scores #21847

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ef64321
Create API endpoint for SEO scores
leonidasmi Nov 15, 2024
a374a97
Onionize the SEO score feature
leonidasmi Nov 18, 2024
c01297c
Merge branch 'feature/dash-phase-1' into 321-create-api-endpoints-for…
leonidasmi Nov 19, 2024
0a88fc4
Add link to API response
leonidasmi Nov 19, 2024
c497fd3
Use domain context for validating REST requests
leonidasmi Nov 19, 2024
705d71d
Optimize query for getting SEO scores
leonidasmi Nov 19, 2024
6487339
Return SEO scores sorted
leonidasmi Nov 19, 2024
f40fa00
Validate taxonomy parameter also based on whether it's an active filt…
leonidasmi Nov 19, 2024
e8a7da2
Clean up
leonidasmi Nov 20, 2024
e0744ea
Don't include explicitly noindexed posts in the SEO scores
leonidasmi Nov 20, 2024
851649c
Add API endpoint for readability scores
leonidasmi Nov 20, 2024
1a4d8ea
Abstract getting the view link of a score into a unified collector
leonidasmi Nov 20, 2024
7b85e58
Use trait for score routes
leonidasmi Nov 20, 2024
f66d7f2
Fix deprecation of creation of dynamic properties for the trait
leonidasmi Nov 20, 2024
4c43d54
Fix the return type of the endpoint
leonidasmi Nov 20, 2024
428b097
Merge branch 'feature/dash-phase-1' into 529-create-api-endpoint-for-…
leonidasmi Nov 20, 2024
3ffb548
DRY up
leonidasmi Nov 21, 2024
b6c5428
Clean up
leonidasmi Nov 21, 2024
76b5cca
Don't pass domain object through DI
leonidasmi Nov 21, 2024
8aa5fec
Import Scores_Interface
leonidasmi Nov 21, 2024
4c786a5
Don't pass scores list domain object through DI
leonidasmi Nov 21, 2024
9084ce6
Use abstract classes instead of traits
leonidasmi Nov 22, 2024
24be8d3
Fix parameter type
leonidasmi Nov 22, 2024
19c8839
Use exceptions when validating API parameters
leonidasmi Nov 22, 2024
188b4e4
Use list instead of array in the collector of the content types
leonidasmi Nov 22, 2024
85d9dd5
Have the queries return objects
leonidasmi Nov 22, 2024
610c0d8
Minor optimization in the collector queries
leonidasmi Nov 22, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
namespace Yoast\WP\SEO\Dashboard\Application\Content_Types;

use Yoast\WP\SEO\Dashboard\Application\Taxonomies\Taxonomies_Repository;
use Yoast\WP\SEO\Dashboard\Domain\Content_Types\Content_Type;
use Yoast\WP\SEO\Dashboard\Domain\Content_Types\Content_Types_List;
use Yoast\WP\SEO\Helpers\Post_Type_Helper;
use Yoast\WP\SEO\Dashboard\Infrastructure\Content_Types\Content_Types_Collector;

/**
* The repository to get content types.
Expand All @@ -16,16 +14,9 @@ class Content_Types_Repository {
/**
* The post type helper.
*
* @var Post_Type_Helper
* @var Content_Types_Collector
*/
protected $post_type_helper;

/**
* The content types list.
*
* @var Content_Types_List
*/
protected $content_types_list;
protected $content_types_collector;

/**
* The taxonomies repository.
Expand All @@ -37,18 +28,15 @@ class Content_Types_Repository {
/**
* The constructor.
*
* @param Post_Type_Helper $post_type_helper The post type helper.
* @param Content_Types_List $content_types_list The content types list.
* @param Taxonomies_Repository $taxonomies_repository The taxonomies repository.
* @param Content_Types_Collector $content_types_collector The post type helper.
* @param Taxonomies_Repository $taxonomies_repository The taxonomies repository.
*/
public function __construct(
Post_Type_Helper $post_type_helper,
Content_Types_List $content_types_list,
Content_Types_Collector $content_types_collector,
Taxonomies_Repository $taxonomies_repository
) {
$this->post_type_helper = $post_type_helper;
$this->content_types_list = $content_types_list;
$this->taxonomies_repository = $taxonomies_repository;
$this->content_types_collector = $content_types_collector;
$this->taxonomies_repository = $taxonomies_repository;
}

/**
Expand All @@ -57,16 +45,13 @@ public function __construct(
* @return array<array<string,array<string, array<string, array<string, string|null>>>>> The content types array.
*/
public function get_content_types(): array {
$post_types = $this->post_type_helper->get_indexable_post_types();

foreach ( $post_types as $post_type ) {
$post_type_object = \get_post_type_object( $post_type ); // @TODO: Refactor `Post_Type_Helper::get_indexable_post_types()` to be able to return objects. That way, we can remove this line.
$content_type_taxonomy = $this->taxonomies_repository->get_content_type_taxonomy( $post_type_object->name );
$content_types_list = $this->content_types_collector->get_content_types();

$content_type = new Content_Type( $post_type_object->name, $post_type_object->label, $content_type_taxonomy );
$this->content_types_list->add( $content_type );
foreach ( $content_types_list->get() as $content_type ) {
$content_type_taxonomy = $this->taxonomies_repository->get_content_type_taxonomy( $content_type->get_name() );
$content_type->set_taxonomy( $content_type_taxonomy );
}

return $this->content_types_list->to_array();
return $content_types_list->to_array();
}
}
77 changes: 77 additions & 0 deletions src/dashboard/application/scores/abstract-scores-repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Scores;

use Yoast\WP\SEO\Dashboard\Domain\Content_Types\Content_Type;
use Yoast\WP\SEO\Dashboard\Domain\Scores\Scores_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Scores\Scores_List;
use Yoast\WP\SEO\Dashboard\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dashboard\Infrastructure\Scores\Score_Link_Collector;
use Yoast\WP\SEO\Dashboard\Infrastructure\Scores\Scores_Collector_Interface;

/**
* The abstract scores repository.
*/
abstract class Abstract_Scores_Repository implements Scores_Repository_Interface {

/**
* The scores collector.
*
* @var Scores_Collector_Interface
*/
protected $scores_collector;

/**
* The score link collector.
*
* @var Score_Link_Collector
*/
protected $score_link_collector;

/**
* All scores.
*
* @var Scores_Interface[]
*/
protected $scores;

/**
* Sets the score link collector.
*
* @required
*
* @param Score_Link_Collector $score_link_collector The score link collector.
*
* @return void
*/
public function set_score_link_collector(
Score_Link_Collector $score_link_collector
) {
$this->score_link_collector = $score_link_collector;
}

/**
* Returns the scores of a content type.
*
* @param Content_Type $content_type The content type.
* @param Taxonomy|null $taxonomy The taxonomy of the term we're filtering for.
* @param int|null $term_id The ID of the term we're filtering for.
*
* @return array<array<string, string|int|array<string, string>>> The scores.
*/
public function get_scores( Content_Type $content_type, ?Taxonomy $taxonomy, ?int $term_id ): array {
$scores_list = new Scores_List();
$current_scores = $this->scores_collector->get_current_scores( $this->scores, $content_type, $term_id );

foreach ( $this->scores as $score ) {
$score_name = $score->get_name();
$score->set_amount( (int) $current_scores->$score_name );
$score->set_view_link( $this->score_link_collector->get_view_link( $score, $content_type, $taxonomy, $term_id ) );

$scores_list->add( $score );
}

return $scores_list->to_array();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Scores\Readability_Scores;

use Yoast\WP\SEO\Dashboard\Application\Scores\Abstract_Scores_Repository;
use Yoast\WP\SEO\Dashboard\Domain\Scores\Readability_Scores\Readability_Scores_Interface;
use Yoast\WP\SEO\Dashboard\Infrastructure\Scores\Readability_Scores\Readability_Scores_Collector;

/**
* The repository to get readability scores.
*/
class Readability_Scores_Repository extends Abstract_Scores_Repository {

/**
* The constructor.
*
* @param Readability_Scores_Collector $readability_scores_collector The readability scores collector.
* @param Readability_Scores_Interface ...$readability_scores All readability scores.
*/
public function __construct(
Readability_Scores_Collector $readability_scores_collector,
Readability_Scores_Interface ...$readability_scores
) {
$this->scores_collector = $readability_scores_collector;
$this->scores = $readability_scores;
}
}
24 changes: 24 additions & 0 deletions src/dashboard/application/scores/scores-repository-interface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Scores;

use Yoast\WP\SEO\Dashboard\Domain\Content_Types\Content_Type;
use Yoast\WP\SEO\Dashboard\Domain\Taxonomies\Taxonomy;

/**
* The interface class to score repositories.
*/
interface Scores_Repository_Interface {

/**
* Returns the scores of a content type.
*
* @param Content_Type $content_type The content type.
* @param Taxonomy|null $taxonomy The taxonomy of the term we're filtering for.
* @param int|null $term_id The ID of the term we're filtering for.
*
* @return array<array<string, string|int|array<string, string>>> The scores.
*/
public function get_scores( Content_Type $content_type, ?Taxonomy $taxonomy, ?int $term_id ): array;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Scores\SEO_Scores;

use Yoast\WP\SEO\Dashboard\Application\Scores\Abstract_Scores_Repository;
use Yoast\WP\SEO\Dashboard\Domain\Scores\SEO_Scores\SEO_Scores_Interface;
use Yoast\WP\SEO\Dashboard\Infrastructure\Scores\SEO_Scores\SEO_Scores_Collector;

/**
* The repository to get SEO Scores.
*/
class SEO_Scores_Repository extends Abstract_Scores_Repository {

/**
* The constructor.
*
* @param SEO_Scores_Collector $seo_scores_collector The SEO scores collector.
* @param SEO_Scores_Interface ...$seo_scores All SEO scores.
*/
public function __construct(
SEO_Scores_Collector $seo_scores_collector,
SEO_Scores_Interface ...$seo_scores
) {
$this->scores_collector = $seo_scores_collector;
$this->scores = $seo_scores;
}
}
13 changes: 12 additions & 1 deletion src/dashboard/domain/content-types/content-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Content_Type {
* @param string $label The label of the content type.
* @param Taxonomy|null $taxonomy The taxonomy that filters the content type.
*/
public function __construct( string $name, string $label, ?Taxonomy $taxonomy ) {
public function __construct( string $name, string $label, ?Taxonomy $taxonomy = null ) {
$this->name = $name;
$this->label = $label;
$this->taxonomy = $taxonomy;
Expand Down Expand Up @@ -69,4 +69,15 @@ public function get_label(): string {
public function get_taxonomy(): ?Taxonomy {
return $this->taxonomy;
}

/**
* Sets the taxonomy that filters the content type.
*
* @param Taxonomy|null $taxonomy The taxonomy that filters the content type.
*
* @return void
*/
public function set_taxonomy( ?Taxonomy $taxonomy ): void {
$this->taxonomy = $taxonomy;
}
}
11 changes: 10 additions & 1 deletion src/dashboard/domain/content-types/content-types-list.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@ class Content_Types_List {
* @return void
*/
public function add( Content_Type $content_type ): void {
$this->content_types[] = $content_type;
$this->content_types[ $content_type->get_name() ] = $content_type;
}

/**
* Returns the content types in the list.
*
* @return array<Content_Type> The content types in the list.
*/
public function get(): array {
return $this->content_types;
}

/**
Expand Down
105 changes: 105 additions & 0 deletions src/dashboard/domain/scores/abstract-score.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Scores;

/**
* Abstract class for a score.
*/
abstract class Abstract_Score implements Scores_Interface {

/**
* The name of the score.
*
* @var string
*/
private $name;

/**
* The key of the score that is used when filtering on the posts page.
*
* @var string
*/
private $filter_key;

/**
* The value of the score that is used when filtering on the posts page.
*
* @var string
*/
private $filter_value;

/**
* The min score of the score.
*
* @var int
*/
private $min_score;

/**
* The max score of the score.
*
* @var int
*/
private $max_score;

/**
* The amount of the score.
*
* @var int
*/
private $amount;

/**
* The view link of the score.
*
* @var string
*/
private $view_link;

/**
* The position of the score.
*
* @var int
*/
private $position;

/**
* Gets the amount of the score.
*
* @return int The amount of the score.
*/
public function get_amount(): int {
return $this->amount;
}

/**
* Sets the amount of the score.
*
* @param int $amount The amount of the score.
*
* @return void
*/
public function set_amount( int $amount ): void {
$this->amount = $amount;
}

/**
* Gets the view link of the score.
*
* @return string|null The view link of the score.
*/
public function get_view_link(): ?string {
return $this->view_link;
}

/**
* Sets the view link of the score.
*
* @param string $view_link The view link of the score.
*
* @return void
*/
public function set_view_link( ?string $view_link ): void {
$this->view_link = $view_link;
}
}
Loading
0