Completed
Pull Request — master (#24)
by Matthew
17:40 queued 02:39
created

ElementCountDown::getCMSFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1.037

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 10
ccs 2
cts 3
cp 0.6667
crap 1.037
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
            "Count down to {$end->Date()} {$end->Time()} {$timezone}"
76
        )->Summary(20);
77
    }
78
79
    public function getCMSFields()
80
    {
81
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
82
            $fields->replaceField(
83
                'Timezone',
84
                DropdownField::create('Timezone')
85 1
                    ->setSource($this->getTimezoneList())
86
            );
87 1
        });
88
        return parent::getCMSFields(); // TODO: Change the autogenerated stub
89
    }
90
91
    /**
92
     * originally from https://davidhancock.co/2013/05/generating-a-list-of-timezones-with-php/
93 2
     * @return array
94
     */
95
    function getTimezoneList()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
96 2
    {
97 2
        $timezoneIdentifiers = DateTimeZone::listIdentifiers(DateTimeZone::ALL);
98
        $utcTime = new DateTime('now', new DateTimeZone('UTC'));
99
100 2
        $tempTimezones = [];
101
        foreach ($timezoneIdentifiers as $timezoneIdentifier) {
102 2
            $currentTimezone = new DateTimeZone($timezoneIdentifier);
103
104
            $tempTimezones[] = array(
105
                'offset' => (int)$currentTimezone->getOffset($utcTime),
106
                'identifier' => $timezoneIdentifier,
107
            );
108 2
        }
109
110 2
        // Sort the array by offset,identifier ascending
111 2
        usort($tempTimezones, function ($a, $b) {
112
            if ($a['offset'] == $b['offset']) {
113
                return strcmp($a['identifier'], $b['identifier']);
114 2
            }
115
            return $a['offset'] - $b['offset'];
116
        });
117
118
        $timezoneList = [];
119
        foreach ($tempTimezones as $tz) {
120
            $sign = ($tz['offset'] > 0) ? '+' : '-';
121 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, 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

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