Completed
Push — master ( c27959...59521c )
by Karl
04:24
created

JobsMulti::setPage()   C

Complexity

Conditions 11
Paths 11

Size

Total Lines 46
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 11.044

Importance

Changes 0
Metric Value
dl 0
loc 46
ccs 39
cts 42
cp 0.9286
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 41
nc 11
nop 2
crap 11.044

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