Passed
Push — master ( c669ef...8bfab5 )
by Robbie
03:20
created

requireDefaultRecords()   D

Complexity

Conditions 10
Paths 22

Size

Total Lines 45
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 24
nc 22
nop 0
dl 0
loc 45
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\UserForms\Extension;
4
5
use SilverStripe\Control\Director;
6
use SilverStripe\Core\Injector\Injector;
7
use SilverStripe\ORM\DataExtension;
8
use SilverStripe\ORM\DataList;
9
use SilverStripe\ORM\DataObject;
10
use SilverStripe\ORM\ValidationException;
11
use SilverStripe\UserForms\Model\EditableFormField;
12
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
13
use SilverStripe\UserForms\Model\Submission\SubmittedForm;
14
use SilverStripe\UserForms\Model\UserDefinedForm;
15
use SilverStripe\UserForms\UserForm;
16
17
/**
18
 * This extension provides a hook that runs during a dev/build which will check for existing data in various
19
 * polymorphic relationship fields for userforms models, and ensure that the data is correct.
20
 *
21
 * Various `Parent` relationships in silverstripe/userforms for SilverStripe 3 were mapped directly to UserDefinedForm
22
 * instances, and were made polymorphic in SilverStripe 4 (which also requires a class name). This means that a
23
 * certain amount of manual checking is required to ensure that upgrades are performed smoothly.
24
 *
25
 * @internal This API is likely to be removed in later major versions of silverstripe/userforms
26
 */
27
class UpgradePolymorphicExtension extends DataExtension
28
{
29
    /**
30
     * A list of userforms classes that have had polymorphic relationships added in SilverStripe 4, and the fields
31
     * on them that are polymorphic
32
     *
33
     * @var array
34
     */
35
    protected $targets = [
36
        EditableFormField::class => ['ParentClass'],
37
        EmailRecipient::class => ['FormClass'],
38
        SubmittedForm::class => ['ParentClass'],
39
    ];
40
41
    /**
42
     * The default class name that will be used to replace values with
43
     *
44
     * @var string
45
     */
46
    protected $defaultReplacement = UserDefinedForm::class;
47
48
    public function requireDefaultRecords()
49
    {
50
        if (!UserDefinedForm::config()->get('upgrade_on_build')) {
51
            return;
52
        }
53
54
        $updated = 0;
55
        foreach ($this->targets as $className => $fieldNames) {
56
            foreach ($fieldNames as $fieldName) {
57
                /** @var DataList $list */
58
                $list = $className::get();
59
60
                foreach ($list as $entry) {
61
                    /** @var DataObject $relationshipObject */
62
                    $relationshipObject = Injector::inst()->get($entry->$fieldName);
63
                    if (!$relationshipObject) {
64
                        continue;
65
                    }
66
67
                    // If the defined data class doesn't have the UserForm trait applied, it's probably wrong. Re-map
68
                    // it to a default value that does
69
                    $classTraits = class_uses($relationshipObject);
70
                    if (in_array(UserForm::class, $classTraits)) {
71
                        continue;
72
                    }
73
74
                    $entry->$fieldName = $this->defaultReplacement;
75
                    try {
76
                        $entry->write();
77
                        $updated++;
78
                    } catch (ValidationException $ex) {
79
                        // no-op, allow the rest of dev/build to continue. There may be an error indicating that the
80
                        // object's class doesn't exist, which can be fixed by {@link DatabaseAdmin::doBuild} and this
81
                        // logic will work the next time dev/build is run.
82
                    }
83
                }
84
            }
85
        }
86
87
        if ($updated) {
88
            $message = "Corrected {$updated} default polymorphic class names to {$this->defaultReplacement}";
89
            if (Director::is_cli()) {
90
                echo sprintf(" * %s\n", $message);
91
            } else {
92
                echo sprintf("<li>%s</li>\n", $message);
93
            }
94
        }
95
    }
96
}
97