|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @link http://www.newicon.net/neon |
|
4
|
|
|
* @copyright Copyright (c) 2018- Newicon Ltd |
|
5
|
|
|
* @license http://www.newicon.net/neon/license/ |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
namespace neon\phoebe\services\adapters\appforms; |
|
9
|
|
|
|
|
10
|
|
|
use neon\phoebe\services\adapters\common\PhoebeClassBase; |
|
11
|
|
|
use neon\phoebe\interfaces\forms\IPhoebeFormClass; |
|
12
|
|
|
use neon\core\helpers\Hash; |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
|
|
/** |
|
16
|
|
|
* Provides a applicationForm phoebe class |
|
17
|
|
|
*/ |
|
18
|
|
|
class PhoebeClass extends PhoebeClassBase |
|
19
|
|
|
implements IPhoebeFormClass |
|
20
|
|
|
{ |
|
21
|
|
|
use PhoebeTrait; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* @inheritdoc |
|
25
|
|
|
*/ |
|
26
|
2 |
|
public function getClassFormDefinition(array $fields=[]) |
|
27
|
|
|
{ |
|
28
|
|
|
// if there is no definition return an empty form |
|
29
|
2 |
|
if (empty($this->definition)) |
|
30
|
|
|
return []; |
|
31
|
|
|
|
|
32
|
|
|
// TODO - NJ20180426 - see if we can get Phoebe to listen to $fields |
|
33
|
|
|
|
|
34
|
|
|
// create the form |
|
35
|
2 |
|
$definition = $this->replaceDefinitionFromDds($this->definition); |
|
|
|
|
|
|
36
|
2 |
|
$this->setMemberFieldNames($definition); |
|
37
|
2 |
|
return $this->convertToForm($definition); |
|
38
|
|
|
} |
|
39
|
|
|
|
|
40
|
|
|
public function getClassBuilderDefinition() |
|
41
|
|
|
{ |
|
42
|
|
|
return $this->definition; |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* @inheritdoc |
|
47
|
|
|
*/ |
|
48
|
|
|
public function getObjectGridDefinition($additionalColumns = []) |
|
49
|
|
|
{ |
|
50
|
|
|
return parent::getObjectGridDefinition($additionalColumns); |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* @inheritdoc |
|
55
|
|
|
*/ |
|
56
|
|
|
public function editClass($changes) |
|
57
|
|
|
{ |
|
58
|
|
|
if (isset($changes['definition'])) |
|
59
|
|
|
$changes['definition'] = $this->prepareDefinition($changes['definition']); |
|
60
|
|
|
parent::editClass($changes); |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @inheritdoc |
|
65
|
|
|
*/ |
|
66
|
|
|
public function getRequiredDataSources() |
|
67
|
|
|
{ |
|
68
|
|
|
$dataSources = isset($this->definition['dataSources']) ? $this->definition['dataSources'] : []; |
|
69
|
|
|
$returnedDataSources = []; |
|
70
|
|
|
foreach ($dataSources as $dataSource) { |
|
71
|
|
|
$key = $dataSource['label']; |
|
72
|
|
|
$returnedDataSources[$key] = [ |
|
73
|
|
|
'class_type'=>$dataSource['class_type'], |
|
74
|
|
|
'key'=>$key |
|
75
|
|
|
]; |
|
76
|
|
|
} |
|
77
|
|
|
return $returnedDataSources; |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* @inheritdoc |
|
82
|
|
|
*/ |
|
83
|
|
|
public function findPhoebeKeysForClassTypesInDefinition($ddsClassTypes) |
|
84
|
|
|
{ |
|
85
|
|
|
$definition = $this->definition; |
|
86
|
|
|
$applicationDataPhoebeUuids = []; |
|
87
|
|
|
foreach ($ddsClassTypes as $ct) |
|
88
|
|
|
$applicationDataPhoebeUuids[$ct] = null; |
|
89
|
|
|
foreach ($definition['renderables'] as $k=>$r) { |
|
90
|
|
|
if ($r['type'] == 'ClassComponent' && in_array($r['class_type'], $ddsClassTypes)) { |
|
91
|
|
|
$applicationDataPhoebeUuids[$r['class_type']] = $k; |
|
92
|
|
|
} |
|
93
|
|
|
} |
|
94
|
|
|
return $applicationDataPhoebeUuids; |
|
95
|
|
|
} |
|
96
|
|
|
|
|
97
|
|
|
// ---------------------------------------- // |
|
98
|
|
|
// ---------- Additional Methods ---------- // |
|
99
|
|
|
|
|
100
|
|
|
/** |
|
101
|
|
|
* Set the definition on the model - used when merging the stored definition |
|
102
|
|
|
* with that from Daedalus |
|
103
|
|
|
* |
|
104
|
|
|
* @param array $definition |
|
105
|
|
|
*/ |
|
106
|
2 |
|
public function setDefinition($definition) |
|
107
|
|
|
{ |
|
108
|
2 |
|
$this->getModel()->definition = $definition; |
|
109
|
2 |
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* Keep the model's definition here - overrides are applied in convertToForm |
|
113
|
|
|
* level and not in the phoebe class definition |
|
114
|
|
|
* @return array |
|
115
|
|
|
*/ |
|
116
|
2 |
|
public function getDefinition() |
|
117
|
|
|
{ |
|
118
|
2 |
|
return $this->getModel()->definition; |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
2 |
|
protected function convertToForm($definition) |
|
122
|
|
|
{ |
|
123
|
2 |
|
$form = []; |
|
124
|
2 |
|
$form['name'] = $this->canonicaliseRef($definition['name']); |
|
125
|
2 |
|
$fields = $this->convertRenderablesToFields($definition['rootNode'], $definition['renderables']); |
|
126
|
2 |
|
$form['fields'] = $fields['fields']; |
|
127
|
|
|
// apply any overrides to the form |
|
128
|
2 |
|
if ($this->_overrides) |
|
|
|
|
|
|
129
|
|
|
$form = array_replace_recursive($form, $this->_overrides); |
|
130
|
2 |
|
return $form; |
|
131
|
|
|
} |
|
132
|
|
|
|
|
133
|
2 |
|
protected function convertRenderablesToFields($key, $renderables) { |
|
134
|
2 |
|
if (!isset($renderables[$key])) { |
|
135
|
|
|
dd("Key $key doesn't exist in the form definition", $renderables); |
|
136
|
|
|
throw new \RuntimeException("Key $key doesn't exist in the form definition");} |
|
137
|
2 |
|
$rend = $renderables[$key]; |
|
138
|
2 |
|
$field=[]; |
|
139
|
2 |
|
if (!empty($rend['type'])) { |
|
140
|
2 |
|
$field = []; |
|
141
|
2 |
|
switch($rend['type']) { |
|
142
|
2 |
|
case 'FormComponent': |
|
143
|
2 |
|
if (isset($rend['items'])) |
|
144
|
2 |
|
$field['fields'] = $this->addItems($rend['items'], $renderables); |
|
145
|
2 |
|
break; |
|
146
|
2 |
|
case 'ClassComponent': |
|
147
|
2 |
|
$classDefinition = isset($rend['definition']) ? $rend['definition'] : []; |
|
148
|
2 |
|
if (count($rend['items'])>0) { |
|
149
|
2 |
|
$field['fields'] = []; |
|
150
|
2 |
|
$field['label'] = ''; |
|
151
|
2 |
|
if (isset($classDefinition['showLabel']) && $classDefinition['showLabel']) |
|
152
|
2 |
|
$field['label'] = isset($classDefinition['label']) ? $classDefinition['label'] : $rend['label']; |
|
153
|
2 |
|
$field['description'] = ''; |
|
154
|
2 |
|
if (isset($classDefinition['showDescription']) && $classDefinition['showDescription']) |
|
155
|
|
|
$field['description'] = isset($classDefinition['description']) ? $classDefinition['description'] : $rend['description']; |
|
156
|
2 |
|
if ($this->isRepeater($rend)) { |
|
157
|
2 |
|
$this->addRepeaterHeader($field, $rend['definition'], $key); |
|
158
|
2 |
|
if (isset($classDefinition['showLabel']) && $classDefinition['showLabel']) |
|
159
|
2 |
|
$field['template']['label'] = isset($classDefinition['label']) ? $classDefinition['label'] : $rend['label']; |
|
160
|
2 |
|
$field['template']['fields'] = $this->addItems($rend['items'], $renderables); |
|
161
|
2 |
|
$field['template']['fields'][] = $this->createHiddenField('_renderable', $key); |
|
162
|
2 |
|
$field['template']['fields'][] = $this->createHiddenField('_classType', $rend['class_type']); |
|
163
|
2 |
|
$field['template']['fields'][] = $this->createHiddenField('_uuid'); |
|
164
|
|
|
} else { |
|
165
|
2 |
|
$field['class'] = '\\neon\\core\\form\\Form'; |
|
166
|
2 |
|
$field['name'] = $key; |
|
167
|
2 |
|
$field['dataKey'] = $field['name']; |
|
168
|
2 |
|
$field['fields'] = $this->addItems($rend['items'], $renderables); |
|
169
|
2 |
|
$field['fields'][] = $this->createHiddenField('_renderable', $key); |
|
170
|
2 |
|
$field['fields'][] = $this->createHiddenField('_classType', $rend['class_type']); |
|
171
|
2 |
|
$field['fields'][] = $this->createHiddenField('_uuid'); |
|
172
|
|
|
} |
|
173
|
|
|
} |
|
174
|
2 |
|
break; |
|
175
|
2 |
|
case 'MemberComponent': |
|
176
|
|
|
case 'ElementComponent': |
|
177
|
2 |
|
$field = $rend['definition']; |
|
178
|
|
|
// not all components have names but the form requires everything to have one |
|
179
|
2 |
|
if (empty($field['name'])) { |
|
180
|
2 |
|
$field['name'] = $this->createFieldName($field); |
|
181
|
|
|
} |
|
182
|
2 |
|
break; |
|
183
|
|
|
} |
|
184
|
|
|
} |
|
185
|
2 |
|
return $field; |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
2 |
|
protected function addItems($items, $renderables) |
|
189
|
|
|
{ |
|
190
|
2 |
|
$field = []; |
|
191
|
2 |
|
$order = 1; |
|
192
|
2 |
|
foreach ($items as $rKey) { |
|
193
|
2 |
|
$subField = $this->convertRenderablesToFields($rKey, $renderables, 1); |
|
|
|
|
|
|
194
|
2 |
|
if (isset($subField[$rKey])) |
|
195
|
2 |
|
$field[$rKey] = $subField[$rKey]; |
|
196
|
|
|
else |
|
197
|
2 |
|
$field[$rKey] = $subField; |
|
198
|
2 |
|
$field[$rKey]['order'] = $order++; |
|
199
|
|
|
} |
|
200
|
2 |
|
return $field; |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
2 |
|
protected function isRepeater($renderable) |
|
204
|
|
|
{ |
|
205
|
2 |
|
return (isset($renderable['definition']['isRepeater']) && $renderable['definition']['isRepeater'] == true); |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
2 |
|
protected function addRepeaterHeader(&$field, $repeat, $key) |
|
|
|
|
|
|
209
|
|
|
{ |
|
210
|
|
|
// set the rpeater header part |
|
211
|
2 |
|
$field['class'] = "neon\\core\\form\\FormRepeater"; |
|
212
|
2 |
|
$field['count'] = isset($repeat['defaultInstances']) ? (integer) $repeat['defaultInstances'] : 1; |
|
213
|
2 |
|
$field['countMax'] = isset($repeat['maxInstances']) ? (integer) $repeat['maxInstances'] : 0; |
|
214
|
2 |
|
$field['countMin'] = isset($repeat['minInstances']) ? (integer) $repeat['minInstances'] : 1; |
|
215
|
2 |
|
$allowChangeOfRepeats = ($field['countMin'] != $field['countMax']); |
|
216
|
2 |
|
$field['allowAdd'] = $allowChangeOfRepeats; |
|
217
|
2 |
|
$field['allowRemove'] = $allowChangeOfRepeats; |
|
218
|
|
|
|
|
219
|
|
|
// now set the template header part |
|
220
|
2 |
|
$field['template']['class'] = "neon\\core\\form\\Form"; |
|
221
|
2 |
|
} |
|
222
|
|
|
|
|
223
|
|
|
/** |
|
224
|
|
|
* Create a hidden object id field required when sending back the data |
|
225
|
|
|
* so we know what object it belongs to if set |
|
226
|
|
|
* @return array |
|
227
|
|
|
*/ |
|
228
|
2 |
|
protected function createHiddenField($name, $value=null) |
|
229
|
|
|
{ |
|
230
|
|
|
return [ |
|
231
|
2 |
|
'class' => "neon\\core\\form\\fields\\Hidden", |
|
232
|
2 |
|
'name' => $name, |
|
233
|
2 |
|
'order' => 0, |
|
234
|
2 |
|
'value' => $value |
|
235
|
|
|
]; |
|
236
|
|
|
} |
|
237
|
|
|
|
|
238
|
2 |
|
protected function createFieldName($field) |
|
239
|
|
|
{ |
|
240
|
2 |
|
$uuid = isset($field['id']) ? $field['id'] : Hash::uuid64(); |
|
241
|
2 |
|
return str_replace(['-','_'],['a','Z'], $uuid); |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
} |