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