Completed
Push — master ( 6fdefe...ec2cdb )
by Jeff
04:37 queued 01:52
created

Weather::contentRules()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
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