Issues (98)

src/Model/HealthCheckProvider.php (29 issues)

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';
0 ignored issues
show
The private property $singular_name is not used, and could be removed.
Loading history...
36
37
    private static $plural_name = 'Reports';
0 ignored issues
show
The private property $plural_name is not used, and could be removed.
Loading history...
38
39
    private static $table_name = 'HealthCheckProvider';
0 ignored issues
show
The private property $table_name is not used, and could be removed.
Loading history...
40
41
    #######################
42
    ### Model Section
43
    #######################
44
45
    private static $db = [
0 ignored issues
show
The private property $db is not used, and could be removed.
Loading history...
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 = [
0 ignored issues
show
The private property $has_one is not used, and could be removed.
Loading history...
57
        'Editor' => Member::class,
58
    ];
59
60
    private static $many_many = [
0 ignored issues
show
The private property $many_many is not used, and could be removed.
Loading history...
61
        'HealthCheckItemProviders' => HealthCheckItemProvider::class,
62
    ];
63
64
    #######################
65
    ### Further DB Field Details
66
    #######################
67
68
    private static $indexes = [
0 ignored issues
show
The private property $indexes is not used, and could be removed.
Loading history...
69
        'SendCode' => true,
70
        'ResponseCode' => true,
71
    ];
72
73
    private static $default_sort = [
0 ignored issues
show
The private property $default_sort is not used, and could be removed.
Loading history...
74
        'Created' => 'DESC',
75
    ];
76
77
    #######################
78
    ### Field Names and Presentation Section
79
    #######################
80
81
    private static $field_labels = [
0 ignored issues
show
The private property $field_labels is not used, and could be removed.
Loading history...
82
        'SendNow' => 'Send now?',
83
        'Sent' => 'Has been sent',
84
        'HealthCheckItemProviders' => 'Pieces of Info',
85
    ];
86
87
    private static $summary_fields = [
0 ignored issues
show
The private property $summary_fields is not used, and could be removed.
Loading history...
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 = [
0 ignored issues
show
The private property $casting is not used, and could be removed.
Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The property Sent does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The property Sent does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
125
            return false;
126
        }
127
        return parent::canDelete($member);
128
    }
129
130
    public function canEdit($member = null)
131
    {
132
        if ($this->Sent) {
0 ignored issues
show
Bug Best Practice introduced by
The property Sent does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
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) {
0 ignored issues
show
$user is of type SilverStripe\Security\Member, thus it always evaluated to true.
Loading history...
148
                $this->EditorID = Security::getCurrentUser()->ID;
0 ignored issues
show
Bug Best Practice introduced by
The property EditorID does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
149
            }
150
        }
151
        if (! $this->MainUrl) {
152
            $this->MainUrl = $this->getSiteURL();
0 ignored issues
show
Bug Best Practice introduced by
The property MainUrl does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
153
        }
154
        if ($this->Sent) {
0 ignored issues
show
Bug Best Practice introduced by
The property Sent does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
155
            $this->HasError = !$this->getCodesMatch();
0 ignored issues
show
Bug Best Practice introduced by
The property HasError does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
156
        }
157
    }
158
159
    public function getCodesMatch(): bool
160
    {
161
        if ($this->Sent) {
0 ignored issues
show
Bug Best Practice introduced by
The property Sent does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
162
            return $this->SendCode === $this->ResponseCode;
0 ignored issues
show
Bug Best Practice introduced by
The property ResponseCode does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
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);
0 ignored issues
show
The method HealthCheckItemProviders() does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

175
                    $this->/** @scrutinizer ignore-call */ 
176
                           HealthCheckItemProviders()->add($item);
Loading history...
176
                }
177
                $data = $this->retrieveDataInnerInner();
178
                if (count($data)) {
179
                    //send code first because included in data.
180
                    $this->SendCode = $this->createSendCode();
0 ignored issues
show
Bug Best Practice introduced by
The property SendCode does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
181
                    //create data.
182
                    $this->Data = json_encode($this->retrieveDataInner());
0 ignored issues
show
Bug Best Practice introduced by
The property Data does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
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();
0 ignored issues
show
Bug Best Practice introduced by
The property MainUrl does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The property Sent does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
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),
0 ignored issues
show
The method Editor() does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

259
                    ReadonlyField::create('Editor Email', 'Editor Email', $this->/** @scrutinizer ignore-call */ Editor()->Email),
Loading history...
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) {
0 ignored issues
show
Bug Best Practice introduced by
The property ResponseCode does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
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,
0 ignored issues
show
Bug Best Practice introduced by
The property OtherUrls does not exist on Sunnysideup\HealthCheckP...del\HealthCheckProvider. Since you implemented __get, consider adding a @property annotation.
Loading history...
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