Completed
Push — master ( 3667d2...7a3bf5 )
by Karl
12:08
created

JobsMulti::setKeyword()   C

Complexity

Conditions 15
Paths 15

Size

Total Lines 49
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 15.7932

Importance

Changes 0
Metric Value
dl 0
loc 49
ccs 39
cts 46
cp 0.8478
rs 5.1257
c 0
b 0
f 0
cc 15
eloc 45
nc 15
nop 1
crap 15.7932

How to fix   Complexity   

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 namespace JobApis\Jobs\Client;
2
3
use JobApis\Jobs\Client\Providers\AbstractProvider;
4
use JobApis\Jobs\Client\Queries\AbstractQuery;
5
6
class JobsMulti
7
{
8
    /**
9
     * Job board API query objects
10
     *
11
     * @var AbstractQuery
12
     */
13
    protected $queries = [];
14
15
    /**
16
     * Creates query objects for each provider and creates this unified client.
17
     *
18
     * @param array $providers
19
     */
20 18
    public function __construct($providers = [])
21
    {
22 18
        foreach ($providers as $provider => $options) {
23 18
            $query = $provider.'Query';
24 18
            $className = 'JobApis\\Jobs\\Client\\Queries\\'.$query;
25 18
            $this->addQuery($provider, $className, $options);
26 18
        }
27 18
    }
28
29
    /**
30
     * Overrides get<Provider>Jobs() methods
31
     *
32
     * @param $method
33
     * @param $args
34
     *
35
     * @return mixed
36
     */
37 2
    public function __call($method, $args)
38
    {
39 2
        if ($this->isGetJobsByProviderMethod($method)) {
40
            return $this->getJobsByProvider($this->getProviderFromMethod($method));
41
        }
42
43 2
        throw new \BadMethodCallException(sprintf(
44 2
            '%s does not contain a method by the name of "%s"',
45 2
            __CLASS__,
46
            $method
47 2
        ));
48
    }
49
50
    /**
51
     * Instantiates a Query object and adds it to the queries array.
52
     *
53
     * @param $key string Query name
54
     * @param $className string Query class name
55
     * @param $options array Parameters to add to constructor
56
     *
57
     * @return $this
58
     */
59 18
    public function addQuery($key, $className, $options = [])
60
    {
61 18
        $this->queries[$key] = new $className($options);
62 18
        return $this;
63
    }
64
65
    /**
66
     * Gets jobs from all providers in a single go and returns an array of Collection objects.
67
     *
68
     * @return array
69
     */
70
    public function getAllJobs()
71
    {
72
        $jobs = [];
73
        foreach ($this->queries as $key => $query) {
0 ignored issues
show
Bug introduced by
The expression $this->queries of type object<JobApis\Jobs\Client\Queries\AbstractQuery> is not traversable.
Loading history...
74
            $jobs[$key] = $this->getJobsByProvider($key);
75
        }
76
        return $jobs;
77
    }
78
79
    /**
80
     * Gets jobs from a single provider and hydrates a new jobs collection.
81
     *
82
     * @return \JobApis\Jobs\Client\Collection
83
     */
84 2
    public function getJobsByProvider($provider)
85
    {
86
        try {
87 2
            $providerName = 'JobApis\\Jobs\\Client\\Providers\\' . $provider . 'Provider';
88 2
            $client = self::createProvider($providerName, $this->queries[$provider]);
89
            return $client->getJobs();
90 2
        } catch (\Exception $e) {
91 2
            return (new Collection())->addError($e->getMessage());
92
        }
93
    }
94
95
    /**
96
     * Sets a keyword on the query for each provider.
97
     *
98
     * @param $keyword string
99
     *
100
     * @return $this
101
     */
102 2
    public function setKeyword($keyword)
103
    {
104 2
        foreach ($this->queries as $provider => $query) {
0 ignored issues
show
Bug introduced by
The expression $this->queries of type object<JobApis\Jobs\Client\Queries\AbstractQuery> is not traversable.
Loading history...
105
            switch ($provider) {
106 2
                case 'Careerbuilder':
107 2
                    $query->set('Keywords', $keyword);
108 2
                    break;
109 2
                case 'Careercast':
110 2
                    $query->set('keyword', $keyword);
111 2
                    break;
112 2
                case 'Careerjet':
113
                    $query->set('keywords', $keyword);
114
                    break;
115 2
                case 'Dice':
116 2
                    $query->set('text', $keyword);
117 2
                    break;
118 2
                case 'Github':
119 2
                    $query->set('search', $keyword);
120 2
                    break;
121 2
                case 'Govt':
122 2
                    $query->set('query', $keyword);
123 2
                    break;
124 2
                case 'Ieee':
125 2
                    $query->set('keyword', $keyword);
126 2
                    break;
127 2
                case 'Indeed':
128 2
                    $query->set('q', $keyword);
129 2
                    break;
130 2
                case 'Jobinventory':
131 2
                    $query->set('q', $keyword);
132 2
                    break;
133 2
                case 'Juju':
134 2
                    $query->set('k', $keyword);
135 2
                    break;
136 2
                case 'Stackoverflow':
137
                    $query->set('q', $keyword);
138
                    break;
139 2
                case 'Usajobs':
140 2
                    $query->set('Keyword', $keyword);
141 2
                    break;
142 2
                case 'Ziprecruiter':
143 2
                    $query->set('search', $keyword);
144 2
                    break;
145
                default:
146
                    throw new \Exception("Provider {$provider} not found");
147
            }
148 2
        }
149 2
        return $this;
150
    }
151
152
    /**
153
     * Sets a location on the query for each provider.
154
     *
155
     * @param $location
156
     *
157
     * @return $this
158
     */
159 4
    public function setLocation($location)
160
    {
161 4
        if (!$this->isValidLocation($location)) {
162 2
            throw new \OutOfBoundsException("Location parameter must follow the pattern 'City, ST'.");
163
        }
164
165 2
        $locationArr = explode(', ', $location);
166 2
        $city = $locationArr[0];
167 2
        $state = $locationArr[1];
168
169 2
        foreach ($this->queries as $provider => $query) {
0 ignored issues
show
Bug introduced by
The expression $this->queries of type object<JobApis\Jobs\Client\Queries\AbstractQuery> is not traversable.
Loading history...
170
            switch ($provider) {
171 2
                case 'Careerbuilder':
172 2
                    $query->set('Location', $location);
173 2
                    break;
174 2
                case 'Careercast':
175 2
                    $query->set('location', $location);
176 2
                    break;
177 2
                case 'Careerjet':
178
                    $query->set('location', $location);
179
                    break;
180 2
                case 'Dice':
181 2
                    $query->set('city', $city);
182 2
                    $query->set('state', $state);
183 2
                    break;
184 2
                case 'Github':
185 2
                    $query->set('location', $location);
186 2
                    break;
187 2
                case 'Govt':
188 2
                    $queryString = $query->get('query').' in '.$location;
189 2
                    $query->set('query', $queryString);
190 2
                    break;
191 2
                case 'Ieee':
192 2
                    $query->set('location', $location);
193 2
                    break;
194 2
                case 'Indeed':
195 2
                    $query->set('l', $location);
196 2
                    break;
197 2
                case 'Jobinventory':
198 2
                    $query->set('l', $location);
199 2
                    break;
200 2
                case 'Juju':
201 2
                    $query->set('l', $location);
202 2
                    break;
203 2
                case 'Stackoverflow':
204
                    $query->set('l', $location);
205
                    break;
206 2
                case 'Usajobs':
207 2
                    $query->set('LocationName', $location);
208 2
                    break;
209 2
                case 'Ziprecruiter':
210 2
                    $query->set('location', $location);
211 2
                    break;
212
                default:
213
                    throw new \Exception("Provider {$provider} not found");
214
            }
215 2
        }
216 2
        return $this;
217
    }
218
219
    /**
220
     * Sets a page number and number of results per page for each provider.
221
     *
222
     * @param $page integer
223
     * @param $perPage integer
224
     *
225
     * @return $this
226
     */
227 2
    public function setPage($page = 1, $perPage = 10)
228
    {
229 2
        foreach ($this->queries as $provider => $query) {
0 ignored issues
show
Bug introduced by
The expression $this->queries of type object<JobApis\Jobs\Client\Queries\AbstractQuery> is not traversable.
Loading history...
230
            switch ($provider) {
231 2
                case 'Careerbuilder':
232 2
                    $query->set('PageNumber', $page);
233 2
                    $query->set('PerPage', $perPage);
234 2
                    break;
235 2
                case 'Careercast':
236 2
                    $query->set('page', $page);
237 2
                    $query->set('rows', $perPage);
238 2
                    break;
239 2
                case 'Careerjet':
240
                    $query->set('page', $page);
241
                    $query->set('pagesize', $perPage);
242
                    break;
243 2
                case 'Dice':
244 2
                    $query->set('page', $page);
245 2
                    $query->set('pgcnt', $perPage);
246 2
                    break;
247 2
                case 'Github':
248 2
                    $query->set('page', $page-1);
249
                    // No per_page option
250 2
                    break;
251 2
                case 'Govt':
252 2
                    $query->set('size', $perPage);
253 2
                    $query->set('from', $this->getStartFrom($page, $perPage));
254 2
                    break;
255 2
                case 'Ieee':
256 2
                    $query->set('page', $page);
257 2
                    $query->set('rows', $perPage);
258 2
                    break;
259 2
                case 'Indeed':
260 2
                    $query->set('limit', $perPage);
261 2
                    $query->set('start', $this->getStartFrom($page, $perPage));
262 2
                    break;
263 2
                case 'Jobinventory':
264 2
                    $query->set('p', $page);
265 2
                    $query->set('limit', $perPage);
266 2
                    break;
267 2
                case 'Juju':
268 2
                    $query->set('page', $page);
269 2
                    $query->set('jpp', $perPage);
270 2
                    break;
271 2
                case 'Stackoverflow':
272
                    $query->set('pg', $page);
273
                    // No per_page option
274
                    break;
275 2
                case 'Usajobs':
276 2
                    $query->set('Page', $page);
277 2
                    $query->set('ResultsPerPage', $perPage);
278 2
                    break;
279 2
                case 'Ziprecruiter':
280 2
                    $query->set('page', $page);
281 2
                    $query->set('jobs_per_page', $perPage);
282 2
                    break;
283
                default:
284
                    throw new \Exception("Provider {$provider} not found");
285
            }
286 2
        }
287 2
        return $this;
288
    }
289
290
    /**
291
     * Instantiates a provider using a query object.
292
     *
293
     * @param null $name
294
     * @param AbstractQuery $query
295
     *
296
     * @return AbstractProvider
297
     */
298 2
    public static function createProvider($name, AbstractQuery $query)
299
    {
300 2
        return new $name($query);
301
    }
302
303
    /**
304
     * Gets a start from count for APIs that use per_page and start_from pattern.
305
     *
306
     * @param int $page
307
     * @param int $perPage
308
     *
309
     * @return int
310
     */
311 2
    private function getStartFrom($page = 1, $perPage = 10)
312
    {
313 2
        return ($page * $perPage) - $perPage;
314
    }
315
316
    /**
317
     * Tests whether location string follows valid convention (City, ST).
318
     *
319
     * @param string $location
320
     *
321
     * @return bool
322
     */
323 4
    private function isValidLocation($location = null)
324
    {
325 4
        preg_match("/([^,]+),\s*(\w{2})/", $location, $matches);
326 4
        return isset($matches[1]) && isset($matches[2]) ? true : false;
327
    }
328
329
    /**
330
     * Tests whether the method is a valid get<Provider>Jobs() method.
331
     *
332
     * @param $method
333
     *
334
     * @return bool
335
     */
336 2
    private function isGetJobsByProviderMethod($method)
337
    {
338 2
        return preg_match('/(get)(.*?)(Jobs)/', $method, $matches) && $matches[2] && isset($this->queries[$matches[2]]);
339
    }
340
341
    /**
342
     * Get the provider name from the method.
343
     *
344
     * @param $method
345
     *
346
     * @return string
347
     */
348
    private function getProviderFromMethod($method)
349
    {
350
        preg_match('/(get)(.*?)(Jobs)/', $method, $matches);
351
        return $matches[2];
352
    }
353
}
354