TabulatorScaffolder::getFieldList()   F
last analyzed

Complexity

Conditions 29
Paths 1184

Size

Total Lines 100
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 63
c 1
b 0
f 0
dl 0
loc 100
rs 0
cc 29
nc 1184
nop 0

How to fix   Long Method    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 LeKoala\Tabulator;
4
5
use SilverStripe\Forms\Tab;
6
use SilverStripe\Forms\TabSet;
7
use SilverStripe\Forms\FieldList;
8
use SilverStripe\Forms\FormScaffolder;
9
use SilverStripe\Core\Injector\Injector;
10
use SilverStripe\ORM\DataObject;
11
12
/**
13
 * Helps to scaffold fields with TabulatorGrids instead of GridFields
14
 */
15
class TabulatorScaffolder extends FormScaffolder
16
{
17
    public static function scaffoldFormFields(DataObject $obj, array $_params = []): FieldList
18
    {
19
        $params = array_merge(
20
            [
21
                'tabbed' => false,
22
                'includeRelations' => false,
23
                'restrictFields' => false,
24
                'fieldClasses' => false,
25
                'ajaxSafe' => false
26
            ],
27
            $_params
28
        );
29
30
        $fs = new self($obj);
31
        $fs->tabbed = $params['tabbed'];
32
        $fs->includeRelations = $params['includeRelations'];
33
        $fs->restrictFields = $params['restrictFields'];
34
        $fs->fieldClasses = $params['fieldClasses'];
35
        $fs->ajaxSafe = $params['ajaxSafe'];
36
37
        return $fs->getFieldList();
38
    }
39
40
    /**
41
     * Gets the form fields as defined through the metadata
42
     * on {@link $obj} and the custom parameters passed to FormScaffolder.
43
     * Depending on those parameters, the fields can be used in ajax-context,
44
     * contain {@link TabSet}s etc.
45
     */
46
    public function getFieldList(): FieldList
47
    {
48
        $fields = new FieldList();
49
50
        // tabbed or untabbed
51
        if ($this->tabbed) {
52
            $fields->push(new TabSet("Root", $mainTab = new Tab("Main")));
53
            $mainTab->setTitle(_t(__CLASS__ . '.TABMAIN', 'Main'));
54
        }
55
56
        // Add logical fields directly specified in db config
57
        foreach ($this->obj->config()->get('db') as $fieldName => $fieldType) {
58
            // Skip restricted fields
59
            if ($this->restrictFields && !in_array($fieldName, $this->restrictFields)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->restrictFields 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...
60
                continue;
61
            }
62
63
            // @todo Pass localized title
64
            if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->fieldClasses 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...
65
                $fieldClass = $this->fieldClasses[$fieldName];
66
                $fieldObject = new $fieldClass($fieldName);
67
            } else {
68
                $fieldObject = $this
69
                    ->obj
70
                    ->dbObject($fieldName)
71
                    ->scaffoldFormField(null, $this->getParamsArray());
72
            }
73
            // Allow fields to opt-out of scaffolding
74
            if (!$fieldObject) {
75
                continue;
76
            }
77
            $fieldObject->setTitle($this->obj->fieldLabel($fieldName));
78
            if ($this->tabbed) {
79
                $fields->addFieldToTab("Root.Main", $fieldObject);
80
            } else {
81
                $fields->push($fieldObject);
82
            }
83
        }
84
85
        // add has_one relation fields
86
        if ($this->obj->hasOne()) {
87
            foreach ($this->obj->hasOne() as $relationship => $component) {
88
                if ($this->restrictFields && !in_array($relationship, $this->restrictFields)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->restrictFields 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...
89
                    continue;
90
                }
91
                $fieldName = $component === DataObject::class
92
                    ? $relationship // Polymorphic has_one field is composite, so don't refer to ID subfield
93
                    : "{$relationship}ID";
94
                if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->fieldClasses 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...
95
                    $fieldClass = $this->fieldClasses[$fieldName];
96
                    $hasOneField = new $fieldClass($fieldName);
97
                } else {
98
                    $hasOneField = $this->obj->dbObject($fieldName)->scaffoldFormField(null, $this->getParamsArray());
99
                }
100
                if (empty($hasOneField)) {
101
                    continue; // Allow fields to opt out of scaffolding
102
                }
103
                $hasOneField->setTitle($this->obj->fieldLabel($relationship));
104
                if ($this->tabbed) {
105
                    $fields->addFieldToTab("Root.Main", $hasOneField);
106
                } else {
107
                    $fields->push($hasOneField);
108
                }
109
            }
110
        }
111
112
        // only add relational fields if an ID is present
113
        if ($this->obj->ID) {
114
            // add has_many relation fields
115
            $includeHasMany = $this->obj->hasMany() && ($this->includeRelations === true || isset($this->includeRelations['has_many']));
116
117
            if ($includeHasMany) {
118
                foreach ($this->obj->hasMany() as $relationship => $component) {
119
                    static::addDefaultRelationshipFields(
120
                        $fields,
121
                        $relationship,
122
                        (isset($this->fieldClasses[$relationship]))
123
                            ? $this->fieldClasses[$relationship] : null,
124
                        $this->tabbed,
125
                        $this->obj
126
                    );
127
                }
128
            }
129
130
            $includeManyMany = $this->obj->manyMany() && ($this->includeRelations === true || isset($this->includeRelations['many_many']));
131
            if ($includeManyMany) {
132
                foreach ($this->obj->manyMany() as $relationship => $component) {
133
                    static::addDefaultRelationshipFields(
134
                        $fields,
135
                        $relationship,
136
                        (isset($this->fieldClasses[$relationship]))
137
                            ? $this->fieldClasses[$relationship] : null,
138
                        $this->tabbed,
139
                        $this->obj
140
                    );
141
                }
142
            }
143
        }
144
145
        return $fields;
146
    }
147
148
    /**
149
     * Adds the default relation fields for the relationship provided.
150
     *
151
     * @param FieldList $fields Reference to the @FieldList to add fields to.
152
     * @param string $relationship The relationship identifier.
153
     * @param mixed $overrideFieldClass Specify the field class to use here or leave as null to use default.
154
     * @param bool $tabbed Whether this relationship has it's own tab or not.
155
     * @param DataObject $dataObject The @DataObject that has the relation.
156
     */
157
    public static function addDefaultRelationshipFields(
158
        FieldList &$fields,
159
        $relationship,
160
        $overrideFieldClass,
161
        $tabbed,
162
        DataObject $dataObject
163
    ) {
164
        if ($tabbed) {
165
            $fields->findOrMakeTab(
166
                "Root.$relationship",
167
                $dataObject->fieldLabel($relationship)
168
            );
169
        }
170
171
        $fieldClass = $overrideFieldClass ?: TabulatorGrid::class;
172
173
        /** @var TabulatorGrid $grid */
174
        $grid = Injector::inst()->create(
175
            $fieldClass,
176
            $relationship,
177
            $dataObject->fieldLabel($relationship),
178
            $dataObject->$relationship(),
179
        );
180
        $grid->setLazyInit(true);
181
        if ($tabbed) {
182
            $fields->addFieldToTab("Root.$relationship", $grid);
183
        } else {
184
            $fields->push($grid);
185
        }
186
    }
187
}
188