Skip to content
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

First run at a setup #21965

Merged
merged 15 commits into from
Jan 23, 2025
48 changes: 48 additions & 0 deletions src/dashboard/domain/data-provider/data-container.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Data_Provider;

/**
* The data container.
*/
class Data_Container {

/**
* All the search data points.
*
* @var array<Data_Interface> $data_container
*/
private $data_container;

/**
* The constructor
*/
public function __construct() {
$this->data_container = [];
}

/**
* Method to add data.
*
* @param Data_Interface $data The data.
*
* @return void
*/
public function add_data( Data_Interface $data ) {
$this->data_container[] = $data;
}

/**
* Converts the list to an array.
*
* @return array<string,string> The array of endpoints.
*/
public function to_array(): array {
$result = [];
foreach ( $this->data_container as $data ) {
$result[] = $data->to_array();
}

return $result;
}
}
16 changes: 16 additions & 0 deletions src/dashboard/domain/data-provider/data-interface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Data_Provider;

/**
* The interface to describe the data domain.
*/
interface Data_Interface {

/**
* A to array method.
*
* @return array<string>
*/
public function to_array(): array;
}
18 changes: 18 additions & 0 deletions src/dashboard/domain/data-provider/data-provider-interface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Data_Provider;

/**
* Interface describing the way to get data for a specific data provider.
*/
interface Data_Provider_Interface {

/**
* Method to get search related data from a provider.
*
* @param Parameters $parameters The parameter to get the search data for.
*
* @return Data_Container
*/
public function get_data( Parameters $parameters ): Data_Container;
}
90 changes: 90 additions & 0 deletions src/dashboard/domain/data-provider/parameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Data_Provider;

/**
* Object representation of the request parameters.
*/
abstract class Parameters {
thijsoo marked this conversation as resolved.
Show resolved Hide resolved

/**
* The start date.
*
* @var string $start_date
*/
private $start_date;

/**
* The end date.
*
* @var string $end_date
*/
private $end_date;

/**
* The amount of results.
*
* @var int $limit
*/
private $limit;

/**
* Getter for the start date.
*
* @return string
*/
public function get_start_date(): string {
return $this->start_date;
}

/**
* Getter for the end date.
* The date format should be Y-M-D.
*
* @return string
*/
public function get_end_date(): string {
return $this->end_date;
}

/**
* Getter for the result limit.
*
* @return int
*/
public function get_limit(): int {
return $this->limit;
}

/**
* The start date setter.
*
* @param string $start_date The start date.
*
* @return void
*/
public function set_start_date( string $start_date ): void {
$this->start_date = $start_date;
}

/**
* The end date setter.
*
* @param string $end_date The end date.
*
* @return void
*/
public function set_end_date( string $end_date ): void {
$this->end_date = $end_date;
}

/**
* The result limit.
*
* @param int $limit The result limit.
* @return void
*/
public function set_limit( int $limit ): void {
$this->limit = $limit;
}
}
88 changes: 88 additions & 0 deletions src/dashboard/domain/search-rankings/search-data.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Search_Rankings;

use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Interface;

/**
* Domain object that represents a single Search Data record.
*/
class Search_Data implements Data_Interface {

/**
* The amount of clicks a `key` gets.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no longer a key but rather a subject. Don't want to block merging because of that, I'll correct in my subsequent PR if that's ok.

*
* @var int $clicks
*/
private $clicks;

/**
* The click-through rate a `key` gets.
*
* @var float $clicks
*/
private $ctr;

/**
* The amount of impressions a `key` gets.
*
* @var int $impressions
*/
private $impressions;

/**
* The average position for the given `key`.
*
* @var float $position
*/
private $position;

/**
* An array representation of the different `keys`.
* In the context of this domain object keys can represent a `URI` or a `search term`
*
* @var string[]
*/
private $keys = [];

/**
* The seo score.
*
* @var int
*/
private $seo_score;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having reservations about whether the seo_score should be here or it should be injected by an indexable-related domain class, but let's see that in the final backend task for that widget.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unresolving this because indeed it needs to be dealt with in the future, so lets keep it open for future reference.

There are going to be search-ranking data that will not have seo scores, so we will need a tweak of the approach here, which we can do when we finalize the endpoint,


/**
* The constructor.
*
* @param int $clicks The clicks.
* @param float $ctr The ctr.
* @param int $impressions The impressions.
* @param float $position The position.
* @param string[] $keys The clicks.
*/
public function __construct( int $clicks, float $ctr, int $impressions, float $position, array $keys ) {
$this->clicks = $clicks;
$this->ctr = $ctr;
$this->impressions = $impressions;
$this->position = $position;
$this->keys = $keys;
$this->seo_score = 0;
}

/**
* The array representation of this domain object.
*
* @return array<string|float|int|string[]>
*/
public function to_array(): array {
return [
'clicks' => $this->clicks,
'ctr' => $this->ctr,
'impressions' => $this->impressions,
'position' => $this->position,
'keys' => $this->keys,
'seoScore' => $this->seo_score,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dashboard\Domain\Search_Rankings;

use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Provider_Interface;
use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Parameters;
use Yoast\WP\SEO\Dashboard\Infrastructure\Search_Console\Site_Kit_Search_Console_Adapter;
use Yoast\WP\SEO\Dashboard\Infrastructure\Search_Rankings\Search_Rankings_Parser;

/**
* The data provider for search ranking related data.
*/
class Search_Rankings_Data_Provider implements Data_Provider_Interface {

/**
* The adapter.
*
* @var Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter
*/
private $site_kit_search_console_adapter;

/**
* The ranking parser.
*
* @var Search_Rankings_Parser $search_rankings_parser
*/
private $search_rankings_parser;

/**
* The constructor.
*
* @param Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter The adapter.
* @param Search_Rankings_Parser $search_rankings_parser The parser.
*/
public function __construct( Site_Kit_Search_Console_Adapter $site_kit_search_console_adapter, Search_Rankings_Parser $search_rankings_parser ) {
$this->site_kit_search_console_adapter = $site_kit_search_console_adapter;
$this->search_rankings_parser = $search_rankings_parser;
}

/**
* Method to get search related data from a provider.
*
* @param Parameters $parameters The parameter to get the search data for.
*
* @return Data_Container
*/
public function get_data( Parameters $parameters ): Data_Container {

$results = $this->site_kit_search_console_adapter->get_data( $parameters );

return $this->search_rankings_parser->parse( $results );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
// phpcs:disable Yoast.NamingConventions.NamespaceName.MaxExceeded
namespace Yoast\WP\SEO\Dashboard\Infrastructure\Endpoints\Search_Rankings;

use Exception;
use Yoast\WP\SEO\Dashboard\Domain\Endpoint\Endpoint_Interface;
use Yoast\WP\SEO\Dashboard\User_Interface\Search_Rankings\Abstract_Ranking_Route;
use Yoast\WP\SEO\Dashboard\User_Interface\Search_Rankings\Top_Page_Route;

/**
* Represents the top page results endpoint.
*/
class Top_Page_Endpoint implements Endpoint_Interface {

/**
* Gets the name.
*
* @return string
*/
public function get_name(): string {
return 'topPageResults';
}

/**
* Gets the namespace.
*
* @return string
*/
public function get_namespace(): string {
return Abstract_Ranking_Route::ROUTE_NAMESPACE;
}

/**
* Gets the route.
*
* @throws Exception If the route prefix is not overwritten this throws.
* @return string
*/
public function get_route(): string {
return Top_Page_Route::get_route_prefix();
}

/**
* Gets the URL.
*
* @return string
*/
public function get_url(): string {
return \rest_url( $this->get_namespace() . $this->get_route() );
}
}
Loading
Loading