1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace app\models\types; |
4
|
|
|
|
5
|
|
|
use Yii; |
6
|
|
|
use app\models\ContentType; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* This is the model class for Weather content type. |
10
|
|
|
*/ |
11
|
|
|
class Weather extends ContentType |
12
|
|
|
{ |
13
|
|
|
const BASE_CACHE_TIME = 600; |
14
|
|
|
const URL = 'https://api.darksky.net/forecast/%apikey%/%data%?lang=%lang%&units=%units%&exclude=hourly,daily,alerts'; |
15
|
|
|
|
16
|
|
|
public $name = 'Weather'; |
17
|
|
|
public $description = 'Display weather for given coordinates.'; |
18
|
|
|
public $html = '<div class="weather">%data%</div>'; |
19
|
|
|
public $css = '%field% { text-align: center; } %field% .wi { font-size: 0.8em; }'; |
20
|
|
|
public $js = ''; |
21
|
|
|
public $input = 'latlong'; |
22
|
|
|
public $output = 'text'; |
23
|
|
|
public $usable = true; |
24
|
|
|
public $preview = '@web/images/weather.preview.jpg'; |
25
|
|
|
|
26
|
|
|
private $opts; |
27
|
|
|
|
28
|
|
|
const ICONS = [ |
29
|
|
|
'clear-day' => 'wi-day-sunny', |
30
|
|
|
'clear-night' => 'wi-night-clear', |
31
|
|
|
'rain' => 'wi-rain', |
32
|
|
|
'snow' => 'wi-snow', |
33
|
|
|
'sleet' => 'wi-sleet', |
34
|
|
|
'wind' => 'wi-strong-wind', |
35
|
|
|
'fog' => 'wi-fog', |
36
|
|
|
'cloudy' => 'wi-cloudy', |
37
|
|
|
'partly-cloudy-day' => 'wi-day-cloudy', |
38
|
|
|
'partly-cloudy-night' => 'wi-night-cloudy', |
39
|
|
|
'hail' => 'wi-hail', |
40
|
|
|
'thunderstorm' => 'wi-lightning', |
41
|
|
|
'tornado' => 'wi-tornado', |
42
|
|
|
]; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Power by DarkSky : https://darksky.net/poweredby/. |
46
|
|
|
*/ |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* {@inheritdoc} |
50
|
|
|
*/ |
51
|
|
|
public function contentRules() |
52
|
|
|
{ |
53
|
|
|
return [ |
54
|
|
|
[['data'], 'match', 'pattern' => '/^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/'], |
55
|
|
|
]; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* {@inheritdoc} |
60
|
|
|
*/ |
61
|
|
|
public function processData($data) |
62
|
|
|
{ |
63
|
|
|
$this->opts = Yii::$app->params['weather']; |
64
|
|
|
|
65
|
|
|
$url = str_replace([ |
66
|
|
|
'%apikey%', |
67
|
|
|
'%data%', |
68
|
|
|
'%lang%', |
69
|
|
|
'%units%', |
70
|
|
|
], [ |
71
|
|
|
$this->opts['apikey'], |
72
|
|
|
$data, |
73
|
|
|
$this->opts['language'], |
74
|
|
|
$this->opts['units'], |
75
|
|
|
], self::URL); |
76
|
|
|
|
77
|
|
|
// Fetch content from cache if possible |
78
|
|
|
$content = self::fromCache($url); |
79
|
|
|
if (!$content) { |
80
|
|
|
$content = self::downloadContent($url); |
81
|
|
|
self::toCache($url, $content); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
return $this->format(json_decode($content)); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
protected function format($w) |
88
|
|
|
{ |
89
|
|
|
if (!$w || !$w->currently) { |
90
|
|
|
return Yii::t('app', 'Weather unavailable'); |
91
|
|
|
} |
92
|
|
|
$c = $w->currently; |
93
|
|
|
$summary = $this->opts['withSummary'] ? $c->summary : ''; |
94
|
|
|
$icon = array_key_exists($c->icon, self::ICONS) ? self::ICONS[$c->icon] : 'wi-na'; |
95
|
|
|
$temp = round($c->temperature, 1); |
96
|
|
|
$tUnit = Yii::t('app', '°F'); |
97
|
|
|
|
98
|
|
|
return <<<EOD |
99
|
|
|
<span class="weather-content"> |
100
|
|
|
<span class="weather-summary">{$summary}</span> |
101
|
|
|
<span class="wi $icon" /> |
102
|
|
|
<span class="weather-temp">{$temp}{$tUnit}</span> |
103
|
|
|
</span> |
104
|
|
|
</div> |
105
|
|
|
EOD; |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
|