1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Sunnysideup\HealthCheckProvider\Model; |
4
|
|
|
|
5
|
|
|
use SilverStripe\Control\Director; |
6
|
|
|
use SilverStripe\Forms\CheckboxSetField; |
7
|
|
|
use SilverStripe\Forms\GridField\GridField; |
8
|
|
|
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor; |
9
|
|
|
use SilverStripe\Forms\HTMLReadonlyField; |
10
|
|
|
use SilverStripe\Forms\LiteralField; |
11
|
|
|
use SilverStripe\Forms\ReadonlyField; |
12
|
|
|
use SilverStripe\Forms\TextField; |
13
|
|
|
use SilverStripe\ORM\DataObject; |
14
|
|
|
use SilverStripe\Security\Member; |
15
|
|
|
use SilverStripe\Security\Security; |
16
|
|
|
|
17
|
|
|
class HealthCheckProvider extends DataObject |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* @var string |
21
|
|
|
*/ |
22
|
|
|
private const VIEW_URL = 'https://check.silverstripe-webdevelopment.com/report/view/'; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var string |
26
|
|
|
*/ |
27
|
|
|
private const NOT_PROVIDED_PHRASE = 'not provided'; |
28
|
|
|
|
29
|
|
|
protected $cacheForData = []; |
30
|
|
|
|
31
|
|
|
####################### |
32
|
|
|
### Names Section |
33
|
|
|
####################### |
34
|
|
|
|
35
|
|
|
private static $singular_name = 'Report'; |
|
|
|
|
36
|
|
|
|
37
|
|
|
private static $plural_name = 'Reports'; |
|
|
|
|
38
|
|
|
|
39
|
|
|
private static $table_name = 'HealthCheckProvider'; |
|
|
|
|
40
|
|
|
|
41
|
|
|
####################### |
42
|
|
|
### Model Section |
43
|
|
|
####################### |
44
|
|
|
|
45
|
|
|
private static $db = [ |
|
|
|
|
46
|
|
|
'MainUrl' => 'Varchar(255)', |
47
|
|
|
'OtherUrls' => 'Text', |
48
|
|
|
'SendNow' => 'Boolean', |
49
|
|
|
'Sent' => 'Boolean', |
50
|
|
|
'SendCode' => 'Varchar(125)', |
51
|
|
|
'ResponseCode' => 'Varchar(125)', |
52
|
|
|
'HasError' => 'Boolean', |
53
|
|
|
'Data' => 'Text', |
54
|
|
|
]; |
55
|
|
|
|
56
|
|
|
private static $has_one = [ |
|
|
|
|
57
|
|
|
'Editor' => Member::class, |
58
|
|
|
]; |
59
|
|
|
|
60
|
|
|
private static $many_many = [ |
|
|
|
|
61
|
|
|
'HealthCheckItemProviders' => HealthCheckItemProvider::class, |
62
|
|
|
]; |
63
|
|
|
|
64
|
|
|
####################### |
65
|
|
|
### Further DB Field Details |
66
|
|
|
####################### |
67
|
|
|
|
68
|
|
|
private static $indexes = [ |
|
|
|
|
69
|
|
|
'SendCode' => true, |
70
|
|
|
'ResponseCode' => true, |
71
|
|
|
]; |
72
|
|
|
|
73
|
|
|
private static $default_sort = [ |
|
|
|
|
74
|
|
|
'Created' => 'DESC', |
75
|
|
|
]; |
76
|
|
|
|
77
|
|
|
####################### |
78
|
|
|
### Field Names and Presentation Section |
79
|
|
|
####################### |
80
|
|
|
|
81
|
|
|
private static $field_labels = [ |
|
|
|
|
82
|
|
|
'SendNow' => 'Send now?', |
83
|
|
|
'Sent' => 'Has been sent', |
84
|
|
|
'HealthCheckItemProviders' => 'Pieces of Info', |
85
|
|
|
]; |
86
|
|
|
|
87
|
|
|
private static $summary_fields = [ |
|
|
|
|
88
|
|
|
'Title' => 'Health Report Data', |
89
|
|
|
'Sent.Nice' => 'Sent', |
90
|
|
|
'HasError.Nice' => 'Error', |
91
|
|
|
'Editor.Title' => 'Editor', |
92
|
|
|
]; |
93
|
|
|
|
94
|
|
|
####################### |
95
|
|
|
### Casting Section |
96
|
|
|
####################### |
97
|
|
|
|
98
|
|
|
private static $casting = [ |
|
|
|
|
99
|
|
|
'Title' => 'Varchar', |
100
|
|
|
]; |
101
|
|
|
|
102
|
|
|
private $checkLoop = 0; |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* casted variable |
106
|
|
|
*/ |
107
|
|
|
public function getTitle(): string |
108
|
|
|
{ |
109
|
|
|
$str = 'Health Check for ' . $this->MainUrl; |
110
|
|
|
if ($this->Sent) { |
|
|
|
|
111
|
|
|
$str .= '; Sent on ' . $this->dbObject('LastEdited')->Nice(); |
112
|
|
|
} else { |
113
|
|
|
$str .= '; Not sent yet'; |
114
|
|
|
} |
115
|
|
|
return $str; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
####################### |
119
|
|
|
### can Section |
120
|
|
|
####################### |
121
|
|
|
|
122
|
|
|
public function canDelete($member = null) |
123
|
|
|
{ |
124
|
|
|
if ($this->Sent) { |
|
|
|
|
125
|
|
|
return false; |
126
|
|
|
} |
127
|
|
|
return parent::canDelete($member); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
public function canEdit($member = null) |
131
|
|
|
{ |
132
|
|
|
if ($this->Sent) { |
|
|
|
|
133
|
|
|
return false; |
134
|
|
|
} |
135
|
|
|
return parent::canEdit($member); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
####################### |
139
|
|
|
### write Section |
140
|
|
|
####################### |
141
|
|
|
|
142
|
|
|
protected function onBeforeWrite() |
143
|
|
|
{ |
144
|
|
|
parent::onBeforeWrite(); |
145
|
|
|
if (! $this->EditorID) { |
146
|
|
|
$user = Security::getCurrentUser(); |
147
|
|
|
if ($user) { |
|
|
|
|
148
|
|
|
$this->EditorID = Security::getCurrentUser()->ID; |
|
|
|
|
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
if (! $this->MainUrl) { |
152
|
|
|
$this->MainUrl = $this->getSiteURL(); |
|
|
|
|
153
|
|
|
} |
154
|
|
|
if ($this->Sent) { |
|
|
|
|
155
|
|
|
$this->HasError = !$this->getCodesMatch(); |
|
|
|
|
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
public function getCodesMatch(): bool |
160
|
|
|
{ |
161
|
|
|
if ($this->Sent) { |
|
|
|
|
162
|
|
|
return $this->SendCode === $this->ResponseCode; |
|
|
|
|
163
|
|
|
} |
164
|
|
|
return true; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
protected function onAfterWrite() |
168
|
|
|
{ |
169
|
|
|
parent::onAfterWrite(); |
170
|
|
|
|
171
|
|
|
if ($this->checkLoop < 3) { |
172
|
|
|
++$this->checkLoop; |
173
|
|
|
if (! $this->SendCode) { |
174
|
|
|
foreach (HealthCheckItemProvider::get()->filter(['Include' => true]) as $item) { |
175
|
|
|
$this->HealthCheckItemProviders()->add($item); |
|
|
|
|
176
|
|
|
} |
177
|
|
|
$data = $this->retrieveDataInnerInner(); |
178
|
|
|
if (count($data)) { |
179
|
|
|
//send code first because included in data. |
180
|
|
|
$this->SendCode = $this->createSendCode(); |
|
|
|
|
181
|
|
|
//create data. |
182
|
|
|
$this->Data = json_encode($this->retrieveDataInner()); |
|
|
|
|
183
|
|
|
//loop |
184
|
|
|
$this->write(); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
####################### |
191
|
|
|
### CMS Edit Section |
192
|
|
|
####################### |
193
|
|
|
|
194
|
|
|
public function populateDefaults() |
195
|
|
|
{ |
196
|
|
|
parent::populateDefaults(); |
197
|
|
|
$this->MainUrl = $this->getSiteURL(); |
|
|
|
|
198
|
|
|
return $this; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
public function getCMSFields() |
202
|
|
|
{ |
203
|
|
|
$fields = parent::getCMSFields(); |
204
|
|
|
$fields->removeByName( |
205
|
|
|
[ |
206
|
|
|
'SendCode', |
207
|
|
|
'SendNow', |
208
|
|
|
'ResponseCode', |
209
|
|
|
'Sent', |
210
|
|
|
'Data', |
211
|
|
|
'EditorID', |
212
|
|
|
] |
213
|
|
|
); |
214
|
|
|
if ($this->exists()) { |
215
|
|
|
$fields->removeByName( |
216
|
|
|
[ |
217
|
|
|
'HealthCheckItemProviders', |
218
|
|
|
] |
219
|
|
|
); |
220
|
|
|
if ($this->Sent) { |
|
|
|
|
221
|
|
|
$viewLink = $this->ViewLink(); |
222
|
|
|
if ($viewLink) { |
223
|
|
|
$fields->addFieldsToTab( |
224
|
|
|
'Root.Main', |
225
|
|
|
[ |
226
|
|
|
HTMLReadonlyField::create( |
227
|
|
|
'Link', |
228
|
|
|
'Open report', |
229
|
|
|
'<a href="' . $viewLink . '">View Link</a>' |
230
|
|
|
), |
231
|
|
|
] |
232
|
|
|
); |
233
|
|
|
} |
234
|
|
|
} else { |
235
|
|
|
$fields->removeByName( |
236
|
|
|
[ |
237
|
|
|
'HasError', |
238
|
|
|
] |
239
|
|
|
); |
240
|
|
|
$fields->addFieldsToTab( |
241
|
|
|
'Root.Main', |
242
|
|
|
[ |
243
|
|
|
CheckboxSetField::create( |
244
|
|
|
'HealthCheckItemProviders', |
245
|
|
|
'Data Points to be Provided', |
246
|
|
|
HealthCheckItemProvider::get()->filter(['Include' => true])->map('ID', 'CodeNice') |
247
|
|
|
)->setDescription('Please untick any data that you prefer not to provide.'), |
248
|
|
|
] |
249
|
|
|
); |
250
|
|
|
} |
251
|
|
|
$fields->addFieldsToTab( |
252
|
|
|
'Root.Main', |
253
|
|
|
[ |
254
|
|
|
TextField::create('MainUrl', 'Main URL'), |
255
|
|
|
TextField::create('MainUrl', 'Main URL'), |
256
|
|
|
TextField::create('OtherUrls', 'Other Urls') |
257
|
|
|
->setDescription('Separate by comma - e.g. new.mysite.com, otherurl.com, etc ...'), |
258
|
|
|
ReadonlyField::create('HasBeenSent', 'Sent', $this->dbObject('Sent')->Nice()), |
259
|
|
|
ReadonlyField::create('Editor Email', 'Editor Email', $this->Editor()->Email), |
|
|
|
|
260
|
|
|
ReadonlyField::create('LastEdited'), |
261
|
|
|
] |
262
|
|
|
); |
263
|
|
|
$fields->addFieldsToTab( |
264
|
|
|
'Root.Output', |
265
|
|
|
[ |
266
|
|
|
ReadonlyField::create('SendCode'), |
267
|
|
|
ReadonlyField::create('ResponseCode'), |
268
|
|
|
LiteralField::create( |
269
|
|
|
'Output', |
270
|
|
|
'<h2>Data</h2><pre>' . json_encode(json_decode($this->Data), JSON_PRETTY_PRINT) . '</pre>' |
271
|
|
|
), |
272
|
|
|
] |
273
|
|
|
); |
274
|
|
|
$fields->addFieldsToTab( |
275
|
|
|
'Root.PiecesOfInfo', |
276
|
|
|
[ |
277
|
|
|
GridField::create( |
278
|
|
|
'HealthCheckItemProvidersList', |
279
|
|
|
'Data List', |
280
|
|
|
HealthCheckItemProvider::get(), |
281
|
|
|
GridFieldConfig_RecordEditor::create() |
282
|
|
|
), |
283
|
|
|
] |
284
|
|
|
); |
285
|
|
|
} else { |
286
|
|
|
$fields->removeByName( |
287
|
|
|
[ |
288
|
|
|
'HasError', |
289
|
|
|
] |
290
|
|
|
); |
291
|
|
|
} |
292
|
|
|
return $fields; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
public function ViewLink() |
296
|
|
|
{ |
297
|
|
|
if ($this->ResponseCode) { |
|
|
|
|
298
|
|
|
return self::VIEW_URL . $this->ResponseCode . '/'; |
299
|
|
|
} |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
protected function hasAnswers(): bool |
303
|
|
|
{ |
304
|
|
|
return (int) $this->HealthCheckItemProviders()->count() > 0; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
protected function createSendCode(): string |
308
|
|
|
{ |
309
|
|
|
$array = $this->retrieveDataInnerInner(); |
310
|
|
|
$serialized = serialize($array); |
311
|
|
|
|
312
|
|
|
return hash('ripemd160', $this->ID . $serialized); |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Return the host website URL |
317
|
|
|
* @return string URL of the host website |
318
|
|
|
*/ |
319
|
|
|
protected function getSiteURL(): string |
320
|
|
|
{ |
321
|
|
|
$base = Director::host(); |
322
|
|
|
|
323
|
|
|
return rtrim($base, '/'); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
####################### |
327
|
|
|
### Calculations |
328
|
|
|
####################### |
329
|
|
|
|
330
|
|
|
protected function retrieveDataInner(): array |
331
|
|
|
{ |
332
|
|
|
return [ |
333
|
|
|
'ID' => $this->ID, |
334
|
|
|
'SendCode' => $this->SendCode, |
335
|
|
|
'MainUrl' => $this->MainUrl, |
336
|
|
|
'OtherUrls' => $this->OtherUrls, |
|
|
|
|
337
|
|
|
'Editor' => [ |
338
|
|
|
'Email' => $this->Editor()->Email, |
339
|
|
|
'FirstName' => $this->Editor()->FirstName, |
340
|
|
|
'Surname' => $this->Editor()->Surname, |
341
|
|
|
], |
342
|
|
|
'Data' => $this->retrieveDataInnerInner(), |
343
|
|
|
]; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
protected function retrieveDataInnerInner(): array |
347
|
|
|
{ |
348
|
|
|
if (count($this->cacheForData) === 0) { |
349
|
|
|
$this->cacheForData = []; |
350
|
|
|
$includeIDList = $this->HealthCheckItemProviders() |
351
|
|
|
->filter(['Include' => true]) |
352
|
|
|
->column('ID'); |
353
|
|
|
$list = HealthCheckItemProvider::get(); |
354
|
|
|
foreach ($list as $item) { |
355
|
|
|
$shortName = $item->getCode(); |
356
|
|
|
if (in_array($item->ID, $includeIDList, false)) { |
357
|
|
|
$this->cacheForData[$shortName] = $item->findAnswer($this); |
358
|
|
|
} else { |
359
|
|
|
$this->cacheForData[$shortName] = SELF::NOT_PROVIDED_PHRASE; |
360
|
|
|
} |
361
|
|
|
} |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
return $this->cacheForData; |
365
|
|
|
} |
366
|
|
|
} |
367
|
|
|
|