Phase 5: Content and SEO - Yoast SEO, Schema.org markup, Open Graph, favicon support, XML sitemap

This commit is contained in:
Hanson.xyz Dev
2025-11-28 17:10:24 -06:00
parent c4f29a3152
commit 91de533da4
1552 changed files with 171432 additions and 7 deletions
@@ -0,0 +1,157 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dashboard\Application\Configuration;
use Yoast\WP\SEO\Dashboard\Application\Content_Types\Content_Types_Repository;
use Yoast\WP\SEO\Dashboard\Application\Endpoints\Endpoints_Repository;
use Yoast\WP\SEO\Dashboard\Application\Tracking\Setup_Steps_Tracking;
use Yoast\WP\SEO\Dashboard\Infrastructure\Browser_Cache\Browser_Cache_Configuration;
use Yoast\WP\SEO\Dashboard\Infrastructure\Integrations\Site_Kit;
use Yoast\WP\SEO\Dashboard\Infrastructure\Nonces\Nonce_Repository;
use Yoast\WP\SEO\Editors\Application\Analysis_Features\Enabled_Analysis_Features_Repository;
use Yoast\WP\SEO\Editors\Framework\Keyphrase_Analysis;
use Yoast\WP\SEO\Editors\Framework\Readability_Analysis;
use Yoast\WP\SEO\Helpers\Indexable_Helper;
use Yoast\WP\SEO\Helpers\User_Helper;
/**
* Responsible for the dashboard configuration.
*/
class Dashboard_Configuration {
/**
* The content types repository.
*
* @var Content_Types_Repository
*/
private $content_types_repository;
/**
* The indexable helper.
*
* @var Indexable_Helper
*/
private $indexable_helper;
/**
* The user helper.
*
* @var User_Helper
*/
private $user_helper;
/**
* The repository.
*
* @var Enabled_Analysis_Features_Repository
*/
private $enabled_analysis_features_repository;
/**
* The endpoints repository.
*
* @var Endpoints_Repository
*/
private $endpoints_repository;
/**
* The nonce repository.
*
* @var Nonce_Repository
*/
private $nonce_repository;
/**
* The Site Kit integration data.
*
* @var Site_Kit
*/
private $site_kit_integration_data;
/**
* The setup steps tracking data.
*
* @var Setup_Steps_Tracking
*/
private $setup_steps_tracking;
/**
* The browser cache configuration.
*
* @var Browser_Cache_Configuration
*/
private $browser_cache_configuration;
/**
* The constructor.
*
* @param Content_Types_Repository $content_types_repository The content types repository.
* @param Indexable_Helper $indexable_helper The indexable helper
* repository.
* @param User_Helper $user_helper The user helper.
* @param Enabled_Analysis_Features_Repository $enabled_analysis_features_repository The analysis feature.
* repository.
* @param Endpoints_Repository $endpoints_repository The endpoints repository.
* @param Nonce_Repository $nonce_repository The nonce repository.
* @param Site_Kit $site_kit_integration_data The Site Kit integration data.
* @param Setup_Steps_Tracking $setup_steps_tracking The setup steps tracking data.
* @param Browser_Cache_Configuration $browser_cache_configuration The browser cache configuration.
*/
public function __construct(
Content_Types_Repository $content_types_repository,
Indexable_Helper $indexable_helper,
User_Helper $user_helper,
Enabled_Analysis_Features_Repository $enabled_analysis_features_repository,
Endpoints_Repository $endpoints_repository,
Nonce_Repository $nonce_repository,
Site_Kit $site_kit_integration_data,
Setup_Steps_Tracking $setup_steps_tracking,
Browser_Cache_Configuration $browser_cache_configuration
) {
$this->content_types_repository = $content_types_repository;
$this->indexable_helper = $indexable_helper;
$this->user_helper = $user_helper;
$this->enabled_analysis_features_repository = $enabled_analysis_features_repository;
$this->endpoints_repository = $endpoints_repository;
$this->nonce_repository = $nonce_repository;
$this->site_kit_integration_data = $site_kit_integration_data;
$this->setup_steps_tracking = $setup_steps_tracking;
$this->browser_cache_configuration = $browser_cache_configuration;
}
/**
* Returns a configuration
*
* @return array<string, array<string>|array<string, string|array<string, array<string, int>>>>
*/
public function get_configuration(): array {
$configuration = [
'contentTypes' => $this->content_types_repository->get_content_types(),
'indexablesEnabled' => $this->indexable_helper->should_index_indexables(),
'displayName' => $this->user_helper->get_current_user_display_name(),
'enabledAnalysisFeatures' => $this->enabled_analysis_features_repository->get_features_by_keys(
[
Readability_Analysis::NAME,
Keyphrase_Analysis::NAME,
]
)->to_array(),
'endpoints' => $this->endpoints_repository->get_all_endpoints()->to_array(),
'nonce' => $this->nonce_repository->get_rest_nonce(),
'setupStepsTracking' => $this->setup_steps_tracking->to_array(),
];
$site_kit_integration_data = $this->site_kit_integration_data->to_array();
if ( ! empty( $site_kit_integration_data ) ) {
$configuration ['siteKitConfiguration'] = $site_kit_integration_data;
}
$browser_cache_configuration = $this->browser_cache_configuration->get_configuration();
if ( ! empty( $browser_cache_configuration ) ) {
$configuration ['browserCache'] = $browser_cache_configuration;
}
return $configuration;
}
}
@@ -0,0 +1,57 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dashboard\Application\Content_Types;
use Yoast\WP\SEO\Dashboard\Application\Taxonomies\Taxonomies_Repository;
use Yoast\WP\SEO\Dashboard\Infrastructure\Content_Types\Content_Types_Collector;
/**
* The repository to get content types.
*/
class Content_Types_Repository {
/**
* The post type helper.
*
* @var Content_Types_Collector
*/
protected $content_types_collector;
/**
* The taxonomies repository.
*
* @var Taxonomies_Repository
*/
private $taxonomies_repository;
/**
* The constructor.
*
* @param Content_Types_Collector $content_types_collector The post type helper.
* @param Taxonomies_Repository $taxonomies_repository The taxonomies repository.
*/
public function __construct(
Content_Types_Collector $content_types_collector,
Taxonomies_Repository $taxonomies_repository
) {
$this->content_types_collector = $content_types_collector;
$this->taxonomies_repository = $taxonomies_repository;
}
/**
* Returns the content types array.
*
* @return array<array<string, array<string, array<string, array<string, string|null>>>>> The content types array.
*/
public function get_content_types(): array {
$content_types_list = $this->content_types_collector->get_content_types();
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 $content_types_list->to_array();
}
}
@@ -0,0 +1,42 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Endpoints;
use Yoast\WP\SEO\Dashboard\Domain\Endpoint\Endpoint_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Endpoint\Endpoint_List;
/**
* Repository for endpoints.
*/
class Endpoints_Repository {
/**
* Holds the endpoints.
*
* @var array<Endpoint_Interface>
*/
private $endpoints;
/**
* Constructs the repository.
*
* @param Endpoint_Interface ...$endpoints The endpoints to add to the repository.
*/
public function __construct( Endpoint_Interface ...$endpoints ) {
$this->endpoints = $endpoints;
}
/**
* Creates a list with all endpoints.
*
* @return Endpoint_List The list with all endpoints.
*/
public function get_all_endpoints(): Endpoint_List {
$list = new Endpoint_List();
foreach ( $this->endpoints as $endpoint ) {
$list->add_endpoint( $endpoint );
}
return $list;
}
}
@@ -0,0 +1,59 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dashboard\Application\Filter_Pairs;
use Yoast\WP\SEO\Dashboard\Domain\Filter_Pairs\Filter_Pairs_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dashboard\Infrastructure\Taxonomies\Taxonomies_Collector;
/**
* The repository to get hardcoded filter pairs.
*/
class Filter_Pairs_Repository {
/**
* The taxonomies collector.
*
* @var Taxonomies_Collector
*/
private $taxonomies_collector;
/**
* All filter pairs.
*
* @var Filter_Pairs_Interface[]
*/
private $filter_pairs;
/**
* The constructor.
*
* @param Taxonomies_Collector $taxonomies_collector The taxonomies collector.
* @param Filter_Pairs_Interface ...$filter_pairs All filter pairs.
*/
public function __construct(
Taxonomies_Collector $taxonomies_collector,
Filter_Pairs_Interface ...$filter_pairs
) {
$this->taxonomies_collector = $taxonomies_collector;
$this->filter_pairs = $filter_pairs;
}
/**
* Returns a taxonomy based on a content type, by looking into hardcoded filter pairs.
*
* @param string $content_type The content type.
*
* @return Taxonomy|null The taxonomy filter.
*/
public function get_taxonomy( string $content_type ): ?Taxonomy {
foreach ( $this->filter_pairs as $filter_pair ) {
if ( $filter_pair->get_filtered_content_type() === $content_type ) {
return $this->taxonomies_collector->get_taxonomy( $filter_pair->get_filtering_taxonomy(), $content_type );
}
}
return null;
}
}
@@ -0,0 +1,55 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dashboard\Application\Score_Groups\SEO_Score_Groups;
use Yoast\WP\SEO\Dashboard\Domain\Score_Groups\SEO_Score_Groups\No_SEO_Score_Group;
use Yoast\WP\SEO\Dashboard\Domain\Score_Groups\SEO_Score_Groups\SEO_Score_Groups_Interface;
/**
* The repository to get SEO score groups.
*/
class SEO_Score_Groups_Repository {
/**
* All SEO score groups.
*
* @var SEO_Score_Groups_Interface[]
*/
private $seo_score_groups;
/**
* The constructor.
*
* @param SEO_Score_Groups_Interface ...$seo_score_groups All SEO score groups.
*/
public function __construct( SEO_Score_Groups_Interface ...$seo_score_groups ) {
$this->seo_score_groups = $seo_score_groups;
}
/**
* Returns the SEO score group that a SEO score belongs to.
*
* @param int $seo_score The SEO score to be assigned into a group.
*
* @return SEO_Score_Groups_Interface The SEO score group that the SEO score belongs to.
*/
public function get_seo_score_group( ?int $seo_score ): SEO_Score_Groups_Interface {
if ( $seo_score === null || $seo_score === 0 ) {
return new No_SEO_Score_Group();
}
foreach ( $this->seo_score_groups as $seo_score_group ) {
if ( $seo_score_group->get_max_score() === null ) {
continue;
}
if ( $seo_score >= $seo_score_group->get_min_score() && $seo_score <= $seo_score_group->get_max_score() ) {
return $seo_score_group;
}
}
return new No_SEO_Score_Group();
}
}
@@ -0,0 +1,80 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Score_Results;
use Exception;
use Yoast\WP\SEO\Dashboard\Domain\Content_Types\Content_Type;
use Yoast\WP\SEO\Dashboard\Domain\Score_Groups\Score_Groups_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Score_Results\Score_Result;
use Yoast\WP\SEO\Dashboard\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dashboard\Infrastructure\Score_Results\Score_Results_Collector_Interface;
/**
* The abstract score results repository.
*/
abstract class Abstract_Score_Results_Repository {
/**
* The score results collector.
*
* @var Score_Results_Collector_Interface
*/
protected $score_results_collector;
/**
* The current scores repository.
*
* @var Current_Scores_Repository
*/
protected $current_scores_repository;
/**
* All score groups.
*
* @var Score_Groups_Interface[]
*/
protected $score_groups;
/**
* Sets the repositories.
*
* @required
*
* @param Current_Scores_Repository $current_scores_repository The current scores repository.
*
* @return void
*/
public function set_repositories( Current_Scores_Repository $current_scores_repository ) {
$this->current_scores_repository = $current_scores_repository;
}
/**
* Returns the score results for 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.
* @param bool|null $is_troubleshooting Whether we're in troubleshooting mode.
*
* @return array<array<string, string|int|array<string, string>>> The scores.
*
* @throws Exception When getting score results from the infrastructure fails.
*/
public function get_score_results( Content_Type $content_type, ?Taxonomy $taxonomy, ?int $term_id, ?bool $is_troubleshooting ): array {
$score_results = $this->score_results_collector->get_score_results( $this->score_groups, $content_type, $term_id, $is_troubleshooting );
if ( $is_troubleshooting === true ) {
$score_results['score_ids'] = clone $score_results['scores'];
foreach ( $score_results['scores'] as &$score ) {
$score = ( $score !== null ) ? \count( \explode( ',', $score ) ) : 0;
}
}
$current_scores_list = $this->current_scores_repository->get_current_scores( $this->score_groups, $score_results, $content_type, $taxonomy, $term_id );
$score_result_object = new Score_Result( $current_scores_list, $score_results['query_time'], $score_results['cache_used'] );
return $score_result_object->to_array();
}
}
@@ -0,0 +1,76 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Score_Results;
use Yoast\WP\SEO\Dashboard\Domain\Content_Types\Content_Type;
use Yoast\WP\SEO\Dashboard\Domain\Score_Groups\Score_Groups_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Score_Results\Current_Score;
use Yoast\WP\SEO\Dashboard\Domain\Score_Results\Current_Scores_List;
use Yoast\WP\SEO\Dashboard\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dashboard\Infrastructure\Score_Groups\Score_Group_Link_Collector;
/**
* The current scores repository.
*/
class Current_Scores_Repository {
/**
* The score group link collector.
*
* @var Score_Group_Link_Collector
*/
protected $score_group_link_collector;
/**
* The constructor.
*
* @param Score_Group_Link_Collector $score_group_link_collector The score group link collector.
*/
public function __construct( Score_Group_Link_Collector $score_group_link_collector ) {
$this->score_group_link_collector = $score_group_link_collector;
}
/**
* Returns the current results.
*
* @param Score_Groups_Interface[] $score_groups The score groups.
* @param array<string, string> $score_results The score results.
* @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 current results.
*/
public function get_current_scores( array $score_groups, array $score_results, Content_Type $content_type, ?Taxonomy $taxonomy, ?int $term_id ): Current_Scores_List {
$current_scores_list = new Current_Scores_List();
foreach ( $score_groups as $score_group ) {
$score_name = $score_group->get_name();
$current_score_links = $this->get_current_score_links( $score_group, $content_type, $taxonomy, $term_id );
$score_amount = (int) $score_results['scores']->$score_name;
$score_ids = ( isset( $score_results['score_ids'] ) ) ? $score_results['score_ids']->$score_name : null;
$current_score = new Current_Score( $score_name, $score_amount, $score_ids, $current_score_links );
$current_scores_list->add( $current_score, $score_group->get_position() );
}
return $current_scores_list;
}
/**
* Returns the links for the current scores of a score group.
*
* @param Score_Groups_Interface $score_group The scoure group.
* @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<string, string> The current score links.
*/
protected function get_current_score_links( Score_Groups_Interface $score_group, Content_Type $content_type, ?Taxonomy $taxonomy, ?int $term_id ): array {
return [
'view' => $this->score_group_link_collector->get_view_link( $score_group, $content_type, $taxonomy, $term_id ),
];
}
}
@@ -0,0 +1,28 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Score_Results\Readability_Score_Results;
use Yoast\WP\SEO\Dashboard\Application\Score_Results\Abstract_Score_Results_Repository;
use Yoast\WP\SEO\Dashboard\Domain\Score_Groups\Readability_Score_Groups\Readability_Score_Groups_Interface;
use Yoast\WP\SEO\Dashboard\Infrastructure\Score_Results\Readability_Score_Results\Cached_Readability_Score_Results_Collector;
/**
* The repository to get readability score results.
*/
class Readability_Score_Results_Repository extends Abstract_Score_Results_Repository {
/**
* The constructor.
*
* @param Cached_Readability_Score_Results_Collector $readability_score_results_collector The cached readability score results collector.
* @param Readability_Score_Groups_Interface ...$readability_score_groups All readability score groups.
*/
public function __construct(
Cached_Readability_Score_Results_Collector $readability_score_results_collector,
Readability_Score_Groups_Interface ...$readability_score_groups
) {
$this->score_results_collector = $readability_score_results_collector;
$this->score_groups = $readability_score_groups;
}
}
@@ -0,0 +1,28 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Application\Score_Results\SEO_Score_Results;
use Yoast\WP\SEO\Dashboard\Application\Score_Results\Abstract_Score_Results_Repository;
use Yoast\WP\SEO\Dashboard\Domain\Score_Groups\SEO_Score_Groups\SEO_Score_Groups_Interface;
use Yoast\WP\SEO\Dashboard\Infrastructure\Score_Results\SEO_Score_Results\Cached_SEO_Score_Results_Collector;
/**
* The repository to get SEO score results.
*/
class SEO_Score_Results_Repository extends Abstract_Score_Results_Repository {
/**
* The constructor.
*
* @param Cached_SEO_Score_Results_Collector $seo_score_results_collector The cached SEO score results collector.
* @param SEO_Score_Groups_Interface ...$seo_score_groups All SEO score groups.
*/
public function __construct(
Cached_SEO_Score_Results_Collector $seo_score_results_collector,
SEO_Score_Groups_Interface ...$seo_score_groups
) {
$this->score_results_collector = $seo_score_results_collector;
$this->score_groups = $seo_score_groups;
}
}
@@ -0,0 +1,61 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Search_Rankings;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Dashboard_Repository_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Parameters;
use Yoast\WP\SEO\Dashboard\Domain\Time_Based_Seo_Metrics\Data_Source_Not_Available_Exception;
use Yoast\WP\SEO\Dashboard\Infrastructure\Integrations\Site_Kit;
use Yoast\WP\SEO\Dashboard\Infrastructure\Search_Console\Site_Kit_Search_Console_Adapter;
/**
* The data provider for comparing search ranking related data.
*/
class Search_Ranking_Compare_Repository implements Dashboard_Repository_Interface {
/**
* The adapter.
*
* @var Site_Kit_Search_Console_Adapter
*/
private $site_kit_search_console_adapter;
/**
* The site kit configuration object.
*
* @var Site_Kit
*/
private $site_kit_configuration;
/**
* The constructor.
*
* @param Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter The adapter.
* @param Site_Kit $site_kit_configuration The site kit configuration object.
*/
public function __construct(
Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter,
Site_Kit $site_kit_configuration
) {
$this->site_kit_search_console_adapter = $site_kit_search_console_adapter;
$this->site_kit_configuration = $site_kit_configuration;
}
/**
* Gets the comparing search ranking data.
*
* @param Parameters $parameters The parameter to use for getting the comparing search ranking data.
*
* @return Data_Container
*
* @throws Data_Source_Not_Available_Exception When getting the comparing search ranking data fails.
*/
public function get_data( Parameters $parameters ): Data_Container {
if ( ! $this->site_kit_configuration->is_onboarded() ) {
throw new Data_Source_Not_Available_Exception( 'Comparison search ranking repository' );
}
return $this->site_kit_search_console_adapter->get_comparison_data( $parameters );
}
}
@@ -0,0 +1,74 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Search_Rankings;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Dashboard_Repository_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Parameters;
use Yoast\WP\SEO\Dashboard\Domain\Time_Based_Seo_Metrics\Data_Source_Not_Available_Exception;
use Yoast\WP\SEO\Dashboard\Infrastructure\Indexables\Top_Page_Indexable_Collector;
use Yoast\WP\SEO\Dashboard\Infrastructure\Integrations\Site_Kit;
use Yoast\WP\SEO\Dashboard\Infrastructure\Search_Console\Site_Kit_Search_Console_Adapter;
/**
* The data provider for top page data.
*/
class Top_Page_Repository implements Dashboard_Repository_Interface {
/**
* The adapter.
*
* @var Site_Kit_Search_Console_Adapter
*/
private $site_kit_search_console_adapter;
/**
* The top page indexable collector.
*
* @var Top_Page_Indexable_Collector
*/
private $top_page_indexable_collector;
/**
* The site kit configuration object.
*
* @var Site_Kit
*/
private $site_kit_configuration;
/**
* The constructor.
*
* @param Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter The adapter.
* @param Top_Page_Indexable_Collector $top_page_indexable_collector The top page indexable collector.
* @param Site_Kit $site_kit_configuration The site kit configuration object.
*/
public function __construct(
Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter,
Top_Page_Indexable_Collector $top_page_indexable_collector,
Site_Kit $site_kit_configuration
) {
$this->site_kit_search_console_adapter = $site_kit_search_console_adapter;
$this->top_page_indexable_collector = $top_page_indexable_collector;
$this->site_kit_configuration = $site_kit_configuration;
}
/**
* Gets the top pages' data.
*
* @param Parameters $parameters The parameter to use for getting the top pages.
*
* @return Data_Container
*
* @throws Data_Source_Not_Available_Exception When this repository is used without the needed prerequisites ready.
*/
public function get_data( Parameters $parameters ): Data_Container {
if ( ! $this->site_kit_configuration->is_onboarded() ) {
throw new Data_Source_Not_Available_Exception( 'Top page repository' );
}
$top_pages_search_ranking_data = $this->site_kit_search_console_adapter->get_data( $parameters );
$top_pages_full_data = $this->top_page_indexable_collector->get_data( $top_pages_search_ranking_data );
return $top_pages_full_data;
}
}
@@ -0,0 +1,61 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Search_Rankings;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Dashboard_Repository_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Parameters;
use Yoast\WP\SEO\Dashboard\Domain\Time_Based_Seo_Metrics\Data_Source_Not_Available_Exception;
use Yoast\WP\SEO\Dashboard\Infrastructure\Integrations\Site_Kit;
use Yoast\WP\SEO\Dashboard\Infrastructure\Search_Console\Site_Kit_Search_Console_Adapter;
/**
* The data provider for top query data.
*/
class Top_Query_Repository implements Dashboard_Repository_Interface {
/**
* The adapter.
*
* @var Site_Kit_Search_Console_Adapter
*/
private $site_kit_search_console_adapter;
/**
* The site kit configuration object.
*
* @var Site_Kit
*/
private $site_kit_configuration;
/**
* The constructor.
*
* @param Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter The adapter.
* @param Site_Kit $site_kit_configuration The site kit configuration object.
*/
public function __construct(
Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter,
Site_Kit $site_kit_configuration
) {
$this->site_kit_search_console_adapter = $site_kit_search_console_adapter;
$this->site_kit_configuration = $site_kit_configuration;
}
/**
* Gets the top queries' data.
*
* @param Parameters $parameters The parameter to use for getting the top queries.
*
* @return Data_Container
*
* @throws Data_Source_Not_Available_Exception When this repository is used without the needed prerequisites ready.
*/
public function get_data( Parameters $parameters ): Data_Container {
if ( ! $this->site_kit_configuration->is_onboarded() ) {
throw new Data_Source_Not_Available_Exception( 'Top queries repository' );
}
return $this->site_kit_search_console_adapter->get_data( $parameters );
}
}
@@ -0,0 +1,66 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dashboard\Application\Taxonomies;
use Yoast\WP\SEO\Dashboard\Application\Filter_Pairs\Filter_Pairs_Repository;
use Yoast\WP\SEO\Dashboard\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dashboard\Infrastructure\Taxonomies\Taxonomies_Collector;
/**
* The repository to get taxonomies.
*/
class Taxonomies_Repository {
/**
* The taxonomies collector.
*
* @var Taxonomies_Collector
*/
private $taxonomies_collector;
/**
* The filter pairs repository.
*
* @var Filter_Pairs_Repository
*/
private $filter_pairs_repository;
/**
* The constructor.
*
* @param Taxonomies_Collector $taxonomies_collector The taxonomies collector.
* @param Filter_Pairs_Repository $filter_pairs_repository The filter pairs repository.
*/
public function __construct(
Taxonomies_Collector $taxonomies_collector,
Filter_Pairs_Repository $filter_pairs_repository
) {
$this->taxonomies_collector = $taxonomies_collector;
$this->filter_pairs_repository = $filter_pairs_repository;
}
/**
* Returns the object of the filtering taxonomy of a content type.
*
* @param string $content_type The content type that the taxonomy filters.
*
* @return Taxonomy|null The filtering taxonomy of the content type.
*/
public function get_content_type_taxonomy( string $content_type ) {
// First we check if there's a filter that overrides the filtering taxonomy for this content type.
$taxonomy = $this->taxonomies_collector->get_custom_filtering_taxonomy( $content_type );
if ( $taxonomy ) {
return $taxonomy;
}
// Then we check if there is a filter explicitly made for this content type.
$taxonomy = $this->filter_pairs_repository->get_taxonomy( $content_type );
if ( $taxonomy ) {
return $taxonomy;
}
// If everything else returned empty, we can always try the fallback taxonomy.
return $this->taxonomies_collector->get_fallback_taxonomy( $content_type );
}
}
@@ -0,0 +1,87 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Tracking;
use Yoast\WP\SEO\Dashboard\Infrastructure\Tracking\Setup_Steps_Tracking_Repository_Interface;
/**
* Tracks the setup steps.
*/
class Setup_Steps_Tracking {
/**
* The setup steps tracking repository.
*
* @var Setup_Steps_Tracking_Repository_Interface
*/
private $setup_steps_tracking_repository;
/**
* Constructs the class.
*
* @param Setup_Steps_Tracking_Repository_Interface $setup_steps_tracking_repository The setup steps tracking repository.
*/
public function __construct( Setup_Steps_Tracking_Repository_Interface $setup_steps_tracking_repository ) {
$this->setup_steps_tracking_repository = $setup_steps_tracking_repository;
}
/**
* If the Site Kit setup widget has been loaded.
*
* @return string "yes" on "no".
*/
public function get_setup_widget_loaded(): string {
return $this->setup_steps_tracking_repository->get_setup_steps_tracking_element( 'setup_widget_loaded' );
}
/**
* Gets the stage of the first interaction.
*
* @return string The stage name.
*/
public function get_first_interaction_stage(): string {
return $this->setup_steps_tracking_repository->get_setup_steps_tracking_element( 'first_interaction_stage' );
}
/**
* Gets the stage of the last interaction.
*
* @return string The stage name.
*/
public function get_last_interaction_stage(): string {
return $this->setup_steps_tracking_repository->get_setup_steps_tracking_element( 'last_interaction_stage' );
}
/**
* If the setup widget has been temporarily dismissed.
*
* @return string "yes" on "no".
*/
public function get_setup_widget_temporarily_dismissed(): string {
return $this->setup_steps_tracking_repository->get_setup_steps_tracking_element( 'setup_widget_temporarily_dismissed' );
}
/**
* If the setup widget has been permanently dismissed.
*
* @return string "yes" on "no".
*/
public function get_setup_widget_permanently_dismissed(): string {
return $this->setup_steps_tracking_repository->get_setup_steps_tracking_element( 'setup_widget_permanently_dismissed' );
}
/**
* Return this object represented by a key value array.
*
* @return array<string> The tracking data
*/
public function to_array(): array {
return [
'setupWidgetLoaded' => $this->get_setup_widget_loaded(),
'firstInteractionStage' => $this->get_first_interaction_stage(),
'lastInteractionStage' => $this->get_last_interaction_stage(),
'setupWidgetTemporarilyDismissed' => $this->get_setup_widget_temporarily_dismissed(),
'setupWidgetPermanentlyDismissed' => $this->get_setup_widget_permanently_dismissed(),
];
}
}
@@ -0,0 +1,61 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Traffic;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Dashboard_Repository_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Parameters;
use Yoast\WP\SEO\Dashboard\Domain\Time_Based_Seo_Metrics\Data_Source_Not_Available_Exception;
use Yoast\WP\SEO\Dashboard\Infrastructure\Analytics_4\Site_Kit_Analytics_4_Adapter;
use Yoast\WP\SEO\Dashboard\Infrastructure\Integrations\Site_Kit;
/**
* The data provider for comparison organic sessions data.
*/
class Organic_Sessions_Compare_Repository implements Dashboard_Repository_Interface {
/**
* The adapter.
*
* @var Site_Kit_Analytics_4_Adapter
*/
private $site_kit_analytics_4_adapter;
/**
* The site kit configuration object.
*
* @var Site_Kit
*/
private $site_kit_configuration;
/**
* The constructor.
*
* @param Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter The adapter.
* @param Site_Kit $site_kit_configuration The site kit configuration object.
*/
public function __construct(
Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter,
Site_Kit $site_kit_configuration
) {
$this->site_kit_analytics_4_adapter = $site_kit_analytics_4_adapter;
$this->site_kit_configuration = $site_kit_configuration;
}
/**
* Gets comparison organic sessions' data.
*
* @param Parameters $parameters The parameter to use for getting the comparison organic sessions' data.
*
* @return Data_Container
*
* @throws Data_Source_Not_Available_Exception When getting the comparison organic sessions' data fails.
*/
public function get_data( Parameters $parameters ): Data_Container {
if ( ! $this->site_kit_configuration->is_onboarded() || ! $this->site_kit_configuration->is_ga_connected() ) {
throw new Data_Source_Not_Available_Exception( 'Comparison organic sessions repository' );
}
return $this->site_kit_analytics_4_adapter->get_comparison_data( $parameters );
}
}
@@ -0,0 +1,61 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Application\Traffic;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Dashboard_Repository_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Parameters;
use Yoast\WP\SEO\Dashboard\Domain\Time_Based_Seo_Metrics\Data_Source_Not_Available_Exception;
use Yoast\WP\SEO\Dashboard\Infrastructure\Analytics_4\Site_Kit_Analytics_4_Adapter;
use Yoast\WP\SEO\Dashboard\Infrastructure\Integrations\Site_Kit;
/**
* The data provider for daily organic sessions data.
*/
class Organic_Sessions_Daily_Repository implements Dashboard_Repository_Interface {
/**
* The adapter.
*
* @var Site_Kit_Analytics_4_Adapter
*/
private $site_kit_analytics_4_adapter;
/**
* The site kit configuration object.
*
* @var Site_Kit
*/
private $site_kit_configuration;
/**
* The constructor.
*
* @param Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter The adapter.
* @param Site_Kit $site_kit_configuration The site kit configuration object.
*/
public function __construct(
Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter,
Site_Kit $site_kit_configuration
) {
$this->site_kit_analytics_4_adapter = $site_kit_analytics_4_adapter;
$this->site_kit_configuration = $site_kit_configuration;
}
/**
* Gets daily organic sessions' data.
*
* @param Parameters $parameters The parameter to use for getting the daily organic sessions' data.
*
* @return Data_Container
*
* @throws Data_Source_Not_Available_Exception When this repository is used without the needed prerequisites ready.
*/
public function get_data( Parameters $parameters ): Data_Container {
if ( ! $this->site_kit_configuration->is_onboarded() || ! $this->site_kit_configuration->is_ga_connected() ) {
throw new Data_Source_Not_Available_Exception( 'Daily organic sessions repository' );
}
return $this->site_kit_analytics_4_adapter->get_daily_data( $parameters );
}
}