Completed
Push — master ( 7163fd...45a253 )
by Karl
03:15
created

JobsMulti::setKeyword()   D

Complexity

Conditions 9
Paths 9

Size

Total Lines 31
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 9.0995

Importance

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