Passed
Push — master ( ebdfbb...20570e )
by
unknown
02:32
created

EmailRecipient::validate()   D

Complexity

Conditions 9
Paths 10

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 18
nc 10
nop 0
dl 0
loc 30
rs 4.909
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\UserForms\Model\Recipient;
4
5
use SilverStripe\Admin\LeftAndMain;
6
use SilverStripe\Assets\FileFinder;
7
use SilverStripe\CMS\Controllers\CMSMain;
8
use SilverStripe\CMS\Controllers\CMSPageEditController;
9
use SilverStripe\CMS\Model\SiteTree;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Control\Email\Email;
12
use SilverStripe\Core\Manifest\ModuleResource;
13
use SilverStripe\Core\Manifest\ModuleResourceLoader;
14
use SilverStripe\Forms\CheckboxField;
15
use SilverStripe\Forms\DropdownField;
16
use SilverStripe\Forms\FieldGroup;
17
use SilverStripe\Forms\FieldList;
18
use SilverStripe\Forms\Form;
19
use SilverStripe\Forms\GridField\GridField;
20
use SilverStripe\Forms\GridField\GridFieldButtonRow;
21
use SilverStripe\Forms\GridField\GridFieldConfig;
22
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
23
use SilverStripe\Forms\GridField\GridFieldToolbarHeader;
24
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
25
use SilverStripe\Forms\LiteralField;
26
use SilverStripe\Forms\TabSet;
27
use SilverStripe\Forms\TextareaField;
28
use SilverStripe\Forms\TextField;
29
use SilverStripe\ORM\ArrayList;
30
use SilverStripe\ORM\DataObject;
31
use SilverStripe\ORM\DB;
32
use SilverStripe\ORM\FieldType\DBField;
33
use SilverStripe\UserForms\Model\EditableFormField;
34
use SilverStripe\UserForms\Model\EditableFormField\EditableEmailField;
35
use SilverStripe\UserForms\Model\EditableFormField\EditableMultipleOptionField;
36
use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
37
use SilverStripe\UserForms\Model\UserDefinedForm;
38
use SilverStripe\View\Requirements;
39
use Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton;
40
use Symbiote\GridFieldExtensions\GridFieldEditableColumns;
41
42
/**
43
 * A Form can have multiply members / emails to email the submission
44
 * to and custom subjects
45
 *
46
 * @package userforms
47
 */
48
class EmailRecipient extends DataObject
49
{
50
    private static $db = [
51
        'EmailAddress' => 'Varchar(200)',
52
        'EmailSubject' => 'Varchar(200)',
53
        'EmailFrom' => 'Varchar(200)',
54
        'EmailReplyTo' => 'Varchar(200)',
55
        'EmailBody' => 'Text',
56
        'EmailBodyHtml' => 'HTMLText',
57
        'EmailTemplate' => 'Varchar',
58
        'SendPlain' => 'Boolean',
59
        'HideFormData' => 'Boolean',
60
        'CustomRulesCondition' => 'Enum("And,Or")'
61
    ];
62
63
    private static $has_one = [
64
        'Form' => DataObject::class,
65
        'SendEmailFromField' => EditableFormField::class,
66
        'SendEmailToField' => EditableFormField::class,
67
        'SendEmailSubjectField' => EditableFormField::class
68
    ];
69
70
    private static $has_many = [
71
        'CustomRules' => EmailRecipientCondition::class,
72
    ];
73
74
    private static $owns = [
75
        'CustomRules',
76
    ];
77
78
    private static $cascade_deetes = [
79
        'CustomRules',
80
    ];
81
82
    private static $summary_fields = [
83
        'EmailAddress',
84
        'EmailSubject',
85
        'EmailFrom'
86
    ];
87
88
    private static $table_name = 'UserDefinedForm_EmailRecipient';
89
90
    /**
91
     * Setting this to true will allow you to select "risky" fields as
92
     * email recipient, such as free-text entry fields.
93
     *
94
     * It's advisable to leave this off.
95
     *
96
     * @config
97
     * @var bool
98
     */
99
    private static $allow_unbound_recipient_fields = false;
100
101
    public function requireDefaultRecords()
102
    {
103
        parent::requireDefaultRecords();
104
105
        // make sure to migrate the class across (prior to v5.x)
106
        DB::query("UPDATE UserDefinedForm_EmailRecipient SET FormClass = 'Page' WHERE FormClass IS NULL");
107
    }
108
109
    public function summaryFields()
110
    {
111
        $fields = parent::summaryFields();
112
        if (isset($fields['EmailAddress'])) {
113
            /** @skipUpgrade */
114
            $fields['EmailAddress'] = _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILADDRESS', 'Email');
115
        }
116
        if (isset($fields['EmailSubject'])) {
117
            $fields['EmailSubject'] = _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILSUBJECT', 'Subject');
118
        }
119
        if (isset($fields['EmailFrom'])) {
120
            $fields['EmailFrom'] = _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILFROM', 'From');
121
        }
122
        return $fields;
123
    }
124
125
    /**
126
     * Get instance of UserDefinedForm when editing in getCMSFields
127
     *
128
     * @return UserDefinedForm
129
     */
130
    protected function getFormParent()
131
    {
132
        // LeftAndMain::sessionNamespace is protected. @todo replace this with a non-deprecated equivalent.
133
        $sessionNamespace = $this->config()->get('session_namespace') ?: CMSMain::class;
134
135
        $formID = $this->FormID
0 ignored issues
show
Bug Best Practice introduced by
The property FormID does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
136
            ? $this->FormID
137
            : Controller::curr()->getRequest()->getSession()->get($sessionNamespace . '.currentPage');
138
        return UserDefinedForm::get()->byID($formID);
139
    }
140
141
    public function getTitle()
142
    {
143
        if ($this->EmailAddress) {
0 ignored issues
show
Bug Best Practice introduced by
The property EmailAddress does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
144
            return $this->EmailAddress;
145
        }
146
        if ($this->EmailSubject) {
0 ignored issues
show
Bug Best Practice introduced by
The property EmailSubject does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
147
            return $this->EmailSubject;
148
        }
149
        return parent::getTitle();
150
    }
151
152
    /**
153
     * Generate a gridfield config for editing filter rules
154
     *
155
     * @return GridFieldConfig
156
     */
157
    protected function getRulesConfig()
158
    {
159
        $formFields = $this->getFormParent()->Fields();
160
161
        $config = GridFieldConfig::create()
162
            ->addComponents(
163
                new GridFieldButtonRow('before'),
164
                new GridFieldToolbarHeader(),
165
                new GridFieldAddNewInlineButton(),
166
                new GridFieldDeleteAction(),
167
                $columns = new GridFieldEditableColumns()
168
            );
169
170
        $columns->setDisplayFields(array(
171
            'ConditionFieldID' => function ($record, $column, $grid) use ($formFields) {
0 ignored issues
show
Unused Code introduced by
The parameter $grid is not used and could be removed. ( Ignorable by Annotation )

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

171
            'ConditionFieldID' => function ($record, $column, /** @scrutinizer ignore-unused */ $grid) use ($formFields) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
172
                return DropdownField::create($column, false, $formFields->map('ID', 'Title'));
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

172
                return DropdownField::create($column, /** @scrutinizer ignore-type */ false, $formFields->map('ID', 'Title'));
Loading history...
173
            },
174
            'ConditionOption' => function ($record, $column, $grid) {
0 ignored issues
show
Unused Code introduced by
The parameter $grid is not used and could be removed. ( Ignorable by Annotation )

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

174
            'ConditionOption' => function ($record, $column, /** @scrutinizer ignore-unused */ $grid) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
175
                $options = EmailRecipientCondition::config()->condition_options;
176
                return DropdownField::create($column, false, $options);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

176
                return DropdownField::create($column, /** @scrutinizer ignore-type */ false, $options);
Loading history...
177
            },
178
            'ConditionValue' => function ($record, $column, $grid) {
0 ignored issues
show
Unused Code introduced by
The parameter $grid is not used and could be removed. ( Ignorable by Annotation )

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

178
            'ConditionValue' => function ($record, $column, /** @scrutinizer ignore-unused */ $grid) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
179
                return TextField::create($column);
180
            }
181
        ));
182
183
        return $config;
184
    }
185
186
    /**
187
     * @return FieldList
188
     */
189
    public function getCMSFields()
190
    {
191
        Requirements::javascript('silverstripe/userforms:client/dist/js/userforms-cms.js');
192
193
        // Determine optional field values
194
        $form = $this->getFormParent();
195
196
        // predefined choices are also candidates
197
        $multiOptionFields = EditableMultipleOptionField::get()->filter('ParentID', $form->ID);
198
199
        // if they have email fields then we could send from it
200
        $validEmailFromFields = EditableEmailField::get()->filter('ParentID', $form->ID);
201
202
        // For the subject, only one-line entry boxes make sense
203
        $validSubjectFields = ArrayList::create(
204
            EditableTextField::get()
205
                ->filter('ParentID', $form->ID)
206
                ->exclude('Rows:GreaterThan', 1)
207
                ->toArray()
208
        );
209
        $validSubjectFields->merge($multiOptionFields);
210
211
212
        // Check valid email-recipient fields
213
        if ($this->config()->get('allow_unbound_recipient_fields')) {
214
            // To address can only be email fields or multi option fields
215
            $validEmailToFields = ArrayList::create($validEmailFromFields->toArray());
216
            $validEmailToFields->merge($multiOptionFields);
217
        } else {
218
            // To address cannot be unbound, so restrict to pre-defined lists
219
            $validEmailToFields = $multiOptionFields;
220
        }
221
222
        // Build fieldlist
223
        $fields = FieldList::create(Tabset::create('Root')->addExtraClass('EmailRecipientForm'));
0 ignored issues
show
Bug introduced by
'Root' of type string is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

223
        $fields = FieldList::create(Tabset::create(/** @scrutinizer ignore-type */ 'Root')->addExtraClass('EmailRecipientForm'));
Loading history...
224
225
        // Configuration fields
226
        $fields->addFieldsToTab('Root.EmailDetails', [
227
            // Subject
228
            FieldGroup::create(
229
                TextField::create(
230
                    'EmailSubject',
231
                    _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPESUBJECT', 'Type subject')
232
                )
233
                    ->setAttribute('style', 'min-width: 400px;'),
234
                DropdownField::create(
235
                    'SendEmailSubjectFieldID',
236
                    _t(
237
                        'SilverStripe\\UserForms\\Model\\UserDefinedForm.SELECTAFIELDTOSETSUBJECT',
238
                        '.. or select a field to use as the subject'
239
                    ),
240
                    $validSubjectFields->map('ID', 'Title')
241
                )->setEmptyString('')
242
            )
243
                ->setTitle(_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILSUBJECT', 'Email subject')),
244
245
            // To
246
            FieldGroup::create(
247
                TextField::create(
248
                    'EmailAddress',
249
                    _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPETO', 'Type to address')
250
                )
251
                    ->setAttribute('style', 'min-width: 400px;'),
252
                DropdownField::create(
253
                    'SendEmailToFieldID',
254
                    _t(
255
                        'SilverStripe\\UserForms\\Model\\UserDefinedForm.ORSELECTAFIELDTOUSEASTO',
256
                        '.. or select a field to use as the to address'
257
                    ),
258
                    $validEmailToFields->map('ID', 'Title')
259
                )->setEmptyString(' ')
260
            )
261
                ->setTitle(_t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDEMAILTO', 'Send email to'))
262
                ->setDescription(_t(
263
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDEMAILTO_DESCRIPTION',
264
                    'You may enter multiple email addresses as a comma separated list.'
265
                )),
266
267
268
            // From
269
            TextField::create(
270
                'EmailFrom',
271
                _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.FROMADDRESS', 'Send email from')
272
            )
273
                ->setDescription(_t(
274
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.EmailFromContent',
275
                    "The from address allows you to set who the email comes from. On most servers this ".
276
                    "will need to be set to an email address on the same domain name as your site. ".
277
                    "For example on yoursite.com the from address may need to be [email protected]. ".
278
                    "You can however, set any email address you wish as the reply to address."
279
                )),
280
281
282
            // Reply-To
283
            FieldGroup::create(
284
                TextField::create('EmailReplyTo', _t(
285
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.TYPEREPLY',
286
                    'Type reply address'
287
                ))
288
                    ->setAttribute('style', 'min-width: 400px;'),
289
                DropdownField::create(
290
                    'SendEmailFromFieldID',
291
                    _t(
292
                        'SilverStripe\\UserForms\\Model\\UserDefinedForm.ORSELECTAFIELDTOUSEASFROM',
293
                        '.. or select a field to use as reply to address'
294
                    ),
295
                    $validEmailFromFields->map('ID', 'Title')
0 ignored issues
show
Bug introduced by
$validEmailFromFields->map('ID', 'Title') of type SilverStripe\ORM\Map is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

295
                    /** @scrutinizer ignore-type */ $validEmailFromFields->map('ID', 'Title')
Loading history...
296
                )->setEmptyString(' ')
297
            )
298
                ->setTitle(_t(
299
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.REPLYADDRESS',
300
                    'Email for reply to'
301
                ))
302
                ->setDescription(_t(
303
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.REPLYADDRESS_DESCRIPTION',
304
                    'The email address which the recipient is able to \'reply\' to.'
305
                ))
306
        ]);
307
308
        $fields->fieldByName('Root.EmailDetails')->setTitle(_t(__CLASS__.'.EMAILDETAILSTAB', 'Email Details'));
309
310
        // Only show the preview link if the recipient has been saved.
311
        if (!empty($this->EmailTemplate)) {
0 ignored issues
show
Bug Best Practice introduced by
The property EmailTemplate does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
312
            $pageEditController = singleton(CMSPageEditController::class);
313
            $pageEditController
314
                ->getRequest()
315
                ->setSession(Controller::curr()->getRequest()->getSession());
316
317
            $preview = sprintf(
318
                '<p><a href="%s" target="_blank" class="btn btn-outline-secondary">%s</a></p><em>%s</em>',
319
                Controller::join_links(
320
                    $pageEditController->getEditForm()->FormAction(),
321
                    "field/EmailRecipients/item/{$this->ID}/preview"
322
                ),
323
                _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.PREVIEW_EMAIL', 'Preview email'),
324
                _t(
325
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.PREVIEW_EMAIL_DESCRIPTION',
326
                    'Note: Unsaved changes will not appear in the preview.'
327
                )
328
            );
329
        } else {
330
            $preview = sprintf(
331
                '<em>%s</em>',
332
                _t(
333
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.PREVIEW_EMAIL_UNAVAILABLE',
334
                    'You can preview this email once you have saved the Recipient.'
335
                )
336
            );
337
        }
338
339
        // Email templates
340
        $fields->addFieldsToTab('Root.EmailContent', [
341
            CheckboxField::create(
342
                'HideFormData',
343
                _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.HIDEFORMDATA', 'Hide form data from email?')
344
            ),
345
            CheckboxField::create(
346
                'SendPlain',
347
                _t(
348
                    'SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDPLAIN',
349
                    'Send email as plain text? (HTML will be stripped)'
350
                )
351
            ),
352
            HTMLEditorField::create(
353
                'EmailBodyHtml',
354
                _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILBODYHTML', 'Body')
355
            )
356
                ->addExtraClass('toggle-html-only'),
357
            TextareaField::create(
358
                'EmailBody',
359
                _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILBODY', 'Body')
360
            )
361
                ->addExtraClass('toggle-plain-only'),
362
            LiteralField::create('EmailPreview', $preview)
363
        ]);
364
365
        $templates = $this->getEmailTemplateDropdownValues();
366
367
        if ($templates) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $templates of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
368
            $fields->insertBefore(
369
                DropdownField::create(
370
                    'EmailTemplate',
371
                    _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.EMAILTEMPLATE', 'Email template'),
372
                    $templates
373
                )->addExtraClass('toggle-html-only'),
374
                'EmailBodyHtml'
375
            );
376
        }
377
378
        $fields->fieldByName('Root.EmailContent')->setTitle(_t(__CLASS__.'.EMAILCONTENTTAB', 'Email Content'));
379
380
        // Custom rules for sending this field
381
        $grid = GridField::create(
382
            'CustomRules',
383
            _t('SilverStripe\\UserForms\\Model\\EditableFormField.CUSTOMRULES', 'Custom Rules'),
384
            $this->CustomRules(),
0 ignored issues
show
Bug introduced by
The method CustomRules() does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. 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

384
            $this->/** @scrutinizer ignore-call */ 
385
                   CustomRules(),
Loading history...
385
            $this->getRulesConfig()
0 ignored issues
show
Bug introduced by
$this->getRulesConfig() of type SilverStripe\Forms\GridField\GridFieldConfig is incompatible with the type array expected by parameter $args of SilverStripe\View\ViewableData::create(). ( Ignorable by Annotation )

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

385
            /** @scrutinizer ignore-type */ $this->getRulesConfig()
Loading history...
386
        );
387
        $grid->setDescription(_t(
388
            'SilverStripe\\UserForms\\Model\\UserDefinedForm.RulesDescription',
389
            'Emails will only be sent to the recipient if the custom rules are met. If no rules are defined, this receipient will receive notifications for every submission.'
390
        ));
391
        $fields->addFieldsToTab('Root.CustomRules', [
392
            DropdownField::create(
393
                'CustomRulesCondition',
394
                _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIF', 'Send condition'),
395
                [
396
                    'Or' => _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFOR', 'Any conditions are true'),
397
                    'And' => _t('SilverStripe\\UserForms\\Model\\UserDefinedForm.SENDIFAND', 'All conditions are true')
398
                ]
399
            ),
400
            $grid
401
        ]);
402
403
        $fields->fieldByName('Root.CustomRules')->setTitle(_t(__CLASS__.'.CUSTOMRULESTAB', 'Custom Rules'));
404
405
        $this->extend('updateCMSFields', $fields);
406
        return $fields;
407
    }
408
409
    /**
410
     * Return whether a user can create an object of this type
411
     *
412
     * @param Member $member
0 ignored issues
show
Bug introduced by
The type SilverStripe\UserForms\Model\Recipient\Member was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
413
     * @param array $context Virtual parameter to allow context to be passed in to check
414
     * @return bool
415
     */
416
    public function canCreate($member = null, $context = [])
417
    {
418
        // Check parent page
419
        $parent = $this->getCanCreateContext(func_get_args());
420
        if ($parent) {
0 ignored issues
show
introduced by
The condition $parent can never be true.
Loading history...
421
            return $parent->canEdit($member);
422
        }
423
424
        // Fall back to secure admin permissions
425
        return parent::canCreate($member);
426
    }
427
428
    /**
429
     * Helper method to check the parent for this object
430
     *
431
     * @param array $args List of arguments passed to canCreate
432
     * @return SiteTree Parent page instance
433
     */
434
    protected function getCanCreateContext($args)
435
    {
436
        // Inspect second parameter to canCreate for a 'Parent' context
437
        if (isset($args[1][Form::class])) {
438
            return $args[1][Form::class];
439
        }
440
        // Hack in currently edited page if context is missing
441
        if (Controller::has_curr() && Controller::curr() instanceof CMSMain) {
442
            return Controller::curr()->currentPage();
443
        }
444
445
        // No page being edited
446
        return null;
447
    }
448
449
    public function canView($member = null)
450
    {
451
        if ($form = $this->getFormParent()) {
452
            return $form->canView($member);
453
        }
454
        return parent::canView($member);
455
    }
456
457
    public function canEdit($member = null)
458
    {
459
        if ($form = $this->getFormParent()) {
460
            return $form->canEdit($member);
461
        }
462
463
        return parent::canEdit($member);
464
    }
465
466
    /**
467
     * @param Member
468
     *
469
     * @return boolean
470
     */
471
    public function canDelete($member = null)
472
    {
473
        return $this->canEdit($member);
474
    }
475
476
    /**
477
     * Determine if this recipient may receive notifications for this submission
478
     *
479
     * @param array $data
480
     * @param Form $form
481
     * @return bool
482
     */
483
    public function canSend($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed. ( Ignorable by Annotation )

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

483
    public function canSend($data, /** @scrutinizer ignore-unused */ $form)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
484
    {
485
        // Skip if no rules configured
486
        $customRules = $this->CustomRules();
487
        if (!$customRules->count()) {
488
            return true;
489
        }
490
491
        // Check all rules
492
        $isAnd = $this->CustomRulesCondition === 'And';
0 ignored issues
show
Bug Best Practice introduced by
The property CustomRulesCondition does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
493
        foreach ($customRules as $customRule) {
494
            /** @var EmailRecipientCondition  $customRule */
495
            $matches = $customRule->matches($data);
496
            if ($isAnd && !$matches) {
497
                return false;
498
            }
499
            if (!$isAnd && $matches) {
500
                return true;
501
            }
502
        }
503
504
        // Once all rules are checked
505
        return $isAnd;
506
    }
507
508
    /**
509
     * Make sure the email template saved against the recipient exists on the file system.
510
     *
511
     * @param string
512
     *
513
     * @return boolean
514
     */
515
    public function emailTemplateExists($template = '')
516
    {
517
        $t = ($template ? $template : $this->EmailTemplate);
0 ignored issues
show
Bug Best Practice introduced by
The property EmailTemplate does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
518
519
        return array_key_exists($t, (array) $this->getEmailTemplateDropdownValues());
520
    }
521
522
    /**
523
     * Get the email body for the current email format
524
     *
525
     * @return string
526
     */
527
    public function getEmailBodyContent()
528
    {
529
        if ($this->SendPlain) {
0 ignored issues
show
Bug Best Practice introduced by
The property SendPlain does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
530
            return DBField::create_field('HTMLText', $this->EmailBody)->Plain();
0 ignored issues
show
Bug Best Practice introduced by
The property EmailBody does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
531
        }
532
        return DBField::create_field('HTMLText', $this->EmailBodyHtml);
0 ignored issues
show
Bug Best Practice introduced by
The property EmailBodyHtml does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
533
    }
534
535
    /**
536
     * Gets a list of email templates suitable for populating the email template dropdown.
537
     *
538
     * @return array
539
     */
540
    public function getEmailTemplateDropdownValues()
541
    {
542
        $templates = [];
543
544
        $finder = new FileFinder();
545
        $finder->setOption('name_regex', '/^.*\.ss$/');
546
547
        $parent = $this->getFormParent();
548
549
        if (!$parent) {
0 ignored issues
show
introduced by
The condition ! $parent can never be false.
Loading history...
550
            return [];
551
        }
552
553
        $emailTemplateDirectory = $parent->config()->get('email_template_directory');
554
        $templateDirectory = ModuleResourceLoader::resourcePath($emailTemplateDirectory);
555
556
        if (!$templateDirectory) {
557
            return [];
558
        }
559
560
        $found = $finder->find(BASE_PATH . DIRECTORY_SEPARATOR . $templateDirectory);
561
562
        foreach ($found as $key => $value) {
563
            $template = pathinfo($value);
564
            $absoluteFilename = $template['dirname'] . DIRECTORY_SEPARATOR . $template['filename'];
565
566
            // Optionally remove vendor/ path prefixes
567
            $resource = ModuleResourceLoader::singleton()->resolveResource($emailTemplateDirectory);
568
            if ($resource instanceof ModuleResource && $resource->getModule()) {
569
                $prefixToStrip = $resource->getModule()->getPath();
570
            } else {
571
                $prefixToStrip = BASE_PATH;
572
            }
573
            $templatePath = substr($absoluteFilename, strlen($prefixToStrip) + 1);
574
575
            // Optionally remove "templates/" prefixes
576
            if (substr($templatePath, 0, 10)) {
577
                $templatePath = substr($templatePath, 10);
578
            }
579
580
            $templates[$templatePath] = $template['filename'];
581
        }
582
583
        return $templates;
584
    }
585
586
    /**
587
     * Validate that valid email addresses are being used
588
     *
589
     * @return ValidationResult
0 ignored issues
show
Bug introduced by
The type SilverStripe\UserForms\M...ipient\ValidationResult was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
590
     */
591
    public function validate()
592
    {
593
        $result = parent::validate();
594
        $checkEmail = [
595
            'EmailAddress' => 'EMAILADDRESSINVALID',
596
            'EmailFrom' => 'EMAILFROMINVALID',
597
            'EmailReplyTo' => 'EMAILREPLYTOINVALID',
598
        ];
599
        foreach ($checkEmail as $check => $translation) {
600
            if ($this->$check) {
601
                //may be a comma separated list of emails
602
                $addresses = explode(',', $this->$check);
603
                foreach ($addresses as $address) {
604
                    $trimAddress = trim($address);
605
                    if ($trimAddress && !Email::is_valid_address($trimAddress)) {
606
                        $error = _t(
607
                            __CLASS__.".$translation",
608
                            "Invalid email address $trimAddress"
609
                        );
610
                        $result->addError($error . " ($trimAddress)");
611
                    }
612
                }
613
            }
614
        }
615
616
        // if there is no from address and no fallback, you'll have errors if this isn't defined
617
        if (!$this->EmailFrom && empty(Email::getSendAllEmailsFrom()) && empty(Email::config()->get('admin_email'))) {
0 ignored issues
show
Bug Best Practice introduced by
The property EmailFrom does not exist on SilverStripe\UserForms\M...ecipient\EmailRecipient. Since you implemented __get, consider adding a @property annotation.
Loading history...
618
            $result->addError(_t(__CLASS__.".EMAILFROMREQUIRED", '"Email From" address is required'));
619
        }
620
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type SilverStripe\ORM\ValidationResult which is incompatible with the documented return type SilverStripe\UserForms\M...ipient\ValidationResult.
Loading history...
621
    }
622
}
623