Completed
Push — master ( e7e845...1ac605 )
by Felix
01:51
created

AdWordsService::getSearchParameters()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 51
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 51
rs 6.9743
c 0
b 0
f 0
cc 7
eloc 33
nc 20
nop 5

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
2
3
namespace SchulzeFelix\AdWords;
4
5
use Google\AdsApi\AdWords\v201705\cm\ApiException;
6
use Google\AdsApi\AdWords\v201705\cm\Language;
7
use Google\AdsApi\AdWords\v201705\cm\Location;
8
use Google\AdsApi\AdWords\v201705\cm\NetworkSetting;
9
use Google\AdsApi\AdWords\v201705\cm\Paging;
10
use Google\AdsApi\AdWords\v201705\cm\RateExceededError;
11
use Google\AdsApi\AdWords\v201705\o\AttributeType;
12
use Google\AdsApi\AdWords\v201705\o\IdeaTextFilterSearchParameter;
13
use Google\AdsApi\AdWords\v201705\o\IdeaType;
14
use Google\AdsApi\AdWords\v201705\o\LanguageSearchParameter;
15
use Google\AdsApi\AdWords\v201705\o\LocationSearchParameter;
16
use Google\AdsApi\AdWords\v201705\o\NetworkSearchParameter;
17
use Google\AdsApi\AdWords\v201705\o\RelatedToQuerySearchParameter;
18
use Google\AdsApi\AdWords\v201705\o\TargetingIdeaSelector;
19
use Google\AdsApi\AdWords\v201705\o\TargetingIdeaService;
20
21
class AdWordsService
22
{
23
    const PAGE_LIMIT = 1000;
24
25
    const MAX_RETRIES = 10;
26
27
    /** @var TargetingIdeaService */
28
    protected $targetingIdeaService;
29
30
    public function __construct(TargetingIdeaService $targetingIdeaService)
31
    {
32
        $this->targetingIdeaService = $targetingIdeaService;
33
    }
34
35
    /**
36
     * Query the Google AdWords TargetingIdeaService with given parameters.
37
     *
38
     * @param array $keywords
39
     * @param $requestType
40
     * @param $language
41
     * @param $location
42
     * @param bool $withTargetedMonthlySearches
43
     * @param $included
44
     * @param $excluded
45
     *
46
     * @throws ApiException
47
     *
48
     * @return \Google\AdsApi\AdWords\v201705\o\TargetingIdeaPage
49
     */
50
    public function performQuery(array $keywords, $requestType, $language = null, $location = null, $withTargetedMonthlySearches = false, $included = null, $excluded = null)
51
    {
52
53
        // Create selector.
54
        $selector = new TargetingIdeaSelector();
55
        $selector->setRequestType($requestType);
56
        $selector->setIdeaType(IdeaType::KEYWORD);
57
        $selector->setRequestedAttributeTypes($this->getRequestedAttributeTypes($withTargetedMonthlySearches));
0 ignored issues
show
Documentation introduced by
$this->getRequestedAttri...argetedMonthlySearches) is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
58
        $selector->setPaging(new Paging(0, self::PAGE_LIMIT));
59
        $selector->setSearchParameters($this->getSearchParameters($keywords, $language, $location, $included, $excluded));
60
61
        $currentTry = 0;
62
63
        while (true) {
64
            try {
65
                $results = $this->targetingIdeaService->get($selector);
66
67
                return $results;
68
            } catch (ApiException $exception) {
69
                $error = $exception->getErrors()[0];
70
                if ($error instanceof RateExceededError and ++$currentTry < self::MAX_RETRIES) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
71
                    sleep($error->getRetryAfterSeconds());
72
                } else {
73
                    throw $exception;
74
                }
75
            }
76
        }
77
    }
78
79
    /**
80
     * @return TargetingIdeaService
81
     */
82
    public function getTargetingIdeaService()
83
    {
84
        return $this->targetingIdeaService;
85
    }
86
87
    /**
88
     * @param bool $withTargetedMonthlySearches
89
     *
90
     * @return array
91
     */
92
    private function getRequestedAttributeTypes($withTargetedMonthlySearches = false)
93
    {
94
        if ($withTargetedMonthlySearches) {
95
            return [
96
                AttributeType::KEYWORD_TEXT,
97
                AttributeType::SEARCH_VOLUME,
98
                AttributeType::COMPETITION,
99
                AttributeType::AVERAGE_CPC,
100
                AttributeType::TARGETED_MONTHLY_SEARCHES,
101
            ];
102
        }
103
104
        return [
105
            AttributeType::KEYWORD_TEXT,
106
            AttributeType::SEARCH_VOLUME,
107
            AttributeType::COMPETITION,
108
            AttributeType::AVERAGE_CPC,
109
        ];
110
    }
111
112
    /**
113
     * @param array $keywords
114
     * @param $languageId
115
     * @param $locationId
116
     * @param $included
117
     * @param $excluded
118
     *
119
     * @return array
120
     */
121
    private function getSearchParameters(array $keywords, $languageId, $locationId, $included, $excluded)
122
    {
123
        $searchParameters = [];
124
125
        //Create Language Parameter
126
        if (!is_null($languageId)) {
127
            $languageParameter = new LanguageSearchParameter();
128
            $language = new Language();
129
            $language->setId($languageId);
130
            $languageParameter->setLanguages([$language]);
131
            $searchParameters[] = $languageParameter;
132
        }
133
134
        //Create Location Parameter
135
        if (!is_null($locationId)) {
136
            $locationParameter = new LocationSearchParameter();
137
            $location = new Location();
138
            $location->setId($locationId);
139
            $locationParameter->setLocations([$location]);
140
            $searchParameters[] = $locationParameter;
141
        }
142
143
        //Network Settings
144
        $networkSetting = new NetworkSetting();
145
        $networkSetting->setTargetGoogleSearch(true);
146
        $networkSetting->setTargetSearchNetwork(false);
147
        $networkSetting->setTargetContentNetwork(false);
148
        $networkSetting->setTargetPartnerSearchNetwork(false);
149
150
        $networkSearchParameter = new NetworkSearchParameter();
151
        $networkSearchParameter->setNetworkSetting($networkSetting);
152
        $searchParameters[] = $networkSearchParameter;
153
154
        // Create related to query search parameter.
155
        $relatedToQuerySearchParameter = new RelatedToQuerySearchParameter();
156
        $relatedToQuerySearchParameter->setQueries($keywords);
157
        $searchParameters[] = $relatedToQuerySearchParameter;
158
159
        if(!is_null($included) or !is_null($excluded)){
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
160
            $ideaTextFilterSearchParameter = new IdeaTextFilterSearchParameter();
161
            if(!is_null($included)) {
162
                $ideaTextFilterSearchParameter->setIncluded($included);
163
            }
164
            if(!is_null($excluded)) {
165
                $ideaTextFilterSearchParameter->setExcluded($excluded);
166
            }
167
            $searchParameters[] = $ideaTextFilterSearchParameter;
168
        }
169
170
        return $searchParameters;
171
    }
172
}
173