Google Search Console - v1.0.0
Fetchers
Higher-level helpers that build the exact SearchAnalyticsRequest the shipped UIs need and return typed DTOs. Every fetcher is a thin wrapper — no state of its own, no dependencies beyond a SearchAnalyticsClient instance.
Three fetchers ship:
| Fetcher | Runs | Returns |
|---|---|---|
PerformanceOverviewFetcher |
Two API calls (totals + daily trend) | PerformanceOverviewData |
TopQueriesFetcher |
One API call (dimension query) |
TopQueriesData |
TopPagesFetcher |
One API call (dimension page) |
TopPagesData |
PerformanceOverviewFetcher
FQCN: ArtisanPackUI\GoogleSearchConsole\Reporting\PerformanceOverviewFetcher
fetch( GoogleConnection $connection, DateRange $range, ?string $siteUrl = null ): PerformanceOverviewData
Two searchAnalytics.query calls:
- Totals: no dimensions, aggregated across the range.
- Trend: dimension
date, one row per day, sorted ascending after the response is parsed.
The DTO exposes:
totals: array{clicks: float, impressions: float, ctr: float, position: float}trend: list<array{date: string, clicks: float, impressions: float, ctr: float, position: float}>hasData: bool—falsewhen both calls returned zero rows (fresh property, last 2–3 finalising days, etc.).toArray(): array— serializes to the shape the/performanceendpoint returns.
Example:
use ArtisanPackUI\GoogleSearchConsole\Reporting\DateRange;
use ArtisanPackUI\GoogleSearchConsole\Reporting\PerformanceOverviewFetcher;
$fetcher = new PerformanceOverviewFetcher( googleSearchConsole()->client() );
$data = $fetcher->fetch( $connection, DateRange::lastDays( 28 ) );
if ( ! $data->hasData ) {
return view( 'dashboard.empty' );
}
echo number_format( $data->totals[ 'clicks' ] ) . ' clicks over ' . count( $data->trend ) . ' days';
TopQueriesFetcher
FQCN: ArtisanPackUI\GoogleSearchConsole\Reporting\TopQueriesFetcher
Constant: DEFAULT_LIMIT = 50.
fetch( GoogleConnection $connection, DateRange $range, ?string $siteUrl = null, ?int $limit = null ): TopQueriesData
One searchAnalytics.query call with dimension query, row limit $limit ?? self::DEFAULT_LIMIT (clamped by the request DTO to 1..SearchAnalyticsRequest::MAX_ROW_LIMIT, which is 25000).
The DTO exposes:
rows: list<array{query: string, clicks: float, impressions: float, ctr: float, position: float}>toArray(): array— matches the/top-queriesendpoint shape.
Rows come back sorted by clicks descending — Google's default and unchangeable (the API doesn't accept an orderBys).
Example:
use ArtisanPackUI\GoogleSearchConsole\Reporting\DateRange;
use ArtisanPackUI\GoogleSearchConsole\Reporting\TopQueriesFetcher;
$fetcher = new TopQueriesFetcher( googleSearchConsole()->client() );
$data = $fetcher->fetch( $connection, DateRange::lastDays( 90 ), null, 200 );
foreach ( $data->rows as $row ) {
echo "{$row['query']}: {$row['clicks']} clicks, {$row['impressions']} impressions\n";
}
TopPagesFetcher
FQCN: ArtisanPackUI\GoogleSearchConsole\Reporting\TopPagesFetcher
Constant: DEFAULT_LIMIT = 50.
fetch( GoogleConnection $connection, DateRange $range, ?string $siteUrl = null, ?int $limit = null ): TopPagesData
Same shape as TopQueriesFetcher, but with dimension page. Rows carry a page key (the full URL) instead of a query key.
Example:
use ArtisanPackUI\GoogleSearchConsole\Reporting\DateRange;
use ArtisanPackUI\GoogleSearchConsole\Reporting\TopPagesFetcher;
$fetcher = new TopPagesFetcher( googleSearchConsole()->client() );
$data = $fetcher->fetch( $connection, DateRange::lastDays( 28 ) );
foreach ( $data->rows as $row ) {
echo "{$row['page']}: {$row['clicks']} clicks\n";
}
When to write your own fetcher
The three ship because they back the three shipped UIs. If your report is similar but different — e.g., "top queries filtered by country US" — you have three options:
- Skip the fetcher. Call
SearchAnalyticsClient::query()directly with your ownSearchAnalyticsRequest. Simplest for one-off reports. - Extend one of the shipped fetchers. They're plain classes; subclass and override the
fetch()body if 80% overlaps. - Write your own. Copy
TopQueriesFetcheras a template — it's ~30 lines.
Example custom fetcher:
namespace App\Reporting;
use ArtisanPackUI\Google\Models\GoogleConnection;
use ArtisanPackUI\GoogleSearchConsole\Reporting\DateRange;
use ArtisanPackUI\GoogleSearchConsole\Reporting\SearchAnalyticsClient;
use ArtisanPackUI\GoogleSearchConsole\Reporting\SearchAnalyticsRequest;
class TopQueriesByCountryFetcher
{
public function __construct( protected SearchAnalyticsClient $client ) {}
public function fetch( GoogleConnection $connection, DateRange $range, string $country ): array
{
$response = $this->client->query(
new SearchAnalyticsRequest(
dateRange: $range,
dimensions: [ 'query' ],
dimensionFilterGroups: [
[
'filters' => [
[ 'dimension' => 'country', 'operator' => 'equals', 'expression' => $country ],
],
],
],
rowLimit: 100,
),
$connection,
);
return $response->rows();
}
}
Bind and inject as you would any Laravel service.
See also
- API Reference/Fetchers — full class signatures.
- Reporting/Date Range — the
DateRangevalue object. - Reporting/Search Analytics Client — the underlying client.