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
|
|||
60 | continue; |
||
61 | } |
||
62 | |||
63 | // @todo Pass localized title |
||
64 | if ($this->fieldClasses && isset($this->fieldClasses[$fieldName])) { |
||
0 ignored issues
–
show
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 ![]() |
|||
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
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 ![]() |
|||
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
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 ![]() |
|||
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 |
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.