Completed
Push — master ( 144f3b...04a31c )
by Felix
01:28
created

SearchConsoleClient::getGoogleClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace SchulzeFelix\SearchConsole;
4
5
use Google_Client;
6
use GuzzleHttp\Client;
7
use Google_Service_Webmasters;
8
use Illuminate\Support\Collection;
9
10
class SearchConsoleClient
11
{
12
    const CHUNK_SIZE = 5000;
13
14
    /**
15
     * @var Google_Client
16
     */
17
    private $googleClient;
18
19
    private $queryOptParams = [];
20
21
    /**
22
     * SearchConsoleClient constructor.
23
     * @param Google_Client $googleClient
24
     * @internal param Google_Service_Webmasters $service
25
     */
26
    public function __construct(Google_Client $googleClient)
27
    {
28
        $this->googleClient = $googleClient;
29
    }
30
31
    /**
32
     * @param string $siteUrl
33
     * @param int $rows
34
     * @param \Google_Service_Webmasters_SearchAnalyticsQueryRequest $request
35
     * @return Collection
36
     */
37
    public function performQuery($siteUrl, $rows, $request): Collection
38
    {
39
        $searchanalyticsResource = $this->getWebmastersService()->searchanalytics;
40
41
        $maxQueries = 2000;
42
        $currentRequest = 1;
43
        $dataRows = new Collection();
44
45
        while ($currentRequest < $maxQueries) {
46
            $startRow = ($currentRequest - 1) * self::CHUNK_SIZE;
47
48
            $request->setRowLimit(self::CHUNK_SIZE);
49
            $request->setStartRow($startRow);
50
51
            $backoff = new ExponentialBackoff(10);
52
            $response = $backoff->execute(function () use ($searchanalyticsResource, $siteUrl, $request) {
53
                return $searchanalyticsResource->query($siteUrl, $request, $this->queryOptParams);
54
            });
55
56
            // Stop if no more rows returned
57
            if (count($response->getRows()) == 0) {
58
                break;
59
            }
60
61
            foreach ($response->getRows() as $row) {
62
                /*
63
                 * Use a unique hash as key to prevent duplicates caused by the query dimension problem with the google api
64
                 * Google give less than 5000 rows back when two or more dimension with the query dimension are choosen, repeated calls give back more rows
65
                 * https://productforums.google.com/forum/?hl=en#!topic/webmasters/wF_Rm9CGr4U
66
                 */
67
68
                $uniqueHash = md5(str_random());
69
                $item = [];
70
71
                if (count($row->getKeys())) {
72
                    $item = array_combine($request->getDimensions(), $row->getKeys());
73
                    $uniqueHash = $this->getUniqueItemHash($row, $request);
74
                }
75
76
                $item['clicks'] = $row->getClicks();
77
                $item['impressions'] = $row->getImpressions();
78
                $item['ctr'] = $row->getCtr();
79
                $item['position'] = $row->getPosition();
80
                $item['searchType'] = $request->getSearchType();
81
82
                $dataRows->put($uniqueHash, $item);
83
            }
84
85
            //Stop if the requested row count are reached
86
            if ($dataRows->count() >= $rows) {
87
                break;
88
            }
89
90
            $currentRequest++;
91
        }
92
93
        return $dataRows->take($rows);
94
    }
95
96
    /**
97
     * @param string $quotaUser
98
     */
99
    public function setQuotaUser(string $quotaUser)
100
    {
101
        $quotaUser = md5($quotaUser);
102
103
        $this->queryOptParams['quotaUser'] = $quotaUser;
104
105
        $guzzleConfig = $this->googleClient->getHttpClient()->getConfig();
106
107
        array_set($guzzleConfig, 'base_uri', Google_Client::API_BASE_PATH.'?quotaUser='.$quotaUser);
108
109
        $guzzleClient = new Client($guzzleConfig);
110
111
        $this->googleClient->setHttpClient($guzzleClient);
112
    }
113
114
    /**
115
     * @param string $accessToken
116
     */
117
    public function setAccessToken(string $accessToken)
118
    {
119
        $this->googleClient->setAccessToken($accessToken);
120
    }
121
122
    public function getGoogleClient(): Google_Client
123
    {
124
        return $this->googleClient;
125
    }
126
127
    public function getWebmastersService(): Google_Service_Webmasters
128
    {
129
        return new Google_Service_Webmasters($this->googleClient);
130
    }
131
132
    private function getUniqueItemHash($row, $request)
133
    {
134
        $keys = implode('', $row->getKeys());
135
136
        $filters = [];
137
        foreach ($request->getDimensionFilterGroups() as $dimensionFilterGroup) {
138
            foreach ($dimensionFilterGroup->filters as $filter) {
139
                $filters[] = $filter->dimension.$filter->expression.$filter->operator;
140
            }
141
        }
142
        $filters = implode('', $filters);
143
144
        return md5($keys.$filters.$request->getSearchType().$request->endDate.$request->startDate);
145
    }
146
}
147