smarty_function_ddsForm()   D
last analyzed

Complexity

Conditions 39
Paths 1

Size

Total Lines 117
Code Lines 90

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 1560

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 39
eloc 90
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 117
ccs 0
cts 99
cp 0
crap 1560
rs 4.1666

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
/**
4
 * Manage an Daedalus table form. This allows you to use a form for a single
5
 * Daedalus table, either filling in some or all of the data.
6
 *
7
 * Usage:
8
 * a) creating a new form of type 'abc' which will set a $form and $submitted
9
 * parameter for use in the template
10
 *
11
 * ```
12
 *    {ddsForm classType='abc'}
13
 *    {if ($submitted)}
14
 *        // do something
15
 *    {else}
16
 *        {$form->run()}
17
 *    {/if}
18
 * ```
19
 * You can change the form and submitted parameter names using assignForm
20
 * and assignSubmitted respectively.
21
 *
22
 * b) editing an existing form of type 'abc' and UUID of $uuid
23
 *
24
 * ```
25
 *    {ddsForm classType='abc' uuid=$uuid}
26
 * ```
27
 *
28
 * c) changing the form id & the name of the assigned form and submitted parameters
29
 *
30
 * ```
31
 *    {ddsForm classType='abc' formId='formId' assignForm='myForm' assignSubmitted='myFormSubmitted'}
32
 *    {if ($myFormSubmitted)}
33
 *        // do something
34
 *    {else}
35
 *        {$myForm->run()}
36
 *    {/if}
37
 * ```
38
 *
39
 * d) ReadOnly: You can set whether or not the form can be edited by passing in readOnly. This
40
 * defaults to false.
41
 * ```
42
 *    {ddsForm classType='abc' readOnly=true}
43
 * ````
44
 *
45
 * e) Selecting Fields: You can set the fields you want to show on the form and in what order by setting
46
 * the 'fields' parameter to either [fieldName,...] or ['fieldName'=>'label',...] (or
47
 * any combination) to either get a label derived from the fieldName (underscore
48
 * replaced by spaces and all words capitalised) or to set the label
49
 * ```
50
 *    {ddsForm classType='abc' fields=['field1', 'field2', 'field3'=>'field 3 label'...]}
51
 * ```
52
 *
53
 * f) Filtering Maps: some fields get their data from other tables as a set of key=>value pairs
54
 * or map - for example, dynamic select lists. There are occasions when you need to filter those
55
 * lists say by project or client or combination of map fields.
56
 *
57
 * In these cases you can pass in a *mapFilters* to the form which will be applied to the
58
 * other table to return a subset of values. mapFilters are a set of srcField => [mappedField=>value,...].
59
 * Each srcField is on this dds table and the mappedFields are fields on the destination map table.
60
 * Filters are all applied as mapField=value and are all ANDed together.
61
 * ```
62
 *    {ddsForm classType='abc' mapFilters=[
63
 *       'formField1'=>[mapField1=>value1, mapField2=>value2,...],
64
 *       ...
65
 *    ]}
66
 * ```
67
 *
68
 * g) Formatting Maps: @see f) above. Each Daedalus table has a default map field that is
69
 * returned for e.g. select lists. There are times when you may want to change which field or
70
 * fields are returned and specify a format for them. In this case you can pass in a
71
 * *mapFields* parameter. These are a set of formField=>[mappedField,..., 'format'=>[x]] where
72
 * each field required is listed in order, and the format key is used to define how you want
73
 * the returned values to be formatted. This can have keys of prefix, postfix and concat each
74
 * taking a string. e.g. myField=>[field1, field2, 'format'=>['concat'=>': ']]
75
 * ```
76
 *    {ddsForm classType='abc' mapFilters=[
77
 *       'formField1'=>[mapField1=>value1, mapField2=>value2,...],
78
 *       ...
79
 *    ]}
80
 * ```
81
 *
82
 * @param $params
83
 *   Required parameters
84
 *   -------------------
85
 *     'classType'  => the class type of the form in Phoebe
86
 *
87
 *   Optional Parameters
88
 *   -------------------
89
 *     'uuid' => the form UUID if this is not a new form
90
 *     'id' => an HTML id for the form. If not set the UUID is used, or failing
91
 *       that the form type.
92
 *     'label' => the main title of the form if not the default
93
 *     'cssClass' => set additional css classes for the form
94
 *     'fields' => the set of fields (and order) you want displaying on the form
95
 *       or leave out to get all the available fields
96
 *     'mapFilters' => @see f) above - a set of ['formField' => ['tableField'=>'value',...]]
97
 *       to filter dynamic maps extracted from other tables
98
 *     'mapFields' => @see g) above - a set of formField=>['tableField's] that you want
99
 *       returned in a dynamic map if not the default mapped field. You can add a 'format'
100
 *       key with sub array ['concat', 'prefix', 'postfix'] to format how the
101
 *       fields will be combined into the map.
102
 *     'fieldDefaults' => set default values for fields as
103
 *       ['field'=>'default']
104
 *     'fieldProperties' => set provided properties for the form fields as
105
 *       ['field'=>['property'=>'value']]
106
 *     'assignForm' => set this to change the name of the assigned form parameter
107
 *       (default 'form')
108
 *     'assignSubmitted' => set this to use a different submitted parameter
109
 *       (default 'submitted')
110
 *     'assignSaved' => set this to use a different saved parameter
111
 *       (default 'saved')
112
 *     'assignErrors' => set this to use a different form errors parameter
113
 *       (default 'errors')
114
 *     'submitLabel' => a submit label or 'Save'
115
 *     'buttons' => an array of buttons as [
116
 *         ['name'=>'abc', 'label'=>'Abc', 'class'=>'additional classes'],...]
117
 *       ]. These will override the default submit button.
118
 *     'action' => URL to go to if you don't want to handle the form in the same page
119
 *     'readOnly' => set to true if you want the form to be read only
120
 *     'printOnly' => set to true if you want the form to be printable
121
 *     'dataSources' => these allow you to set particular fields on a form so that their values
122
 *       are fixed by the system and not editable by the user. The fields do not have to
123
 *       be displayed to the user in order for them to be set. Set these to an array of
124
 *       'formField'=>value pairs.
125
 *     'enableAjaxValidation' => boolean  whether or not to use AJAX validation. If you set this
126
 *       you need to check $errors to know if a submission was successful or not
127
 *     'enableAjaxSubmission' => boolean  whether or not to use AJAX submission
128
 *     'ajaxValidationUrl' => set to the URL for AJAX validation if not the default
129
 *     'returnUrl' => set the URL to redirect to after saving if required
130
 *     'name' => the name of the form if not the default
131
 *     'debug' => if true output some debug information about the form behaviour
132
 * @param $template  the smarty template
0 ignored issues
show
Bug introduced by
The type the 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...
133
 *
134
 * @return the following parameters will be set on return. The
135
 *   'form' - the form object (this will be the value of assignForm if set)
136
 *   'submitted' - if the form was submitted (this will be the value of assignSubmitted if set)
137
 *   'errors' - whether or not there were any submission errors (this will be the value of assignErrors if set)
138
 *   'uuid' - the UUID of the created object if successful or null otherwise
139
 *   'changeLogUuid' - if the item was submitted, and the corresponding dds table has
140
 *     a change log, then the change log entry uuid will be returned here.
141
 */
142
function smarty_function_ddsForm($params, $template)
143
{
144
	// need to ensure we don't fetch items from the database more than necessary
145
	// or handle the form more than once otherwise we can create additional entries
146
	static $handledObjects = [];
147
	static $forms = [];
148
149
	$phoebeType = 'daedalus';
150
151
	// process the parameters
152
	if (!isset($params['classType']))
153
		throw new \RuntimeException("You must pass in the form's classType otherwise we don't which form it is. You passed in: ".print_r($params,true));
0 ignored issues
show
Bug introduced by
Are you sure print_r($params, true) of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

153
		throw new \RuntimeException("You must pass in the form's classType otherwise we don't which form it is. You passed in: "./** @scrutinizer ignore-type */ print_r($params,true));
Loading history...
154
	$classType = $params['classType'];
155
	$cssClass = isset($params['cssClass']) ? $params['cssClass'] : null;
156
	$label = isset($params['label']) ? $params['label'] : null;
157
	$id = !empty($params['id']) ? $params['id'] : null;
158
	$saveOptions = !empty($params['submitLabel']) ? ['label'=>$params['submitLabel']] : [];
159
	$buttons = !empty($params['buttons']) ? $params['buttons'] : null;
160
	$action = !empty($params['action']) ? $params['action'] : null;
161
	$assignForm = !empty($params['assignForm']) ? $params['assignForm'] : 'form';
162
	$assignSaved = !empty($params['assignSaved']) ? $params['assignSaved'] : 'saved';
163
	$assignErrors = !empty($params['assignErrors']) ? $params['assignErrors'] : 'errors';
164
	$assignSubmitted = !empty($params['assignSubmitted']) ? $params['assignSubmitted'] : 'submitted';
165
	$readOnly = isset($params['readOnly']) ? (bool)$params['readOnly'] : false;
166
	$printOnly = isset($params['printOnly']) ? (bool)$params['printOnly'] : false;
167
	$uuid = !empty($params['uuid']) ? $params['uuid'] : null;
168
	$dataSources = !empty($params['dataSources']) ? $params['dataSources'] : null;
169
	$enableAjaxValidation = isset($params['enableAjaxValidation']) ? (bool)$params['enableAjaxValidation'] : true;
170
	$enableAjaxSubmission = isset($params['enableAjaxSubmission']) ? (bool)$params['enableAjaxSubmission'] : false;
171
	$ajaxValidationUrl = !empty($params['ajaxValidationUrl']) ? $params['ajaxValidationUrl'] : '/phoebe/database/index/validate-form';
172
	$returnUrl = !empty($params['returnUrl']) ? $params['returnUrl'] : null;
173
	$formName = !empty($params['name']) ? $params['name'] : null;
174
	$fields = !empty($params['fields']) ? $params['fields'] : [];
175
	$mapFilters = !empty($params['mapFilters']) ? $params['mapFilters'] : [];
176
	$mapFields = !empty($params['mapFields']) ? $params['mapFields'] : [];
177
	$fieldDefaults = !empty($params['fieldDefaults']) ? $params['fieldDefaults'] : [];
178
	$fieldProperties = !empty($params['fieldProperties']) ? $params['fieldProperties'] : [];
179
	// prefix invalid (HTML5) ids with a letter
180
	$id = ($id ? $id : ($uuid ? $uuid : null));
181
	if ($id) {
182
		if (is_numeric($id[0]) || $id[0] == '-' || $id[0] == '_')
183
			$id = 'z' . $id;
184
	}
185
	$changeLogUuids = [];
186
187
	// get form definition
188
	$phoebe = neon('phoebe')->getIPhoebeType($phoebeType);
189
	$formKey = $classType.$uuid.$id;
190
	if (array_key_exists($formKey, $forms)) {
191
		$form = $forms[$formKey];
192
	} else {
193
		// creating a form is expensive so do it only once per object
194
		$form = neon('phoebe')->getForm($phoebeType, $classType, [
195
			'id' => $id,
196
			'name' => $formName,
197
			'label' => $label,
198
			'cssClass' => $cssClass,
199
			'save'=>$saveOptions,
200
			'buttons' => $buttons,
201
			'readOnly' => $readOnly,
202
			'printOnly' => $printOnly,
203
			'action'=>$action,
204
			'enableAjaxValidation' => $enableAjaxValidation,
205
			'enableAjaxSubmission' => $enableAjaxSubmission,
206
			'ajaxValidationUrl' => url([$ajaxValidationUrl, 'classType' => $classType, 'name'=>$formName]),
207
			'uuid' => $uuid,
208
			'dataSources' => $dataSources,
209
			'returnUrl' => $returnUrl,
210
			'fields' => $fields,
211
			'mapFilters' => $mapFilters,
212
			'mapFields' => $mapFields,
213
			'fieldDefaults' => $fieldDefaults,
214
			'fieldProperties' => $fieldProperties
215
		]);
216
		$forms[$formKey] = $form;
217
	}
218
	$saveFormResults = [
219
		$assignSaved => false,
220
		$assignErrors => null,
221
		$assignSubmitted => false,
222
		'uuid' => $uuid,
223
		'changeLogUuids' => $changeLogUuids
224
	];
225
226
	// is this a submitted form ready for saving and we haven't already handled it
227
	if (!$readOnly && $form->hasRequestData()) {
228
		if (!array_key_exists($uuid, $handledObjects)) {
229
			// pass in any metaInfo that we know about here
230
			$metaInfo = [
231
				'uuid' => $uuid,
232
				'dataSources' => $dataSources,
233
				'returnUrl' => $returnUrl
234
			];
235
			$result = neon('phoebe')->saveForm($phoebeType, $classType, $form, $formName, $metaInfo, $uuid, $changeLogUuids);
236
			if ($result === true && $uuid) {
237
				$object = $phoebe->getObject($uuid);
238
				$form->loadFromDb($object->data);
239
				$saveFormResults['uuid'] = $uuid;
240
				$saveFormResults[$assignSaved] = true;
241
				$saveFormResults['changeLogUuids'] = $changeLogUuids;
242
			} else {
243
				$saveFormResults[$assignErrors] = json_encode($result);
244
			}
245
			$saveFormResults[$assignSubmitted] = true;
246
			$handledObjects[$uuid] = $saveFormResults;
247
		} else {
248
			$saveFormResults = $handledObjects[$uuid];
249
		}
250
	}
251
252
	// assign all of the save results to the template
253
	foreach ($saveFormResults as $k=>$v)
254
		$template->assign($k,$v);
255
256
257
	// assign the resulting form
258
	$template->assign($assignForm, $form);
259
}
260