ElementCountDown::encodeArrayValues()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 0
cts 0
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Dynamic\Elements\CountDown\Elements;
4
5
use \DateTime;
6
use \DateTimeZone;
7
use DNADesign\Elemental\Models\BaseElement;
8
use SilverStripe\Forms\DropdownField;
9
use SilverStripe\Forms\FieldList;
10
use SilverStripe\ORM\FieldType\DBField;
11
use SilverStripe\View\ArrayData;
12
13
/**
14
 * Class ElementCountDown
15
 * @package Dynamic\Elements\Elements
16
 *
17
 * @property string $End
18
 * @property string Timezone
19
 * @property boolean $ShowMonths
20
 * @property boolean $ShowSeconds
21
 * @property boolean $Elapse
22
 */
23
class ElementCountDown extends BaseElement
24
{
25
    /**
26
     * @var string
27
     */
28
    private static $icon = 'font-icon-clock';
0 ignored issues
show
introduced by
The private property $icon is not used, and could be removed.
Loading history...
29
30
    /**
31
     * @var string
32
     */
33
    private static $singular_name = 'Countdown Element';
0 ignored issues
show
introduced by
The private property $singular_name is not used, and could be removed.
Loading history...
34
35
    /**
36
     * @var string
37
     */
38
    private static $plural_name = 'Countdown Elements';
0 ignored issues
show
introduced by
The private property $plural_name is not used, and could be removed.
Loading history...
39
40
    /**
41
     * @var string
42
     */
43
    private static $description = 'Displays a countdown to a specific date and time.';
0 ignored issues
show
introduced by
The private property $description is not used, and could be removed.
Loading history...
44
45
    /**
46
     * @var array
47
     */
48
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
49
        'End' => 'DBDatetime',
50
        'Timezone' => 'Varchar(20)',
51
        'ShowMonths' => 'Boolean',
52
        'ShowSeconds' => 'Boolean',
53
        'Elapse' => 'Boolean',
54
    ];
55
56
    /**
57
     * @var string
58
     */
59
    private static $table_name = 'ElementCountDown';
0 ignored issues
show
introduced by
The private property $table_name is not used, and could be removed.
Loading history...
60
61
    /**
62
     * @var ArrayData
63
     */
64
    private $client_config;
65
66
    /**
67
     * @return string
68
     */
69
    public function getSummary()
70
    {
71
        $end = $this->dbObject('End');
72
        $timezone = $this->dbObject('Timezone');
73
        return DBField::create_field(
74
            'HTMLText',
75
            trim("Count down to {$end->Date()} {$end->Time()} {$timezone}")
76
        )->Summary(20);
77
    }
78
79
    /**
80
     * @return FieldList
81
     */
82
    public function getCMSFields()
83
    {
84
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
85 1
            $fields->replaceField(
86
                'Timezone',
87 1
                DropdownField::create('Timezone')
88
                    ->setSource($this->getTimezoneList())
89
            );
90
        });
91
        return parent::getCMSFields();
92
    }
93 2
94
    /**
95
     * originally from https://davidhancock.co/2013/05/generating-a-list-of-timezones-with-php/
96 2
     * @return array
97 2
     */
98
    protected function getTimezoneList()
99
    {
100 2
        $timezoneIdentifiers = DateTimeZone::listIdentifiers(DateTimeZone::ALL);
101
        $utcTime = new DateTime('now', new DateTimeZone('UTC'));
102 2
103
        $tempTimezones = [];
104
        foreach ($timezoneIdentifiers as $timezoneIdentifier) {
105
            $currentTimezone = new DateTimeZone($timezoneIdentifier);
106
107
            $tempTimezones[] = array(
108 2
                'offset' => (int)$currentTimezone->getOffset($utcTime),
109
                'identifier' => $timezoneIdentifier,
110 2
            );
111 2
        }
112
113
        // Sort the array by offset,identifier ascending
114 2
        usort($tempTimezones, function ($a, $b) {
115
            if ($a['offset'] == $b['offset']) {
116
                return strcmp($a['identifier'], $b['identifier']);
117
            }
118
            return $a['offset'] - $b['offset'];
119
        });
120
121 2
        $timezoneList = [];
122
        foreach ($tempTimezones as $tz) {
123 2
            $sign = ($tz['offset'] > 0) ? '+' : '-';
124 2
            $offset = gmdate('H:i', abs($tz['offset']));
0 ignored issues
show
Bug introduced by
It seems like abs($tz['offset']) can also be of type double; however, parameter $timestamp of gmdate() does only seem to accept integer|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
            $offset = gmdate('H:i', /** @scrutinizer ignore-type */ abs($tz['offset']));
Loading history...
125
            $timezoneList["UTC{$sign}{$offset}"] = "(UTC {$sign}{$offset}) {$tz['identifier']}";
126
        }
127 2
128
        return $timezoneList;
129
    }
130
131
    /**
132
     * @return array
133 1
     */
134
    protected function provideBlockSchema()
135 1
    {
136
        $blockSchema = parent::provideBlockSchema();
137
        $blockSchema['content'] = $this->getSummary();
138 1
        return $blockSchema;
139 1
    }
140
141
    /**
142
     * @return string
143 1
     */
144 1
    public function getType()
145 1
    {
146
        return _t(__CLASS__ . '.BlockType', 'Countdown');
147
    }
148 1
149 1
    /**
150
     * @return $this
151
     */
152 1
    public function setClientConfig()
153
    {
154
        $clientArray = [
155
            'End' => trim("{$this->End}  {$this->Timezone}"),
156
            'Elapse' => $this->Elapse,
157
        ];
158
159
        $this->client_config = ArrayData::create($this->encodeArrayValues($clientArray));
160
161
        return $this;
162
    }
163
164
    /**
165
     * @return ArrayData
166
     */
167
    public function getClientConfig()
168
    {
169
        if (!$this->client_config) {
170
            $this->setClientConfig();
171
        }
172
173
        return $this->client_config;
174
    }
175
176
    /**
177
     * @param $array
178
     * @return mixed
179
     */
180
    protected function encodeArrayValues($array)
181
    {
182
        foreach ($array as $key => $val) {
183
            $array[$key] = trim(json_encode($val));
184
        }
185
186
        return $array;
187
    }
188
189
    /**
190
     * @return \SilverStripe\ORM\ValidationResult
191
     */
192
    public function validate()
193
    {
194
        $result = parent::validate();
195
196
        // skip if not written
197
        if (!$this->isInDB()) {
198
            return $result;
199
        }
200
201
        // skip if only sort changed
202
        $changed = $this->getChangedFields(true);
203
        if (count($changed) == 1 && array_key_exists('Sort', $changed)) {
204
            return $result;
205
        }
206
207
        if (!$this->End) {
208
            $result->addError('An end date and time is required before saving the Countdown Element record');
209
        }
210
211
        return $result;
212
    }
213
}
214