diff --git a/src/dashboard/application/search-rankings/top-page-repository.php b/src/dashboard/application/search-rankings/top-page-repository.php index 0330eec6ff9..6312a335cb2 100644 --- a/src/dashboard/application/search-rankings/top-page-repository.php +++ b/src/dashboard/application/search-rankings/top-page-repository.php @@ -52,8 +52,8 @@ public function __construct( */ public function get_data( Parameters $parameters ): Data_Container { - $top_pages_search_data = $this->site_kit_search_console_adapter->get_data( $parameters ); - $top_pages_full_data = $this->top_page_indexable_collector->get_data( $top_pages_search_data ); + $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; } diff --git a/src/dashboard/application/search-rankings/top-query-repository.php b/src/dashboard/application/search-rankings/top-query-repository.php index ee9c05a63d1..bc0389eb791 100644 --- a/src/dashboard/application/search-rankings/top-query-repository.php +++ b/src/dashboard/application/search-rankings/top-query-repository.php @@ -29,9 +29,9 @@ public function __construct( Site_Kit_Search_Console_Adapter $site_kit_search_co } /** - * Method to get search related data from a provider. + * Gets the top queries' data. * - * @param Parameters $parameters The parameter to get the search data for. + * @param Parameters $parameters The parameter to use for getting the top queries. * * @return Data_Container */ diff --git a/src/dashboard/application/traffic/organic-sessions-repository.php b/src/dashboard/application/traffic/organic-sessions-repository.php new file mode 100644 index 00000000000..35e1280856d --- /dev/null +++ b/src/dashboard/application/traffic/organic-sessions-repository.php @@ -0,0 +1,48 @@ +site_kit_analytics_4_adapter = $site_kit_analytics_4_adapter; + } + + /** + * Gets the organic sessions' data. + * + * @param Parameters $parameters The parameter to use for getting the organic sessions' data. + * + * @return Data_Container + * + * @throws Exception When getting the organic sessions' data fails. + */ + public function get_data( Parameters $parameters ): Data_Container { + + $organic_sessions_data = $this->site_kit_analytics_4_adapter->get_data( $parameters ); + + return $organic_sessions_data; + } +} diff --git a/src/dashboard/domain/analytics-4/failed-request-exception.php b/src/dashboard/domain/analytics-4/failed-request-exception.php new file mode 100644 index 00000000000..917de5c954e --- /dev/null +++ b/src/dashboard/domain/analytics-4/failed-request-exception.php @@ -0,0 +1,21 @@ +limit; } + /** + * Getter for the compare start date. + * + * @return string + */ + public function get_compare_start_date(): ?string { + return $this->compare_start_date; + } + + /** + * Getter for the compare end date. + * The date format should be Y-M-D. + * + * @return string + */ + public function get_compare_end_date(): ?string { + return $this->compare_end_date; + } + /** * The start date setter. * @@ -87,4 +120,26 @@ public function set_end_date( string $end_date ): void { public function set_limit( int $limit ): void { $this->limit = $limit; } + + /** + * The compare start date setter. + * + * @param string $compare_start_date The compare start date. + * + * @return void + */ + public function set_compare_start_date( string $compare_start_date ): void { + $this->compare_start_date = $compare_start_date; + } + + /** + * The compare end date setter. + * + * @param string $compare_end_date The compare end date. + * + * @return void + */ + public function set_compare_end_date( string $compare_end_date ): void { + $this->compare_end_date = $compare_end_date; + } } diff --git a/src/dashboard/domain/search-rankings/search-data.php b/src/dashboard/domain/search-rankings/search-ranking-data.php similarity index 93% rename from src/dashboard/domain/search-rankings/search-data.php rename to src/dashboard/domain/search-rankings/search-ranking-data.php index c0f048f91e7..fe2da91ea6d 100644 --- a/src/dashboard/domain/search-rankings/search-data.php +++ b/src/dashboard/domain/search-rankings/search-ranking-data.php @@ -5,9 +5,9 @@ use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Interface; /** - * Domain object that represents a single Search Data record. + * Domain object that represents a single Search Ranking Data record. */ -class Search_Data implements Data_Interface { +class Search_Ranking_Data implements Data_Interface { /** * The amount of clicks a `subject` gets. diff --git a/src/dashboard/domain/search-rankings/top-page-data.php b/src/dashboard/domain/search-rankings/top-page-data.php index b28f2244f3d..90134146d70 100644 --- a/src/dashboard/domain/search-rankings/top-page-data.php +++ b/src/dashboard/domain/search-rankings/top-page-data.php @@ -11,11 +11,11 @@ class Top_Page_Data implements Data_Interface { /** - * The search data for the top page. + * The search ranking data for the top page. * - * @var Search_Data $search_data + * @var Search_Ranking_Data $search_ranking_data */ - private $search_data; + private $search_ranking_data; /** * The SEO score group the top page belongs to. @@ -34,18 +34,18 @@ class Top_Page_Data implements Data_Interface { /** * The constructor. * - * @param Search_Data $search_data The search data for the top page. - * @param SEO_Score_Groups_Interface $seo_score_group The SEO score group the top page belongs to. - * @param string $edit_link The edit link of the top page. + * @param Search_Ranking_Data $search_ranking_data The search ranking data for the top page. + * @param SEO_Score_Groups_Interface $seo_score_group The SEO score group the top page belongs to. + * @param string $edit_link The edit link of the top page. */ public function __construct( - Search_Data $search_data, + Search_Ranking_Data $search_ranking_data, SEO_Score_Groups_Interface $seo_score_group, ?string $edit_link = null ) { - $this->search_data = $search_data; - $this->seo_score_group = $seo_score_group; - $this->edit_link = $edit_link; + $this->search_ranking_data = $search_ranking_data; + $this->seo_score_group = $seo_score_group; + $this->edit_link = $edit_link; } /** @@ -54,7 +54,7 @@ public function __construct( * @return array */ public function to_array(): array { - $top_page_data = $this->search_data->to_array(); + $top_page_data = $this->search_ranking_data->to_array(); $top_page_data['seoScore'] = $this->seo_score_group->get_name(); $top_page_data['links'] = []; diff --git a/src/dashboard/domain/traffic/comparison-traffic-data.php b/src/dashboard/domain/traffic/comparison-traffic-data.php new file mode 100644 index 00000000000..9ccedf87048 --- /dev/null +++ b/src/dashboard/domain/traffic/comparison-traffic-data.php @@ -0,0 +1,70 @@ +current_traffic_data = $current_traffic_data; + $this->previous_traffic_data = $previous_traffic_data; + } + + /** + * Sets the current traffic data. + * + * @param Traffic_Data $current_traffic_data The current traffic data. + * + * @return void + */ + public function set_current_traffic_data( Traffic_Data $current_traffic_data ): void { + $this->current_traffic_data = $current_traffic_data; + } + + /** + * Sets the previous traffic data. + * + * @param Traffic_Data $previous_traffic_data The previous traffic data. + * + * @return void + */ + public function set_previous_traffic_data( Traffic_Data $previous_traffic_data ): void { + $this->previous_traffic_data = $previous_traffic_data; + } + + /** + * The array representation of this domain object. + * + * @return array + */ + public function to_array(): array { + return [ + 'current' => $this->current_traffic_data->to_array(), + 'previous' => $this->previous_traffic_data->to_array(), + ]; + } +} diff --git a/src/dashboard/domain/traffic/daily-traffic-data.php b/src/dashboard/domain/traffic/daily-traffic-data.php new file mode 100644 index 00000000000..0ca608dbebd --- /dev/null +++ b/src/dashboard/domain/traffic/daily-traffic-data.php @@ -0,0 +1,48 @@ +date = $date; + $this->traffic_data = $traffic_data; + } + + /** + * The array representation of this domain object. + * + * @return array + */ + public function to_array(): array { + $result = []; + $result['date'] = $this->date; + + return \array_merge( $result, $this->traffic_data->to_array() ); + } +} diff --git a/src/dashboard/domain/traffic/traffic-data.php b/src/dashboard/domain/traffic/traffic-data.php new file mode 100644 index 00000000000..0a8655a9031 --- /dev/null +++ b/src/dashboard/domain/traffic/traffic-data.php @@ -0,0 +1,66 @@ + + */ + public function to_array(): array { + $result = []; + + if ( $this->sessions !== null ) { + $result['sessions'] = $this->sessions; + } + + if ( $this->total_users !== null ) { + $result['total_users'] = $this->total_users; + } + + return $result; + } + + /** + * Sets the sessions. + * + * @param int $sessions The sessions. + * + * @return void + */ + public function set_sessions( int $sessions ): void { + $this->sessions = $sessions; + } + + /** + * Sets the total users. + * + * @param int $total_users The total users. + * + * @return void + */ + public function set_total_users( int $total_users ): void { + $this->total_users = $total_users; + } +} diff --git a/src/dashboard/infrastructure/analytics-4/analytics-4-parameters.php b/src/dashboard/infrastructure/analytics-4/analytics-4-parameters.php new file mode 100644 index 00000000000..80a436f7854 --- /dev/null +++ b/src/dashboard/infrastructure/analytics-4/analytics-4-parameters.php @@ -0,0 +1,138 @@ +> $dimensions + */ + private $dimensions = []; + + /** + * The dimensions filters. + * + * @var array> $dimension_filters + */ + private $dimension_filters = []; + + /** + * The metrics. + * + * @var array> $metrics + */ + private $metrics = []; + + /** + * The order by. + * + * @var array>> $order_by + */ + private $order_by = []; + + /** + * Sets the dimensions. + * + * @link https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/Dimension + * + * @param array $dimensions The dimensions. + * + * @return void + */ + public function set_dimensions( array $dimensions ): void { + foreach ( $dimensions as $dimension ) { + $this->dimensions[] = [ 'name' => $dimension ]; + } + } + + /** + * Getter for the dimensions. + * + * @return array> + */ + public function get_dimensions(): array { + return $this->dimensions; + } + + /** + * Sets the dimension filters. + * + * @param array> $dimension_filters The dimension filters. + * + * @return void + */ + public function set_dimension_filters( array $dimension_filters ): void { + $this->dimension_filters = $dimension_filters; + } + + /** + * Getter for the dimension filters. + * + * @return array> + */ + public function get_dimension_filters(): array { + return $this->dimension_filters; + } + + /** + * Sets the metrics. + * + * @link https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/Metric + * + * @param array $metrics The metrics. + * + * @return void + */ + public function set_metrics( array $metrics ): void { + foreach ( $metrics as $metric ) { + $this->metrics[] = [ 'name' => $metric ]; + } + } + + /** + * Getter for the metrics. + * + * @return array> + */ + public function get_metrics(): array { + return $this->metrics; + } + + /** + * Sets the order by. + * + * @link https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/OrderBy + * + * @param string $key The key to order by. + * @param string $name The name to order by. + * + * @return void + */ + public function set_order_by( string $key, string $name ): void { + $order_by = [ + [ + $key => [ + $key . 'Name' => $name, + ], + ], + ]; + + $this->order_by = $order_by; + } + + /** + * Getter for the order by. + * + * @return array>> + */ + public function get_order_by(): array { + return $this->order_by; + } +} diff --git a/src/dashboard/infrastructure/analytics-4/site-kit-analytics-4-adapter.php b/src/dashboard/infrastructure/analytics-4/site-kit-analytics-4-adapter.php new file mode 100644 index 00000000000..4cd0556e4bc --- /dev/null +++ b/src/dashboard/infrastructure/analytics-4/site-kit-analytics-4-adapter.php @@ -0,0 +1,232 @@ +context() ); + self::$analytics_4_module = $modules->get_module( Analytics_4::MODULE_SLUG ); + } + } + + /** + * The wrapper method to do a Site Kit API request for Analytics 4. + * + * @param Analytics_4_Parameters $parameters The parameters. + * + * @return Data_Container The Site Kit API response. + * + * @throws Failed_Request_Exception When the request responds with an error from Site Kit. + */ + public function get_data( Analytics_4_Parameters $parameters ): Data_Container { + $api_parameters = $this->build_parameters( $parameters ); + $response = self::$analytics_4_module->get_data( 'report', $api_parameters ); + + if ( \is_wp_error( $response ) ) { + $error_data = $response->get_error_data(); + $error_status_code = ( $error_data['status'] ?? 500 ); + throw new Failed_Request_Exception( \wp_kses_post( $response->get_error_message() ), (int) $error_status_code ); + } + + return $this->parse_response( $response ); + } + + /** + * Builds the parameters to be used in the Site Kit API request. + * + * @param Analytics_4_Parameters $parameters The parameters. + * + * @return array> The Site Kit API parameters. + */ + protected function build_parameters( $parameters ): array { + $api_parameters = [ + 'slug' => 'analytics-4', + 'datapoint' => 'report', + 'startDate' => $parameters->get_start_date(), + 'endDate' => $parameters->get_end_date(), + ]; + + if ( ! empty( $parameters->get_dimension_filters() ) ) { + $api_parameters['dimensionFilters'] = $parameters->get_dimension_filters(); + } + + if ( ! empty( $parameters->get_dimensions() ) ) { + $api_parameters['dimensions'] = $parameters->get_dimensions(); + } + + if ( ! empty( $parameters->get_metrics() ) ) { + $api_parameters['metrics'] = $parameters->get_metrics(); + } + + if ( ! empty( $parameters->get_order_by() ) ) { + $api_parameters['orderby'] = $parameters->get_order_by(); + } + + if ( ! empty( $parameters->get_compare_start_date() && ! empty( $parameters->get_compare_end_date() ) ) ) { + $api_parameters['compareStartDate'] = $parameters->get_compare_start_date(); + $api_parameters['compareEndDate'] = $parameters->get_compare_end_date(); + } + + return $api_parameters; + } + + // phpcs:disable SlevomatCodingStandard.TypeHints.DisallowMixedTypeHint.DisallowedMixedTypeHint -- Reason: Parameters comes from Site Kit, no control over it. + // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Reason: Object properties come from Site Kit, no control over it. + + /** + * Parses a response for a Site Kit API request for Analytics 4. + * + * @param mixed $response The response to parse. + * + * @return Data_Container The parsed response. + * + * @throws Invalid_Request_Exception When the request is invalid due to unexpected parameters. + */ + protected function parse_response( $response ): Data_Container { + if ( $this->is_daily_request( $response ) ) { + return $this->parse_daily_response( $response ); + } + + if ( $this->is_comparison_request( $response ) ) { + return $this->parse_comparison_response( $response ); + } + + throw new Invalid_Request_Exception( 'Unexpected parameters for the request' ); + } + + /** + * Parses a response for a Site Kit API request that requests daily data for Analytics 4. + * + * @param mixed $response The response to parse. + * + * @return Data_Container The parsed response. + */ + protected function parse_daily_response( $response ): Data_Container { + $data_container = new Data_Container(); + + foreach ( $response->rows as $daily_traffic ) { + $traffic_data = new Traffic_Data(); + + foreach ( $response->metricHeaders as $key => $metric ) { + + // @TODO: Maybe use class methods like MetricValue::getValue() instead of ->value. + // As per https://developers.google.com/analytics/devguides/reporting/data/v1/basics#read_the_response, + // the order of the columns is consistent in the request, header, and rows. + // So we can use the key of the header to get the correct metric value from the row. + $metric_value = $daily_traffic->metricValues[ $key ]->value; + + if ( $metric->name === 'sessions' ) { + $traffic_data->set_sessions( (int) $metric_value ); + } + elseif ( $metric->name === 'totalUsers' ) { + $traffic_data->set_total_users( (int) $metric_value ); + } + } + + // Since we're here, we know that the first dimension is date, so we know that dimensionValues[0]->value is a date. + $data_container->add_data( new Daily_Traffic_Data( $daily_traffic->dimensionValues[0]->value, $traffic_data ) ); + } + + return $data_container; + } + + /** + * Parses a response for a Site Kit API request for Analytics 4 that compares data ranges. + * + * @param mixed $response The response to parse. + * + * @return Data_Container The parsed response. + */ + protected function parse_comparison_response( $response ): Data_Container { + $data_container = new Data_Container(); + $comparison_traffic_data = new Comparison_Traffic_Data(); + + // First row is the current date range's data, second row is the previous date range's data. + foreach ( $response->rows as $date_range_key => $date_range_row ) { + $traffic_data = new Traffic_Data(); + + // Loop through all the metrics of the date range. + foreach ( $response->metricHeaders as $key => $metric ) { + + // @TODO: Maybe use class methods like MetricValue::getValue() instead of ->value. + // As per https://developers.google.com/analytics/devguides/reporting/data/v1/basics#read_the_response, + // the order of the columns is consistent in the request, header, and rows. + // So we can use the key of the header to get the correct metric value from the row. + $metric_value = $date_range_row->metricValues[ $key ]->value; + + if ( $metric->name === 'sessions' ) { + $traffic_data->set_sessions( (int) $metric_value ); + } + elseif ( $metric->name === 'totalUsers' ) { + $traffic_data->set_total_users( (int) $metric_value ); + } + } + + if ( $date_range_key === 0 ) { + $comparison_traffic_data->set_current_traffic_data( $traffic_data ); + } + elseif ( $date_range_key === 1 ) { + $comparison_traffic_data->set_previous_traffic_data( $traffic_data ); + } + } + + $data_container->add_data( $comparison_traffic_data ); + + return $data_container; + } + + /** + * Checks the response of the request to detect if it's a comparison request. + * + * @param mixed $response The response. + * + * @return bool Whether it's a comparison request. + */ + protected function is_comparison_request( $response ): bool { + return \count( $response->dimensionHeaders ) === 1 && $response->dimensionHeaders[0]->name === 'dateRange'; + } + + /** + * Checks the response of the request to detect if it's a daily request. + * + * @param mixed $response The response. + * + * @return bool Whether it's a daily request. + */ + protected function is_daily_request( $response ): bool { + return \count( $response->dimensionHeaders ) === 1 && $response->dimensionHeaders[0]->name === 'date'; + } + + // phpcs:enable SlevomatCodingStandard.TypeHints.DisallowMixedTypeHint.DisallowedMixedTypeHint + // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase +} diff --git a/src/dashboard/infrastructure/search-console/site-kit-search-console-adapter.php b/src/dashboard/infrastructure/search-console/site-kit-search-console-adapter.php index 6f05fdf5e7b..df972e86557 100644 --- a/src/dashboard/infrastructure/search-console/site-kit-search-console-adapter.php +++ b/src/dashboard/infrastructure/search-console/site-kit-search-console-adapter.php @@ -9,10 +9,10 @@ use Google\Site_Kit\Plugin; use Yoast\WP\SEO\Dashboard\Domain\Data_Provider\Data_Container; use Yoast\WP\SEO\Dashboard\Domain\Search_Console\Failed_Request_Exception; -use Yoast\WP\SEO\Dashboard\Domain\Search_Rankings\Search_Data; +use Yoast\WP\SEO\Dashboard\Domain\Search_Rankings\Search_Ranking_Data; /** - * The site API adapter to make calls via the Site_Kit plugin. + * The site API adapter to make calls to the Search Console API, via the Site_Kit plugin. */ class Site_Kit_Search_Console_Adapter { @@ -37,13 +37,13 @@ public function __construct() { } /** - * The wrapper method to add our parameters to a Site Kit API request. + * The wrapper method to do a Site Kit API request for Search Console. * * @param Search_Console_Parameters $parameters The parameters. * * @return Data_Container The Site Kit API response. * - * @throws Failed_Request_Exception When the query of getting score results fails. + * @throws Failed_Request_Exception When the request responds with an error from Site Kit. */ public function get_data( Search_Console_Parameters $parameters ): Data_Container { $api_parameters = [ @@ -55,16 +55,16 @@ public function get_data( Search_Console_Parameters $parameters ): Data_Containe 'dimensions' => $parameters->get_dimensions(), ]; - $data_rows = self::$search_console_module->get_data( 'searchanalytics', $api_parameters ); + $response = self::$search_console_module->get_data( 'searchanalytics', $api_parameters ); - if ( \is_wp_error( $data_rows ) ) { - $error_data = $data_rows->get_error_data(); + if ( \is_wp_error( $response ) ) { + $error_data = $response->get_error_data(); $error_status_code = ( $error_data['status'] ?? 500 ); - throw new Failed_Request_Exception( \wp_kses_post( $data_rows->get_error_message() ), (int) $error_status_code ); + throw new Failed_Request_Exception( \wp_kses_post( $response->get_error_message() ), (int) $error_status_code ); } - $search_data_container = new Data_Container(); - foreach ( $data_rows as $ranking ) { + $search_ranking_data_container = new Data_Container(); + foreach ( $response as $ranking ) { /** * Filter: 'wpseo_transform_dashboard_subject_for_testing' - Allows overriding subjects like URLs for the dashboard, to facilitate testing in local environments. * @@ -74,9 +74,9 @@ public function get_data( Search_Console_Parameters $parameters ): Data_Containe */ $subject = \apply_filters( 'wpseo_transform_dashboard_subject_for_testing', $ranking->keys[0] ); - $search_data_container->add_data( new Search_Data( $ranking->clicks, $ranking->ctr, $ranking->impressions, $ranking->position, $subject ) ); + $search_ranking_data_container->add_data( new Search_Ranking_Data( $ranking->clicks, $ranking->ctr, $ranking->impressions, $ranking->position, $subject ) ); } - return $search_data_container; + return $search_ranking_data_container; } } diff --git a/src/dashboard/user-interface/time-based-seo-metrics/time-based-seo-metrics-route.php b/src/dashboard/user-interface/time-based-seo-metrics/time-based-seo-metrics-route.php index bcace128a0b..4f1455117bd 100644 --- a/src/dashboard/user-interface/time-based-seo-metrics/time-based-seo-metrics-route.php +++ b/src/dashboard/user-interface/time-based-seo-metrics/time-based-seo-metrics-route.php @@ -11,7 +11,9 @@ use Yoast\WP\SEO\Conditionals\Google_Site_Kit_Feature_Conditional; use Yoast\WP\SEO\Dashboard\Application\Search_Rankings\Top_Page_Repository; use Yoast\WP\SEO\Dashboard\Application\Search_Rankings\Top_Query_Repository; +use Yoast\WP\SEO\Dashboard\Application\Traffic\Organic_Sessions_Repository; use Yoast\WP\SEO\Dashboard\Domain\Time_Based_SEO_Metrics\Repository_Not_Found_Exception; +use Yoast\WP\SEO\Dashboard\Infrastructure\Analytics_4\Analytics_4_Parameters; use Yoast\WP\SEO\Dashboard\Infrastructure\Search_Console\Search_Console_Parameters; use Yoast\WP\SEO\Main; use Yoast\WP\SEO\Routes\Route_Interface; @@ -22,7 +24,7 @@ final class Time_Based_SEO_Metrics_Route implements Route_Interface { /** - * The namespace of the rout. + * The namespace of the route. * * @var string */ @@ -49,6 +51,13 @@ final class Time_Based_SEO_Metrics_Route implements Route_Interface { */ private $top_query_repository; + /** + * The data provider for organic session traffic. + * + * @var Organic_Sessions_Repository $organic_sessions_repository + */ + private $organic_sessions_repository; + /** * Returns the needed conditionals. * @@ -61,15 +70,18 @@ public static function get_conditionals(): array { /** * The constructor. * - * @param Top_Page_Repository $top_page_repository The data provider for page based search rankings. - * @param Top_Query_Repository $top_query_repository The data provider for query based search rankings. + * @param Top_Page_Repository $top_page_repository The data provider for page based search rankings. + * @param Top_Query_Repository $top_query_repository The data provider for query based search rankings. + * @param Organic_Sessions_Repository $organic_sessions_repository The data provider for organic session traffic. */ public function __construct( Top_Page_Repository $top_page_repository, - Top_Query_Repository $top_query_repository + Top_Query_Repository $top_query_repository, + Organic_Sessions_Repository $organic_sessions_repository ) { - $this->top_page_repository = $top_page_repository; - $this->top_query_repository = $top_query_repository; + $this->top_page_repository = $top_page_repository; + $this->top_query_repository = $top_query_repository; + $this->organic_sessions_repository = $organic_sessions_repository; } /** @@ -88,7 +100,6 @@ public function register_routes() { 'permission_callback' => [ $this, 'permission_manage_options' ], 'args' => [ 'limit' => [ - 'required' => true, 'type' => 'int', 'sanitize_callback' => static function ( $param ) { return \intval( $param ); @@ -123,24 +134,63 @@ public function register_routes() { */ public function get_time_based_seo_metrics( WP_REST_Request $request ): WP_REST_Response { try { - $request_parameters = new Search_Console_Parameters(); - $request_parameters->set_limit( $request->get_param( 'limit' ) ); $date = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); $date->modify( '-28 days' ); + $start_date = $date->format( 'Y-m-d' ); - $request_parameters->set_start_date( $date->format( 'Y-m-d' ) ); - $request_parameters->set_end_date( ( new DateTime( 'now', new DateTimeZone( 'UTC' ) ) )->format( 'Y-m-d' ) ); + $date = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); + $date->modify( '-1 days' ); + $end_date = $date->format( 'Y-m-d' ); $widget_name = $request->get_param( 'options' )['widget']; switch ( $widget_name ) { case 'query': + $request_parameters = new Search_Console_Parameters(); + $request_parameters->set_limit( $request->get_param( 'limit' ) ); $request_parameters->set_dimensions( [ 'query' ] ); + $request_parameters->set_start_date( $start_date ); + $request_parameters->set_end_date( $end_date ); + $time_based_seo_metrics_container = $this->top_query_repository->get_data( $request_parameters ); break; case 'page': + $request_parameters = new Search_Console_Parameters(); + $request_parameters->set_limit( $request->get_param( 'limit' ) ); $request_parameters->set_dimensions( [ 'page' ] ); + $request_parameters->set_start_date( $start_date ); + $request_parameters->set_end_date( $end_date ); + $time_based_seo_metrics_container = $this->top_page_repository->get_data( $request_parameters ); break; + case 'οrganicSessionsDaily': + $request_parameters = new Analytics_4_Parameters(); + $request_parameters->set_dimensions( [ 'date' ] ); + $request_parameters->set_metrics( [ 'sessions' ] ); + $request_parameters->set_start_date( $start_date ); + $request_parameters->set_end_date( $end_date ); + $request_parameters->set_dimension_filters( [ 'sessionDefaultChannelGrouping' => [ 'Organic Search' ] ] ); + $request_parameters->set_order_by( 'dimension', 'date' ); + + $time_based_seo_metrics_container = $this->organic_sessions_repository->get_data( $request_parameters ); + break; + case 'οrganicSessionsChange': + $request_parameters = new Analytics_4_Parameters(); + $request_parameters->set_metrics( [ 'sessions' ] ); + $request_parameters->set_start_date( $start_date ); + $request_parameters->set_end_date( $end_date ); + $request_parameters->set_dimension_filters( [ 'sessionDefaultChannelGrouping' => [ 'Organic Search' ] ] ); + + $date = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); + $date->modify( '-29 days' ); + $compare_end_date = $date->format( 'Y-m-d' ); + + $date->modify( '-27 days' ); + $compare_start_date = $date->format( 'Y-m-d' ); + $request_parameters->set_compare_start_date( $compare_start_date ); + $request_parameters->set_compare_end_date( $compare_end_date ); + + $time_based_seo_metrics_container = $this->organic_sessions_repository->get_data( $request_parameters ); + break; default: throw new Repository_Not_Found_Exception(); }