Completed
Push — master ( 5f6026...7163fd )
by Karl
17s
created

JobsMulti::setLocation()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 39
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 9.0608

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 30
cts 33
cp 0.9091
rs 4.909
c 0
b 0
f 0
cc 9
eloc 32
nc 9
nop 1
crap 9.0608
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 'Dice':
105 2
                    $query->set('text', $keyword);
106 2
                    break;
107 2
                case 'Govt':
108 2
                    $query->set('query', $keyword);
109 2
                    break;
110 2
                case 'Github':
111 2
                    $query->set('search', $keyword);
112 2
                    break;
113 2
                case 'Indeed':
114 2
                    $query->set('q', $keyword);
115 2
                    break;
116 2
                case 'Usajobs':
117 2
                    $query->set('Keyword', $keyword);
118 2
                    break;
119
                default:
120
                    throw new \Exception("Provider {$provider} not found");
121
            }
122 2
        }
123 2
        return $this;
124
    }
125
126
    /**
127
     * Sets a location on the query for each provider.
128
     *
129
     * @param $location
130
     *
131
     * @return $this
132
     */
133 4
    public function setLocation($location)
134
    {
135 4
        if (!$this->isValidLocation($location)) {
136 2
            throw new \OutOfBoundsException("Location parameter must follow the pattern 'City, ST'.");
137
        }
138
139 2
        $locationArr = explode(', ', $location);
140 2
        $city = $locationArr[0];
141 2
        $state = $locationArr[1];
142
143 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...
144
            switch ($provider) {
145 2
                case 'Careerbuilder':
146 2
                    $query->set('UseFacets', 'true');
147 2
                    $query->set('FacetCityState', $location);
148 2
                    break;
149 2
                case 'Dice':
150 2
                    $query->set('city', $city);
151 2
                    $query->set('state', $state);
152 2
                    break;
153 2
                case 'Govt':
154 2
                    $queryString = $query->get('query').' in '.$location;
155 2
                    $query->set('query', $queryString);
156 2
                    break;
157 2
                case 'Github':
158 2
                    $query->set('location', $location);
159 2
                    break;
160 2
                case 'Indeed':
161 2
                    $query->set('l', $location);
162 2
                    break;
163 2
                case 'Usajobs':
164 2
                    $query->set('LocationName', $location);
165 2
                    break;
166
                default:
167
                    throw new \Exception("Provider {$provider} not found");
168
            }
169 2
        }
170 2
        return $this;
171
    }
172
173
    /**
174
     * Sets a page number and number of results per page for each provider.
175
     *
176
     * @param $page integer
177
     * @param $perPage integer
178
     *
179
     * @return $this
180
     */
181 2
    public function setPage($page = 1, $perPage = 10)
182
    {
183 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...
184
            switch ($provider) {
185 2
                case 'Careerbuilder':
186 2
                    $query->set('PageNumber', $page);
187 2
                    $query->set('PerPage', $perPage);
188 2
                    break;
189 2
                case 'Dice':
190 2
                    $query->set('page', $page);
191 2
                    $query->set('pgcnt', $perPage);
192 2
                    break;
193 2
                case 'Govt':
194 2
                    $query->set('size', $perPage);
195 2
                    $query->set('from', $this->getStartFrom($page, $perPage));
196 2
                    break;
197 2
                case 'Github':
198 2
                    $query->set('page', $page-1);
199
                    // No per_page option
200 2
                    break;
201 2
                case 'Indeed':
202 2
                    $query->set('limit', $perPage);
203 2
                    $query->set('start', $this->getStartFrom($page, $perPage));
204 2
                    break;
205 2
                case 'Usajobs':
206 2
                    $query->set('Page', $page);
207 2
                    $query->set('ResultsPerPage', $perPage);
208 2
                    break;
209
                default:
210
                    throw new \Exception("Provider {$provider} not found");
211
            }
212 2
        }
213 2
        return $this;
214
    }
215
216
    /**
217
     * Gets a start from count for APIs that use per_page and start_from pattern.
218
     *
219
     * @param int $page
220
     * @param int $perPage
221
     *
222
     * @return int
223
     */
224 2
    private function getStartFrom($page = 1, $perPage = 10)
225
    {
226 2
        return ($page * $perPage) - $perPage;
227
    }
228
229
    /**
230
     * Tests whether location string follows valid convention (City, ST).
231
     *
232
     * @param string $location
233
     *
234
     * @return bool
235
     */
236 4
    private function isValidLocation($location = null)
237
    {
238 4
        preg_match("/([^,]+),\s*(\w{2})/", $location, $matches);
239 4
        return isset($matches[1]) && isset($matches[2]) ? true : false;
240
    }
241
242
    /**
243
     * Tests whether the method is a valid get<Provider>Jobs() method.
244
     *
245
     * @param $method
246
     *
247
     * @return bool
248
     */
249 2
    private function isGetJobsByProviderMethod($method)
250
    {
251 2
        return preg_match('/(get)(.*?)(Jobs)/', $method, $matches) && $matches[2] && isset($this->queries[$matches[2]]);
252
    }
253
254
    /**
255
     * Get the provider name from the method.
256
     *
257
     * @param $method
258
     *
259
     * @return string
260
     */
261
    private function getProviderFromMethod($method)
262
    {
263
        preg_match('/(get)(.*?)(Jobs)/', $method, $matches);
264
        return $matches[2];
265
    }
266
}
267