Completed
Push — master ( 4ffc8b...8e0049 )
by Gabriel Felipe
02:04 queued 10s
created

InterestByRegionSearch::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 2
crap 3
1
<?php declare(strict_types=1);
2
3
namespace GSoares\GoogleTrends\Search;
4
5
use GSoares\GoogleTrends\Error\GoogleTrendsException;
6
use GSoares\GoogleTrends\Result\InterestByRegionCollection;
7
use GSoares\GoogleTrends\Result\InterestByRegionResult;
8
9
/**
10
 * @author Gabriel Felipe Soares <[email protected]>
11
 */
12
class InterestByRegionSearch
13
{
14
    private const SEARCH_URL = 'https://trends.google.com/trends/api/widgetdata/comparedgeo';
15
16
    /**
17
     * @var ExploreSearch
18
     */
19
    protected $exploreSearch;
20
21
    /**
22
     * @var SearchRequest
23
     */
24
    protected $searchRequest;
25
26 3
    public function __construct(ExploreSearch $exploreSearch = null, SearchRequest $searchRequest = null)
27
    {
28 3
        $this->searchRequest = $searchRequest ?: new SearchRequest();
29 3
        $this->exploreSearch = $exploreSearch ?: new ExploreSearch($this->searchRequest);
30 3
    }
31
32
    /**
33
     * @param SearchFilter $searchFilter
34
     *
35
     * @return InterestByRegionCollection
36
     *
37
     * @throws GoogleTrendsException
38
     */
39 3
    public function search(SearchFilter $searchFilter): InterestByRegionCollection
40
    {
41 3
        $token = $this->exploreSearch
42 3
            ->search($searchFilter)
43 3
            ->getInterestByRegionResult()
44 3
            ->getToken();
45
46 3
        $searchUrl = $this->buildQuery($searchFilter->withToken($token));
47
48 3
        $responseDecoded = $this->searchRequest->search($searchUrl);
49
50 3
        if (!isset($responseDecoded['default']['geoMapData'])) {
51 1
            throw new GoogleTrendsException(
52 1
                sprintf(
53 1
                    'Invalid google response body "%s"...',
54 1
                    substr(var_export($responseDecoded, true), 100)
55
                )
56
            );
57
        }
58
59 2
        $results = [];
60
61 2
        foreach ($responseDecoded['default']['geoMapData'] ?? [] as $row) {
62 2
            if (!isset($row['geoCode'], $row['geoName'], $row['value'], $row['maxValueIndex'])) {
63 1
                throw new GoogleTrendsException(
64 1
                    sprintf(
65 1
                        'Google compared geo list does not contain all keys. Only has: %s',
66 1
                        implode(', ', array_keys($row))
67
                    )
68
                );
69
            }
70
71 1
            $results[] = new InterestByRegionResult(
72 1
                $row['geoCode'],
73 1
                $row['geoName'],
74 1
                (int)($row['value'][0] ?? 0),
75 1
                (int)$row['maxValueIndex'],
76 1
                (bool)($row['hasData'] ?? false)
77
            );
78
        }
79
80 1
        return new InterestByRegionCollection($searchUrl, ...$results);
81
    }
82
83 3
    private function buildQuery(SearchFilter $searchFilter): string
84
    {
85
        $request = [
86
            'geo' => [
87 3
                'country' => $searchFilter->getLocation(),
88
            ],
89
            'comparisonItem' => [
90
                [
91 3
                    'time' => $searchFilter->getTime(),
92
                    'complexKeywordsRestriction' => [
93
                        'keyword' => [
94
                            [
95 3
                                'type' => 'BROAD',
96 3
                                'value' => $searchFilter->getSearchTerm(),
97
                            ],
98
                        ],
99
                    ]
100
                ],
101
            ],
102 3
            'resolution' => 'REGION',
103 3
            'locale' => $searchFilter->getLanguage(),
104
            'requestOptions' => [
105 3
                'property' => '',
106 3
                'backend' => 'IZG',
107 3
                'category' => $searchFilter->getCategory(),
108
            ]
109
        ];
110
111
        $query = [
112 3
            'hl' => $searchFilter->getLanguage(),
113 3
            'tz' => '-60',
114 3
            'req' => json_encode($request),
115 3
            'token' => $searchFilter->getToken()
116
        ];
117
118 3
        $queryString = str_replace(
119
            [
120 3
                '%3A',
121
                '%2C',
122
                '%2B'
123
            ],
124
            [
125 3
                ':',
126
                ',',
127
                '+',
128
            ],
129 3
            http_build_query($query)
130
        );
131
132 3
        return self::SEARCH_URL . '?' . $queryString;
133
    }
134
}
135