Weather   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 9
c 0
b 0
f 0
lcom 1
cbo 2
dl 0
loc 106
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A contentRules() 0 6 1
A processData() 0 25 2
A format() 0 20 5
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