Completed
Push — master ( 5cadae...e7e845 )
by Felix
01:50
created

AdWords::keywordIdeas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

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 1
nc 1
nop 1
1
<?php
2
3
namespace SchulzeFelix\AdWords;
4
5
use Google\AdsApi\AdWords\v201705\o\AttributeType;
6
use Google\AdsApi\AdWords\v201705\o\RequestType;
7
use Google\AdsApi\AdWords\v201705\o\TargetingIdeaService;
8
use Google\AdsApi\Common\Util\MapEntries;
9
use Illuminate\Support\Collection;
10
use SchulzeFelix\AdWords\Responses\Keyword;
11
use SchulzeFelix\AdWords\Responses\MonthlySearchVolume;
12
13
class AdWords
14
{
15
    const CHUNK_SIZE = 700;
16
17
    /**
18
     * @var TargetingIdeaService
19
     */
20
    private $service;
21
22
    /** @var bool */
23
    protected $withTargetedMonthlySearches = false;
24
25
    /** @var int|null */
26
    protected $language = null;
27
28
    /** @var int|null */
29
    protected $location = null;
30
31
    /**
32
     * AdWords constructor.
33
     *
34
     * @param AdWordsService $service
35
     */
36
    public function __construct(AdWordsService $service)
37
    {
38
        $this->service = $service;
0 ignored issues
show
Documentation Bug introduced by
It seems like $service of type object<SchulzeFelix\AdWords\AdWordsService> is incompatible with the declared type object<Google\AdsApi\AdW...o\TargetingIdeaService> of property $service.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
39
    }
40
41
    /**
42
     * @param array $keywords
43
     *
44
     * @return Collection
45
     */
46
    public function searchVolumes(array $keywords)
47
    {
48
        $keywords = $this->prepareKeywords($keywords);
49
        $requestType = RequestType::STATS;
50
51
        $searchVolumes = new Collection();
52
        $chunks = array_chunk($keywords, self::CHUNK_SIZE);
53
54
        foreach ($chunks as $index => $keywordChunk) {
55
            $results = $this->service->performQuery($keywordChunk, $requestType, $this->language, $this->location, $this->withTargetedMonthlySearches);
56
            if ($results->getEntries() !== null) {
57
                foreach ($results->getEntries() as $targetingIdea) {
58
                    $keyword = $this->extractKeyword($targetingIdea);
59
                    $searchVolumes->push($keyword);
60
                }
61
            }
62
        }
63
64
        $missingKeywords = array_diff($keywords, $searchVolumes->pluck('keyword')->toArray());
65
66
        foreach ($missingKeywords as $missingKeyword) {
67
            $missingKeywordInstance = new Keyword([
68
                'keyword'       => $missingKeyword,
69
                'search_volume' => null,
70
                'cpc'           => null,
71
                'competition'   => null,
72
            ]);
73
74
            if ($this->withTargetedMonthlySearches) {
75
                $missingKeywordInstance->targeted_monthly_searches = null;
76
            }
77
78
            $searchVolumes->push($missingKeywordInstance);
79
        }
80
81
        return $searchVolumes;
82
    }
83
84
    public function keywordIdeas($keyword)
0 ignored issues
show
Unused Code introduced by
The parameter $keyword is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
85
    {
86
87
    }
88
    /**
89
     * Include Targeted Monthly Searches.
90
     *
91
     * @return $this
92
     */
93
    public function withTargetedMonthlySearches()
94
    {
95
        $this->withTargetedMonthlySearches = true;
96
97
        return $this;
98
    }
99
100
    /**
101
     * Add Language Search Parameter.
102
     *
103
     * @return $this
104
     */
105
    public function language($language = null)
106
    {
107
        $this->language = $language;
108
109
        return $this;
110
    }
111
112
    /**
113
     * Add Location Search Parameter.
114
     *
115
     * @return $this
116
     */
117
    public function location($location = null)
118
    {
119
        $this->location = $location;
120
121
        return $this;
122
    }
123
124
    /**
125
     * @return TargetingIdeaService
126
     */
127
    public function getTargetingIdeaService(): TargetingIdeaService
128
    {
129
        return $this->service->getTargetingIdeaService();
130
    }
131
132
    /**
133
     * Private Functions.
134
     */
135
    private function prepareKeywords(array $keywords)
136
    {
137
        $keywords = array_map('trim', $keywords);
138
        $keywords = array_map('mb_strtolower', $keywords);
139
        $keywords = array_filter($keywords);
140
        $keywords = array_unique($keywords);
141
        $keywords = array_values($keywords);
142
143
        return $keywords;
144
    }
145
146
    /**
147
     * @param $targetingIdea
148
     *
149
     * @return Keyword
150
     */
151
    private function extractKeyword($targetingIdea)
152
    {
153
        $data = MapEntries::toAssociativeArray($targetingIdea->getData());
154
        $keyword = $data[AttributeType::KEYWORD_TEXT]->getValue();
155
        $search_volume =
156
            ($data[AttributeType::SEARCH_VOLUME]->getValue() !== null)
157
                ? $data[AttributeType::SEARCH_VOLUME]->getValue() : 0;
158
159
        $average_cpc =
160
            ($data[AttributeType::AVERAGE_CPC]->getValue() !== null)
161
                ? $data[AttributeType::AVERAGE_CPC]->getValue()->getMicroAmount() : 0;
162
        $competition =
163
            ($data[AttributeType::COMPETITION]->getValue() !== null)
164
                ? $data[AttributeType::COMPETITION]->getValue() : 0;
165
166
        $result = new Keyword([
167
            'keyword'                   => $keyword,
168
            'search_volume'             => $search_volume,
169
            'cpc'                       => $average_cpc,
170
            'competition'               => $competition,
171
            'targeted_monthly_searches' => null,
172
        ]);
173
174
        if ($this->withTargetedMonthlySearches) {
175
            $targeted_monthly_searches =
176
                ($data[AttributeType::TARGETED_MONTHLY_SEARCHES]->getValue() !== null)
177
                    ? $data[AttributeType::TARGETED_MONTHLY_SEARCHES]->getValue() : 0;
178
            $targetedMonthlySearches = collect($targeted_monthly_searches)
179
                ->transform(function ($item, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
180
                    return new MonthlySearchVolume([
181
                        'year'  => $item->getYear(),
182
                        'month' => $item->getMonth(),
183
                        'count' => $item->getCount(),
184
                    ]);
185
                });
186
187
            $result->targeted_monthly_searches = $targetedMonthlySearches;
188
        }
189
190
        return $result;
191
    }
192
}
193