Test Failed
Pull Request — master (#27)
by
unknown
02:33
created

InterestByRegionSearch::buildQuery()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3.0309

Importance

Changes 0
Metric Value
dl 0
loc 55
ccs 8
cts 22
cp 0.3636
rs 8.9818
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 3.0309

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
use GSoares\GoogleTrends\Result\ResultCollectionInterface;
9
use GSoares\GoogleTrends\Result\InterestByCityCollection;
10
use GSoares\GoogleTrends\Result\InterestByCityResult;
11
12
/**
13
 * @author Gabriel Felipe Soares <[email protected]>
14
 */
15
class InterestByRegionSearch implements SearchInterface
16
{
17
    private const SEARCH_URL = 'https://trends.google.com/trends/api/widgetdata/comparedgeo';
18
19
    /**
20
     * @var ExploreSearch
21
     */
22
    protected $exploreSearch;
23
24
    /**
25
     * @var SearchRequest
26
     */
27
    protected $searchRequest;
28
29 2
    public function __construct(ExploreSearch $exploreSearch = null, SearchRequest $searchRequest = null)
30
    {
31 2
        $this->searchRequest = $searchRequest ?: new SearchRequest();
32 2
        $this->exploreSearch = $exploreSearch ?: new ExploreSearch($this->searchRequest);
33 2
    }
34
35
    /**
36
     * @param SearchFilter $searchFilter
37
     *
38
     * @return InterestByRegionCollection
39
     *
40
     * @throws GoogleTrendsException
41
     */
42 2
    public function search(SearchFilter $searchFilter): ResultCollectionInterface
43
    {
44 2
        $token = $this->exploreSearch
45 2
            ->search($searchFilter)
46 2
            ->getInterestByRegionResult()
47 2
            ->getToken();
48
49 2
        $searchUrl = $this->buildQuery($searchFilter->withToken($token));
50
//        echo $searchUrl;
51
//        exit;
52
        $responseDecoded = $this->searchRequest->search($searchUrl);
53
54
        if (!isset($responseDecoded['default']['geoMapData'])) {
55
            throw new GoogleTrendsException(
56
                sprintf(
57
                    'Invalid google response body "%s"...',
58
                    substr(var_export($responseDecoded, true), 100)
59
                )
60
            );
61
        }
62
63
        $results = [];
64
//        echo "<pre>";
65
//        print_r($responseDecoded['default']['geoMapData']);
66
//        exit;
67
        foreach ($responseDecoded['default']['geoMapData'] ?? [] as $row) {
68
            if($searchFilter->getResolution() == 'CITY'){
0 ignored issues
show
Bug introduced by
The method getResolution() does not seem to exist on object<GSoares\GoogleTrends\Search\SearchFilter>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
69
                if (!isset($responseDecoded['default']['geoMapData'])) {
70
                    throw new GoogleTrendsException(
71
                        sprintf(
72
                            'Invalid google response body "%s"...',
73
                            substr(var_export($responseDecoded, true), 100)
74
                        )
75
                    );
76
                }
77
                
78
                if (!isset($row['geoName'], $row['value'], $row['maxValueIndex'])) {
79
                throw new GoogleTrendsException(
80
                    sprintf(
81
                        'Google compared geo list does not contain all keys. Only has: %s',
82
                        implode(', ', array_keys($row))
83
                    )
84
                );
85
            }
86
            
87
                $results[] = new InterestByCityResult(
88
                    $row['geoName'],
89
                    (int)($row['value'][0] ?? 0),
90
                    (int)$row['maxValueIndex'],
91
                    (bool)($row['hasData'] ?? false),
92
                    (string)($row['coordinates']['lat'] ?? false),
93
                    (string)($row['coordinates']['lng'] ?? false)
94
                );
95
            }else{
96
                if (!isset($row['geoCode'], $row['geoName'], $row['value'], $row['maxValueIndex'])) {
97
                    throw new GoogleTrendsException(
98
                        sprintf(
99
                            'Google compared geo list does not contain all keys. Only has: %s',
100
                            implode(', ', array_keys($row))
101
                        )
102
                    );
103
                }
104
                
105
                $results[] = new InterestByRegionResult(
106
                    $row['geoCode'],
107
                    $row['geoName'],
108
                    (int)($row['value'][0] ?? 0),
109
                    (int)$row['maxValueIndex'],
110
                    (bool)($row['hasData'] ?? false)
111
                );
112
            }
113
114
            
115
        }
116
        
117
        if($searchFilter->getResolution() == 'CITY'){
0 ignored issues
show
Bug introduced by
The method getResolution() does not seem to exist on object<GSoares\GoogleTrends\Search\SearchFilter>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
118
            return new InterestByCityCollection($searchUrl, ...$results);
119
        }else{
120
            return new InterestByRegionCollection($searchUrl, ...$results);
121
        }
122
    }
123
124 2
    private function buildQuery(SearchFilter $searchFilter): string
125
    {
126 2
        if($searchFilter->getLocation() != ''){
127 2
            $geo = ['country' => $searchFilter->getLocation()];
128
        }else{
129
            $geo = (object)[];
130
        }
131
        
132
        $request = [
133 2
            'geo' => $geo,
134
            'comparisonItem' => [
135
                [
136 2
                    'time' => $searchFilter->getTime(),
137
                    'complexKeywordsRestriction' => [
138
                        'keyword' => [
139
                            [
140 2
                                'type' => 'BROAD',
141 2
                                'value' => $searchFilter->getSearchTerm(),
142
                            ],
143
                        ],
144
                    ]
145
                ],
146
            ],
147 2
            'resolution' => $searchFilter->getResolution(),
0 ignored issues
show
Bug introduced by
The method getResolution() does not seem to exist on object<GSoares\GoogleTrends\Search\SearchFilter>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
148
            'locale' => $searchFilter->getLanguage(),
0 ignored issues
show
Deprecated Code introduced by
The method GSoares\GoogleTrends\Sea...chFilter::getLanguage() has been deprecated with message: Will be removed, cause other languages do not work as filter. We should utilize only location

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
149
            'requestOptions' => [
150
                'property' => $searchFilter->getSearchType(),
151
                'backend' => 'IZG',
152
                'category' => $searchFilter->getCategory(),
153
            ]
154
        ];
155
156
        $query = [
157
            'hl' => $searchFilter->getLanguage(),
0 ignored issues
show
Deprecated Code introduced by
The method GSoares\GoogleTrends\Sea...chFilter::getLanguage() has been deprecated with message: Will be removed, cause other languages do not work as filter. We should utilize only location

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
158
            'tz' => '-60',
159
            'req' => json_encode($request),
160
            'token' => $searchFilter->getToken()
161
        ];
162
163
        $queryString = str_replace(
164
            [
165
                '%3A',
166
                '%2C',
167
                '%2B'
168
            ],
169
            [
170
                ':',
171
                ',',
172
                '+',
173
            ],
174
            http_build_query($query)
175
        );
176
177
        return self::SEARCH_URL . '?' . $queryString;
178
    }
179
}
180