Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like OpenWeatherMap often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use OpenWeatherMap, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
34 | class OpenWeatherMap |
||
35 | { |
||
36 | /** |
||
37 | * @var string The basic api url to fetch weather data from. |
||
38 | */ |
||
39 | private $weatherUrl = 'http://api.openweathermap.org/data/2.5/weather?'; |
||
40 | |||
41 | /** |
||
42 | * @var string The basic api url to fetch weekly forecast data from. |
||
43 | */ |
||
44 | private $weatherHourlyForecastUrl = 'http://api.openweathermap.org/data/2.5/forecast?'; |
||
45 | |||
46 | /** |
||
47 | * @var string The basic api url to fetch daily forecast data from. |
||
48 | */ |
||
49 | private $weatherDailyForecastUrl = 'http://api.openweathermap.org/data/2.5/forecast/daily?'; |
||
50 | |||
51 | /** |
||
52 | * @var string The basic api url to fetch history weather data from. |
||
53 | */ |
||
54 | private $weatherHistoryUrl = 'http://api.openweathermap.org/data/2.5/history/city?'; |
||
55 | |||
56 | /** |
||
57 | * The copyright notice. This is no official text, this hint was created regarding to http://openweathermap.org/copyright. |
||
58 | * |
||
59 | * @var string |
||
60 | */ |
||
61 | const COPYRIGHT = 'Weather data from <a href="http://www.openweathermap.org">OpenWeatherMap.org</a>'; |
||
62 | |||
63 | /** |
||
64 | * @var \Cmfcmf\OpenWeatherMap\AbstractCache|bool The cache class. |
||
65 | */ |
||
66 | private $cacheClass = false; |
||
67 | |||
68 | /** |
||
69 | * @var int |
||
70 | */ |
||
71 | private $seconds; |
||
72 | |||
73 | /** |
||
74 | * @var bool |
||
75 | */ |
||
76 | private $wasCached = false; |
||
77 | |||
78 | /** |
||
79 | * @var FetcherInterface The url fetcher. |
||
80 | */ |
||
81 | private $fetcher; |
||
82 | |||
83 | /** |
||
84 | * @var string |
||
85 | */ |
||
86 | private $apiKey = ''; |
||
87 | |||
88 | /** |
||
89 | * Constructs the OpenWeatherMap object. |
||
90 | * |
||
91 | * @param null|string $appid The API key. Defaults to null. |
||
|
|||
92 | * @param null|FetcherInterface $fetcher The interface to fetch the data from OpenWeatherMap. Defaults to |
||
93 | * CurlFetcher() if cURL is available. Otherwise defaults to |
||
94 | * FileGetContentsFetcher() using 'file_get_contents()'. |
||
95 | * @param bool|string $cacheClass If set to false, caching is disabled. Otherwise this must be a class |
||
96 | * extending AbstractCache. Defaults to false. |
||
97 | * @param int $seconds How long weather data shall be cached. Default 10 minutes. |
||
98 | * |
||
99 | * @throws \Exception If $cache is neither false nor a valid callable extending Cmfcmf\OpenWeatherMap\Util\Cache. |
||
100 | * |
||
101 | * @api |
||
102 | */ |
||
103 | public function __construct($fetcher = null, $cacheClass = false, $seconds = 600) |
||
104 | { |
||
105 | if ($cacheClass !== false && !($cacheClass instanceof AbstractCache)) { |
||
106 | throw new \Exception('The cache class must implement the FetcherInterface!'); |
||
107 | } |
||
108 | if (!is_numeric($seconds)) { |
||
109 | throw new \Exception('$seconds must be numeric.'); |
||
110 | } |
||
111 | if (!isset($fetcher)) { |
||
112 | $fetcher = (function_exists('curl_version')) ? new CurlFetcher() : new FileGetContentsFetcher(); |
||
113 | } |
||
114 | if ($seconds == 0) { |
||
115 | $cacheClass = false; |
||
116 | } |
||
117 | |||
118 | $this->cacheClass = $cacheClass; |
||
119 | $this->seconds = $seconds; |
||
120 | $this->fetcher = $fetcher; |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * Sets the API Key. |
||
125 | * |
||
126 | * @param string API key for the OpenWeatherMap account making the connection. |
||
127 | * |
||
128 | * @api |
||
129 | */ |
||
130 | public function setApiKey($appid) |
||
131 | { |
||
132 | $this->apiKey = $appid; |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * Returns the API Key. |
||
137 | * |
||
138 | * @return string |
||
139 | * |
||
140 | * @api |
||
141 | */ |
||
142 | public function getApiKey() |
||
143 | { |
||
144 | return $this->apiKey; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Returns the current weather at the place you specified as an object. |
||
149 | * |
||
150 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
151 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
152 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
153 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
154 | * |
||
155 | * @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error. |
||
156 | * @throws \InvalidArgumentException If an argument error occurs. |
||
157 | * |
||
158 | * @return CurrentWeather The weather object. |
||
159 | * |
||
160 | * There are three ways to specify the place to get weather information for: |
||
161 | * - Use the city name: $query must be a string containing the city name. |
||
162 | * - Use the city id: $query must be an integer containing the city id. |
||
163 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
164 | * |
||
165 | * Available languages are (as of 17. July 2013): |
||
166 | * - English - en |
||
167 | * - Russian - ru |
||
168 | * - Italian - it |
||
169 | * - Spanish - sp |
||
170 | * - Ukrainian - ua |
||
171 | * - German - de |
||
172 | * - Portuguese - pt |
||
173 | * - Romanian - ro |
||
174 | * - Polish - pl |
||
175 | * - Finnish - fi |
||
176 | * - Dutch - nl |
||
177 | * - French - fr |
||
178 | * - Bulgarian - bg |
||
179 | * - Swedish - se |
||
180 | * - Chinese Traditional - zh_tw |
||
181 | * - Chinese Simplified - zh_cn |
||
182 | * - Turkish - tr |
||
183 | * |
||
184 | * @api |
||
185 | */ |
||
186 | public function getWeather($query, $units = 'imperial', $lang = 'en', $appid = '') |
||
187 | { |
||
188 | // Disable default error handling of SimpleXML (Do not throw E_WARNINGs). |
||
189 | libxml_use_internal_errors(true); |
||
190 | libxml_clear_errors(); |
||
191 | |||
192 | $answer = $this->getRawWeatherData($query, $units, $lang, $appid, 'xml'); |
||
193 | |||
194 | try { |
||
195 | $xml = new \SimpleXMLElement($answer); |
||
196 | } catch (\Exception $e) { |
||
197 | // Invalid xml format. This happens in case OpenWeatherMap returns an error. |
||
198 | // OpenWeatherMap always uses json for errors, even if one specifies xml as format. |
||
199 | $error = json_decode($answer, true); |
||
200 | View Code Duplication | if (isset($error['message'])) { |
|
201 | throw new OWMException($error['message'], $error['cod']); |
||
202 | } else { |
||
203 | throw new OWMException('Unknown fatal error: OpenWeatherMap returned the following json object: '.$answer); |
||
204 | } |
||
205 | } |
||
206 | |||
207 | return new CurrentWeather($xml, $units); |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Returns the current weather at the place you specified as an object. |
||
212 | * |
||
213 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
214 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
215 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
216 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
217 | * @param int $days For how much days you want to get a forecast. Default 1, maximum: 16. |
||
218 | * |
||
219 | * @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error. |
||
220 | * @throws \InvalidArgumentException If an argument error occurs. |
||
221 | * |
||
222 | * @return WeatherForecast The WeatherForecast object. |
||
223 | * |
||
224 | * There are three ways to specify the place to get weather information for: |
||
225 | * - Use the city name: $query must be a string containing the city name. |
||
226 | * - Use the city id: $query must be an integer containing the city id. |
||
227 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
228 | * |
||
229 | * Available languages are (as of 17. July 2013): |
||
230 | * - English - en |
||
231 | * - Russian - ru |
||
232 | * - Italian - it |
||
233 | * - Spanish - sp |
||
234 | * - Ukrainian - ua |
||
235 | * - German - de |
||
236 | * - Portuguese - pt |
||
237 | * - Romanian - ro |
||
238 | * - Polish - pl |
||
239 | * - Finnish - fi |
||
240 | * - Dutch - nl |
||
241 | * - French - fr |
||
242 | * - Bulgarian - bg |
||
243 | * - Swedish - se |
||
244 | * - Chinese Traditional - zh_tw |
||
245 | * - Chinese Simplified - zh_cn |
||
246 | * - Turkish - tr |
||
247 | * |
||
248 | * @api |
||
249 | */ |
||
250 | public function getWeatherForecast($query, $units = 'imperial', $lang = 'en', $appid = '', $days = 1) |
||
251 | { |
||
252 | // Disable default error handling of SimpleXML (Do not throw E_WARNINGs). |
||
253 | libxml_use_internal_errors(true); |
||
254 | libxml_clear_errors(); |
||
255 | |||
256 | if ($days <= 5) { |
||
257 | $answer = $this->getRawHourlyForecastData($query, $units, $lang, $appid, 'xml'); |
||
258 | } elseif ($days <= 16) { |
||
259 | $answer = $this->getRawDailyForecastData($query, $units, $lang, $appid, 'xml', $days); |
||
260 | } else { |
||
261 | throw new \InvalidArgumentException('Error: forecasts are only available for the next 16 days. $days must be lower than 17.'); |
||
262 | } |
||
263 | |||
264 | try { |
||
265 | $xml = new \SimpleXMLElement($answer); |
||
266 | } catch (\Exception $e) { |
||
267 | // Invalid xml format. This happens in case OpenWeatherMap returns an error. |
||
268 | // OpenWeatherMap always uses json for errors, even if one specifies xml as format. |
||
269 | $error = json_decode($answer, true); |
||
270 | View Code Duplication | if (isset($error['message'])) { |
|
271 | throw new OWMException($error['message'], $error['cod']); |
||
272 | } else { |
||
273 | throw new OWMException('Unknown fatal error: OpenWeatherMap returned the following json object: '.$answer); |
||
274 | } |
||
275 | } |
||
276 | |||
277 | return new WeatherForecast($xml, $units, $days); |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Returns the weather history for the place you specified as an object. |
||
282 | * |
||
283 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
284 | * @param \DateTime $start |
||
285 | * @param int $endOrCount |
||
286 | * @param string $type |
||
287 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
288 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
289 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
290 | * |
||
291 | * @throws OpenWeatherMap\Exception If OpenWeatherMap returns an error. |
||
292 | * @throws \InvalidArgumentException If an argument error occurs. |
||
293 | * |
||
294 | * @return WeatherHistory The WeatherHistory object. |
||
295 | * |
||
296 | * There are three ways to specify the place to get weather information for: |
||
297 | * - Use the city name: $query must be a string containing the city name. |
||
298 | * - Use the city id: $query must be an integer containing the city id. |
||
299 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
300 | * |
||
301 | * Available languages are (as of 17. July 2013): |
||
302 | * - English - en |
||
303 | * - Russian - ru |
||
304 | * - Italian - it |
||
305 | * - Spanish - sp |
||
306 | * - Ukrainian - ua |
||
307 | * - German - de |
||
308 | * - Portuguese - pt |
||
309 | * - Romanian - ro |
||
310 | * - Polish - pl |
||
311 | * - Finnish - fi |
||
312 | * - Dutch - nl |
||
313 | * - French - fr |
||
314 | * - Bulgarian - bg |
||
315 | * - Swedish - se |
||
316 | * - Chinese Traditional - zh_tw |
||
317 | * - Chinese Simplified - zh_cn |
||
318 | * - Turkish - tr |
||
319 | * |
||
320 | * @api |
||
321 | */ |
||
322 | public function getWeatherHistory($query, \DateTime $start, $endOrCount = 1, $type = 'hour', $units = 'imperial', $lang = 'en', $appid = '') |
||
323 | { |
||
324 | View Code Duplication | if (!in_array($type, array('tick', 'hour', 'day'))) { |
|
325 | throw new \InvalidArgumentException('$type must be either "tick", "hour" or "day"'); |
||
326 | } |
||
327 | |||
328 | $xml = json_decode($this->getRawWeatherHistory($query, $start, $endOrCount, $type, $units, $lang, empty($appid) ? $this->apiKey : $appid), true); |
||
329 | |||
330 | if ($xml['cod'] != 200) { |
||
331 | throw new OWMException($xml['message'], $xml['cod']); |
||
332 | } |
||
333 | |||
334 | return new WeatherHistory($xml, $query); |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * @deprecated Use {@link self::getRawWeatherData()} instead. |
||
339 | */ |
||
340 | public function getRawData($query, $units = 'imperial', $lang = 'en', $appid = '', $mode = 'xml') |
||
341 | { |
||
342 | return $this->getRawWeatherData($query, $units, $lang, $appid, $mode); |
||
343 | } |
||
344 | |||
345 | /** |
||
346 | * Directly returns the xml/json/html string returned by OpenWeatherMap for the current weather. |
||
347 | * |
||
348 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
349 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
350 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
351 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
352 | * @param string $mode The format of the data fetched. Possible values are 'json', 'html' and 'xml' (default). |
||
353 | * |
||
354 | * @return string Returns false on failure and the fetched data in the format you specified on success. |
||
355 | * |
||
356 | * Warning If an error occurred, OpenWeatherMap returns data in json format ALWAYS |
||
357 | * |
||
358 | * There are three ways to specify the place to get weather information for: |
||
359 | * - Use the city name: $query must be a string containing the city name. |
||
360 | * - Use the city id: $query must be an integer containing the city id. |
||
361 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
362 | * |
||
363 | * Available languages are (as of 17. July 2013): |
||
364 | * - English - en |
||
365 | * - Russian - ru |
||
366 | * - Italian - it |
||
367 | * - Spanish - sp |
||
368 | * - Ukrainian - ua |
||
369 | * - German - de |
||
370 | * - Portuguese - pt |
||
371 | * - Romanian - ro |
||
372 | * - Polish - pl |
||
373 | * - Finnish - fi |
||
374 | * - Dutch - nl |
||
375 | * - French - fr |
||
376 | * - Bulgarian - bg |
||
377 | * - Swedish - se |
||
378 | * - Chinese Traditional - zh_tw |
||
379 | * - Chinese Simplified - zh_cn |
||
380 | * - Turkish - tr |
||
381 | * |
||
382 | * @api |
||
383 | */ |
||
384 | public function getRawWeatherData($query, $units = 'imperial', $lang = 'en', $appid = '', $mode = 'xml') |
||
385 | { |
||
386 | $url = $this->buildUrl($query, $units, $lang, $appid, $mode, $this->weatherUrl); |
||
387 | |||
388 | return $this->cacheOrFetchResult($url); |
||
389 | } |
||
390 | |||
391 | /** |
||
392 | * Directly returns the xml/json/html string returned by OpenWeatherMap for the hourly forecast. |
||
393 | * |
||
394 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
395 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
396 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
397 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
398 | * @param string $mode The format of the data fetched. Possible values are 'json', 'html' and 'xml' (default). |
||
399 | * |
||
400 | * @return string Returns false on failure and the fetched data in the format you specified on success. |
||
401 | * |
||
402 | * Warning If an error occurred, OpenWeatherMap returns data in json format ALWAYS |
||
403 | * |
||
404 | * There are three ways to specify the place to get weather information for: |
||
405 | * - Use the city name: $query must be a string containing the city name. |
||
406 | * - Use the city id: $query must be an integer containing the city id. |
||
407 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
408 | * |
||
409 | * Available languages are (as of 17. July 2013): |
||
410 | * - English - en |
||
411 | * - Russian - ru |
||
412 | * - Italian - it |
||
413 | * - Spanish - sp |
||
414 | * - Ukrainian - ua |
||
415 | * - German - de |
||
416 | * - Portuguese - pt |
||
417 | * - Romanian - ro |
||
418 | * - Polish - pl |
||
419 | * - Finnish - fi |
||
420 | * - Dutch - nl |
||
421 | * - French - fr |
||
422 | * - Bulgarian - bg |
||
423 | * - Swedish - se |
||
424 | * - Chinese Traditional - zh_tw |
||
425 | * - Chinese Simplified - zh_cn |
||
426 | * - Turkish - tr |
||
427 | * |
||
428 | * @api |
||
429 | */ |
||
430 | public function getRawHourlyForecastData($query, $units = 'imperial', $lang = 'en', $appid = '', $mode = 'xml') |
||
431 | { |
||
432 | $url = $this->buildUrl($query, $units, $lang, $appid, $mode, $this->weatherHourlyForecastUrl); |
||
433 | |||
434 | return $this->cacheOrFetchResult($url); |
||
435 | } |
||
436 | |||
437 | /** |
||
438 | * Directly returns the xml/json/html string returned by OpenWeatherMap for the daily forecast. |
||
439 | * |
||
440 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
441 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
442 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
443 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
444 | * @param string $mode The format of the data fetched. Possible values are 'json', 'html' and 'xml' (default) |
||
445 | * @param int $cnt How many days of forecast shall be returned? Maximum (and default): 16 |
||
446 | * |
||
447 | * @throws \InvalidArgumentException If $cnt is higher than 16. |
||
448 | * |
||
449 | * @return string Returns false on failure and the fetched data in the format you specified on success. |
||
450 | * |
||
451 | * Warning If an error occurred, OpenWeatherMap returns data in json format ALWAYS |
||
452 | * |
||
453 | * There are three ways to specify the place to get weather information for: |
||
454 | * - Use the city name: $query must be a string containing the city name. |
||
455 | * - Use the city id: $query must be an integer containing the city id. |
||
456 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
457 | * |
||
458 | * Available languages are (as of 17. July 2013): |
||
459 | * - English - en |
||
460 | * - Russian - ru |
||
461 | * - Italian - it |
||
462 | * - Spanish - sp |
||
463 | * - Ukrainian - ua |
||
464 | * - German - de |
||
465 | * - Portuguese - pt |
||
466 | * - Romanian - ro |
||
467 | * - Polish - pl |
||
468 | * - Finnish - fi |
||
469 | * - Dutch - nl |
||
470 | * - French - fr |
||
471 | * - Bulgarian - bg |
||
472 | * - Swedish - se |
||
473 | * - Chinese Traditional - zh_tw |
||
474 | * - Chinese Simplified - zh_cn |
||
475 | * - Turkish - tr |
||
476 | * |
||
477 | * @api |
||
478 | */ |
||
479 | public function getRawDailyForecastData($query, $units = 'imperial', $lang = 'en', $appid = '', $mode = 'xml', $cnt = 16) |
||
480 | { |
||
481 | if ($cnt > 16) { |
||
482 | throw new \InvalidArgumentException('$cnt must be 16 or below!'); |
||
483 | } |
||
484 | $url = $this->buildUrl($query, $units, $lang, $appid, $mode, $this->weatherDailyForecastUrl)."&cnt=$cnt"; |
||
485 | |||
486 | return $this->cacheOrFetchResult($url); |
||
487 | } |
||
488 | |||
489 | /** |
||
490 | * Directly returns the xml/json/html string returned by OpenWeatherMap for the daily forecast. |
||
491 | * |
||
492 | * @param array|int|string $query The place to get weather information for. For possible values see below. |
||
493 | * @param \DateTime $start The \DateTime object of the date to get the first weather information from. |
||
494 | * @param \DateTime|int $endOrCount Can be either a \DateTime object representing the end of the period to |
||
495 | * receive weather history data for or an integer counting the number of |
||
496 | * reports requested. |
||
497 | * @param string $type The period of the weather history requested. Can be either be either "tick", |
||
498 | * "hour" or "day". |
||
499 | * @param string $units Can be either 'metric' or 'imperial' (default). This affects almost all units returned. |
||
500 | * @param string $lang The language to use for descriptions, default is 'en'. For possible values see below. |
||
501 | * @param string $appid Your app id, default ''. See http://openweathermap.org/appid for more details. |
||
502 | * |
||
503 | * @throws \InvalidArgumentException |
||
504 | * |
||
505 | * @return string Returns false on failure and the fetched data in the format you specified on success. |
||
506 | * |
||
507 | * Warning If an error occurred, OpenWeatherMap returns data in json format ALWAYS |
||
508 | * |
||
509 | * There are three ways to specify the place to get weather information for: |
||
510 | * - Use the city name: $query must be a string containing the city name. |
||
511 | * - Use the city id: $query must be an integer containing the city id. |
||
512 | * - Use the coordinates: $query must be an associative array containing the 'lat' and 'lon' values. |
||
513 | * |
||
514 | * Available languages are (as of 17. July 2013): |
||
515 | * - English - en |
||
516 | * - Russian - ru |
||
517 | * - Italian - it |
||
518 | * - Spanish - sp |
||
519 | * - Ukrainian - ua |
||
520 | * - German - de |
||
521 | * - Portuguese - pt |
||
522 | * - Romanian - ro |
||
523 | * - Polish - pl |
||
524 | * - Finnish - fi |
||
525 | * - Dutch - nl |
||
526 | * - French - fr |
||
527 | * - Bulgarian - bg |
||
528 | * - Swedish - se |
||
529 | * - Chinese Traditional - zh_tw |
||
530 | * - Chinese Simplified - zh_cn |
||
531 | * - Turkish - tr |
||
532 | * |
||
533 | * @api |
||
534 | */ |
||
535 | public function getRawWeatherHistory($query, \DateTime $start, $endOrCount = 1, $type = 'hour', $units = 'imperial', $lang = 'en', $appid = '') |
||
536 | { |
||
537 | View Code Duplication | if (!in_array($type, array('tick', 'hour', 'day'))) { |
|
538 | throw new \InvalidArgumentException('$type must be either "tick", "hour" or "day"'); |
||
539 | } |
||
540 | |||
541 | $queryUrl = $this->weatherHistoryUrl.$this->buildQueryUrlParameter($query)."&start={$start->format('U')}"; |
||
542 | |||
543 | if ($endOrCount instanceof \DateTime) { |
||
544 | $queryUrl .= "&end={$endOrCount->format('U')}"; |
||
545 | } elseif (is_numeric($endOrCount) && $endOrCount > 0) { |
||
546 | $queryUrl .= "&cnt=$endOrCount"; |
||
547 | } else { |
||
548 | throw new \InvalidArgumentException('$endOrCount must be either a \DateTime or a positive integer.'); |
||
549 | } |
||
550 | $queryUrl .= "&type=$type&units=$units&lang=$lang&APPID="; |
||
551 | |||
552 | $queryUrl .= empty($appid) ? $this->apiKey : $appid; |
||
553 | |||
554 | return $this->cacheOrFetchResult($queryUrl); |
||
555 | } |
||
556 | |||
557 | /** |
||
558 | * Fetches the result or delivers a cached version of the result. |
||
559 | * |
||
560 | * @param $url |
||
561 | * |
||
562 | * @return string |
||
563 | * |
||
564 | * @internal |
||
565 | */ |
||
566 | private function cacheOrFetchResult($url) |
||
567 | { |
||
568 | if ($this->cacheClass !== false) { |
||
569 | /** @var \Cmfcmf\OpenWeatherMap\AbstractCache $cache */ |
||
570 | $cache = $this->cacheClass; |
||
571 | $cache->setSeconds($this->seconds); |
||
572 | $this->wasCached = false; |
||
573 | if ($cache->isCached($url)) { |
||
574 | $this->wasCached = true; |
||
575 | |||
576 | return $cache->getCached($url); |
||
577 | } |
||
578 | $result = $this->fetcher->fetch($url); |
||
579 | $cache->setCached($url, $result); |
||
580 | } else { |
||
581 | $result = $this->fetcher->fetch($url); |
||
582 | } |
||
583 | |||
584 | return $result; |
||
585 | } |
||
586 | |||
587 | /** |
||
588 | * Build the url to fetch weather data from. |
||
589 | * |
||
590 | * @param $query |
||
591 | * @param $units |
||
592 | * @param $lang |
||
593 | * @param $appid |
||
594 | * @param $mode |
||
595 | * @param string $url The url to prepend. |
||
596 | * |
||
597 | * @return bool|string The fetched url, false on failure. |
||
598 | * |
||
599 | * @internal |
||
600 | */ |
||
601 | private function buildUrl($query, $units, $lang, $appid, $mode, $url) |
||
610 | |||
611 | /** |
||
612 | * Builds the query string for the url. |
||
613 | * |
||
614 | * @param $query |
||
615 | * |
||
616 | * @return string The built query string for the url. |
||
617 | * |
||
618 | * @throws \InvalidArgumentException If the query parameter is invalid. |
||
619 | * |
||
620 | * @internal |
||
621 | */ |
||
622 | private function buildQueryUrlParameter($query) |
||
635 | |||
636 | /** |
||
637 | * Returns whether or not the last result was fetched from the cache. |
||
638 | * |
||
639 | * @return bool true if last result was fetched from cache, otherwise false. |
||
640 | */ |
||
641 | public function wasCached() |
||
645 | } |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italy
is not defined by the methodfinale(...)
.The most likely cause is that the parameter was removed, but the annotation was not.