Test Failed
Push — master ( 827664...293942 )
by Jean-Christophe
19:02
created

FormModelViewerTrait::setFormFieldsComponent_()   B

Complexity

Conditions 10
Paths 25

Size

Total Lines 27
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
dl 0
loc 27
rs 7.6666
c 1
b 0
f 0
cc 10
nc 25
nop 2

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 Ubiquity\controllers\crud\viewers\traits;
4
5
use Ajax\semantic\html\collections\form\HtmlFormField;
6
use Ajax\semantic\html\collections\form\HtmlFormInput;
7
use Ajax\semantic\html\elements\HtmlButton;
8
use Ajax\semantic\html\elements\HtmlIconGroups;
9
use Ajax\semantic\widgets\dataform\DataForm;
10
use Ubiquity\orm\OrmUtils;
11
use Ubiquity\controllers\crud\EditMemberParams;
12
13
/**
14
 * Associated with a CRUDController class (part of ModelViewer)
15
 * Responsible of the display of the form
16
 * Ubiquity\controllers\crud\viewers\traits$FormModelViewerTrait
17
 * This class is part of Ubiquity
18
 *
19
 * @author jcheron <[email protected]>
20
 * @version 1.0.0
21
 * @property \Ajax\JsUtils $jquery
22
 */
23
trait FormModelViewerTrait {
24
25
	protected function relationMembersInForm($form, $instance, $className, $fields, $relations) {
26
		foreach ( $relations as $field => $member ) {
27
			if (array_search ( $field, $fields ) !== false) {
28
				if (OrmUtils::getAnnotationInfoMember ( $className, "#manyToOne", $member ) !== false) {
29
					$this->manyToOneFormField ( $form, $member, $className, $instance );
30
				} elseif (($annot = OrmUtils::getAnnotationInfoMember ( $className, "#oneToMany", $member )) !== false) {
31
					$this->oneToManyFormField ( $form, $member, $instance, $annot );
32
				} elseif (($annot = OrmUtils::getAnnotationInfoMember ( $className, "#manyToMany", $member )) !== false) {
33
					$this->manyToManyFormField ( $form, $member, $instance, $annot );
34
				}
35
			}
36
		}
37
	}
38
39
	protected function manyToOneFormField(DataForm $form, $member, $className, $instance) {
40
		$joinColumn = OrmUtils::getAnnotationInfoMember ( $className, "#joinColumn", $member );
41
		if ($joinColumn) {
42
			$fkObject = Reflexion::getMemberValue ( $instance, $member );
0 ignored issues
show
Bug introduced by
The type Ubiquity\controllers\crud\viewers\traits\Reflexion 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...
43
			$fkClass = $joinColumn ["className"];
44
			if ($fkObject === null) {
45
				$fkObject = new $fkClass ();
46
			}
47
			$fkId = OrmUtils::getFirstKey ( $fkClass );
48
			$fkIdGetter = "get" . \ucfirst ( $fkId );
49
			if (\method_exists ( $fkObject, "__toString" ) && \method_exists ( $fkObject, $fkIdGetter )) {
50
				$fkField = $joinColumn ["name"];
51
				$fkValue = OrmUtils::getFirstKeyValue ( $fkObject );
52
				if (! Reflexion::setMemberValue ( $instance, $fkField, $fkValue )) {
53
					$instance->{$fkField} = OrmUtils::getFirstKeyValue ( $fkObject );
54
				}
55
				$form->fieldAsDropDown ( $fkField, JArray::modelArray ( $this->controller->_getAdminData ()->getManyToOneDatas ( $fkClass, $instance, $member ), $fkIdGetter, "__toString" ) );
0 ignored issues
show
Bug introduced by
The type Ubiquity\controllers\crud\viewers\traits\JArray 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...
56
				$form->setCaption ( $fkField, \ucfirst ( $member ) );
57
			}
58
		}
59
	}
60
61
	protected function oneToManyFormField(DataForm $form, $member, $instance, $annot) {
62
		$newField = $member . "Ids";
63
		$fkClass = $annot ["className"];
64
		$fkId = OrmUtils::getFirstKey ( $fkClass );
65
		$fkIdGetter = "get" . \ucfirst ( $fkId );
66
		$fkInstances = DAO::getOneToMany ( $instance, $member );
0 ignored issues
show
Bug introduced by
The type Ubiquity\controllers\crud\viewers\traits\DAO 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...
67
		$ids = \array_map ( function ($elm) use ($fkIdGetter) {
68
			return $elm->{$fkIdGetter} ();
69
		}, $fkInstances );
70
		$instance->{$newField} = \implode ( ",", $ids );
71
		$form->fieldAsDropDown ( $newField, JArray::modelArray ( $this->controller->_getAdminData ()->getOneToManyDatas ( $fkClass, $instance, $member ), $fkIdGetter, "__toString" ), true );
72
		$form->setCaption ( $newField, \ucfirst ( $member ) );
73
	}
74
75
	protected function manyToManyFormField(DataForm $form, $member, $instance, $annot) {
76
		$newField = $member . "Ids";
77
		$fkClass = $annot ["targetEntity"];
78
		$fkId = OrmUtils::getFirstKey ( $fkClass );
79
		$fkIdGetter = "get" . \ucfirst ( $fkId );
80
		$fkInstances = DAO::getManyToMany ( $instance, $member );
81
		$ids = \array_map ( function ($elm) use ($fkIdGetter) {
82
			return $elm->{$fkIdGetter} ();
83
		}, $fkInstances );
84
		$instance->{$newField} = \implode ( ",", $ids );
85
		$form->fieldAsDropDown ( $newField, JArray::modelArray ( $this->controller->_getAdminData ()->getManyToManyDatas ( $fkClass, $instance, $member ), $fkIdGetter, "__toString" ), true, [ "jsCallback" => function ($elm) {
86
			$elm->getField ()->asSearch ();
87
		} ] );
88
		$form->setCaption ( $newField, \ucfirst ( $member ) );
89
	}
90
91
	/**
92
	 *
93
	 * @return \Ubiquity\controllers\crud\EditMemberParams[]
94
	 */
95
	public function getEditMemberParams() {
96
		return $this->defaultEditMemberParams ();
97
	}
98
99
	/**
100
	 *
101
	 * @param string $part
102
	 * @return \Ubiquity\controllers\crud\EditMemberParams
103
	 */
104
	protected function getEditMemberParams_($part) {
105
		$params = $this->getEditMemberParams ();
106
		if ($params && isset ( $params [$part] )) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $params of type array<string,Ubiquity\co...\crud\EditMemberParams> 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...
107
			return $params [$part];
108
		}
109
		return new EditMemberParams ();
110
	}
111
112
	/**
113
	 *
114
	 * @return \Ubiquity\controllers\crud\EditMemberParams[]
115
	 */
116
	protected function defaultEditMemberParams() {
117
		return [ "dataTable" => EditMemberParams::dataTable (),"dataElement" => EditMemberParams::dataElement () ];
118
	}
119
120
	/**
121
	 * Returns the form for adding or modifying an object
122
	 *
123
	 * @param string $identifier
124
	 * @param object $instance the object to add or modify
125
	 * @return \Ajax\semantic\widgets\dataform\DataForm
126
	 */
127
	public function getForm($identifier, $instance) {
128
		$form = $this->jquery->semantic ()->dataForm ( $identifier, $instance );
129
		$form->setLibraryId ( "frmEdit" );
130
		$className = \get_class ( $instance );
131
		$fields = $this->controller->_getAdminData ()->getFormFieldNames ( $className, $instance );
132
		$relFields = OrmUtils::getFieldsInRelations_ ( $className );
133
134
		$this->setFormFields_ ( $fields, $relFields );
135
		array_unshift ( $fields, "_message" );
136
		$form->setFields ( $fields );
137
138
		$fieldTypes = OrmUtils::getFieldTypes ( $className );
139
		$this->setFormFieldsComponent ( $form, $fieldTypes );
140
		$this->relationMembersInForm ( $form, $instance, $className, $fields, $relFields );
141
		OrmUtils::setFieldToMemberNames ( $fields, $relFields );
142
		$form->setCaptions ( $this->getFormCaptions ( $fields, $className, $instance ) );
143
		$message = $this->getFormTitle ( $form, $instance );
144
		$form->setCaption ( "_message", $message ["subMessage"] );
145
		$form->fieldAsMessage ( "_message", [ "icon" => $message ["icon"] ] );
146
		$instance->_message = $message ["message"];
147
		$form->setSubmitParams ( $this->controller->_getBaseRoute () . "/update", "#frm-add-update" );
148
		$form->onGenerateField ( [ $this,'onGenerateFormField' ] );
149
		return $form;
150
	}
151
152
	/**
153
	 * Returns a form for member editing
154
	 *
155
	 * @param string $identifier
156
	 * @param object $instance
157
	 * @param string $member
158
	 * @param string $td
159
	 * @param string $part
160
	 * @return \Ajax\semantic\widgets\dataform\DataForm
161
	 */
162
	public function getMemberForm($identifier, $instance, $member, $td, $part) {
163
		$editMemberParams = $this->getEditMemberParams_ ( $part );
164
165
		$form = $this->jquery->semantic ()->dataForm ( $identifier, $instance );
166
		$form->on ( "dblclick", "", true, true );
167
		$form->setProperty ( "onsubmit", "return false;" );
168
		$form->addClass ( "_memberForm" );
169
		$className = \get_class ( $instance );
170
		$fields = [ "id",$member ];
171
		$relFields = OrmUtils::getFieldsInRelations_ ( $className );
172
		$hasRelations = $this->setFormFields_ ( $fields, $relFields );
173
		$form->setFields ( $fields );
174
		$fieldTypes = OrmUtils::getFieldTypes ( $className );
175
		$form->fieldAsHidden ( 0 );
176
		$this->setMemberFormFieldsComponent ( $form, $fieldTypes );
177
		if ($hasRelations) {
178
			$this->relationMembersInForm ( $form, $instance, $className, $fields, $relFields );
179
		}
180
		$form->setCaptions ( [ "","" ] );
181
		$form->onGenerateField ( function (HtmlFormField $f, $nb) use ($identifier, $editMemberParams) {
182
			if ($nb == 1) {
183
				$f->setSize ( "mini" );
184
				if ($editMemberParams->getHasButtons ()) {
185
					$btO = HtmlButton::icon ( "btO", "check" )->addClass ( "green mini compact" )->onClick ( "\$('#" . $identifier . "').trigger('validate');", true, true );
186
					$btC = HtmlButton::icon ( "btC", "close" )->addClass ( "mini compact" )->onClick ( "\$('#" . $identifier . "').trigger('endEdit');" );
187
					$f->wrap ( "<div class='fields' style='margin:0;'>", [ $btO,$btC,"</div>" ] );
188
					if (! $editMemberParams->getHasPopup ()) {
189
						$f->setWidth ( 16 )->setProperty ( "style", "padding-left:0;" );
190
					}
191
				}
192
				$f->on ( "keydown", "if(event.which == 13) {\$('#" . $identifier . "').trigger('validate');}if(event.keyCode===27) {\$('#" . $identifier . "').trigger('endEdit');}" );
193
				$f->onClick ( "return false;", true, true );
194
			} else {
195
				$f->setProperty ( "style", "display: none;" );
196
			}
197
		} );
198
		$form->setSubmitParams ( $this->controller->_getBaseRoute () . "/updateMember/" . $member . "/" . $editMemberParams->getUpdateCallback (), "#" . $td, [ "attr" => "","hasLoader" => false,"jsCallback" => "$(self).remove();","jqueryDone" => "html" ] );
199
		if ($editMemberParams->getHasPopup ()) {
200
			$endEdit = "\$('#" . $identifier . "').html();\$('.popup').hide();\$('#" . $td . "').popup('destroy');";
201
			$validate = $endEdit;
202
		} else {
203
			$endEdit = "let td=\$('#" . $td . "');td.html(td.data('originalText'));";
204
			$validate = "";
205
		}
206
		$form->on ( "endEdit", $endEdit );
207
		$form->on ( "validate", "\$('#" . $identifier . "').form('submit');" . $validate );
208
		$this->jquery->execAtLast ( "$('form').find('input[type=text],textarea,select').filter(':visible:first').focus();" );
209
		return $form;
210
	}
211
212
	private function setFormFields_(&$fields, $relFields) {
213
		$hasRelations = false;
214
		$relFields = array_flip ( $relFields );
215
		foreach ( $fields as $index => $field ) {
216
			if (isset ( $relFields [$field] )) {
217
				$fields [$index] = $relFields [$field];
218
				$hasRelations = true;
219
			}
220
		}
221
		return $hasRelations;
222
	}
223
224
	/**
225
	 * Returns an associative array defining form message title with keys "icon","message","subMessage"
226
	 *
227
	 * @param DataForm $form
228
	 * @param object $instance
229
	 * @return array the message title
230
	 */
231
	protected function getFormTitle($form, $instance) {
232
		$type = ($instance->_new) ? "new" : "edit";
233
		$messageInfos = [ "new" => [ "icon" => HtmlIconGroups::corner ( "table", "plus", "big" ),"subMessage" => "New object creation" ],"edit" => [ "icon" => HtmlIconGroups::corner ( "table", "edit", "big" ),"subMessage" => "Editing an existing object" ] ];
234
		$message = $messageInfos [$type];
235
		$message ["message"] = \get_class ( $instance );
236
		return $message;
237
	}
238
239
	/**
240
	 * Sets the components for each field
241
	 *
242
	 * @param DataForm $form
243
	 * @param array $fieldTypes associative array of field names (keys) and types (values)
244
	 */
245
	public function setFormFieldsComponent(DataForm $form, $fieldTypes) {
246
		$this->setFormFieldsComponent_ ( $form, $fieldTypes );
247
	}
248
249
	/**
250
	 * Sets the components for each field
251
	 *
252
	 * @param DataForm $form
253
	 * @param array $fieldTypes associative array of field names (keys) and types (values)
254
	 */
255
	public function setMemberFormFieldsComponent(DataForm $form, $fieldTypes) {
256
		$this->setFormFieldsComponent_ ( $form, $fieldTypes );
257
	}
258
259
	protected function setFormFieldsComponent_(DataForm $form, $fieldTypes) {
260
		foreach ( $fieldTypes as $property => $type ) {
261
			switch ($property) {
262
				case "password" :
263
					$form->fieldAsInput ( $property, [ "inputType" => "password" ] );
264
					$form->setValidationParams ( [ "inline" => true ] );
265
					break;
266
				case "email" :
267
				case "mail" :
268
					$form->fieldAsInput ( $property, [ "inputType" => "email","rules" => [ [ "email" ] ] ] );
269
					break;
270
			}
271
272
			switch ($type) {
273
				case "tinyint(1)" :
274
					$form->fieldAsCheckbox ( $property );
275
					break;
276
				case "int" :
277
				case "integer" :
278
					$form->fieldAsInput ( $property, [ "inputType" => "number" ] );
279
					break;
280
				case "date" :
281
					$form->fieldAsInput ( $property, [ "inputType" => "date" ] );
282
					break;
283
				case "datetime" :
284
					$form->fieldAsInput ( $property, [ "inputType" => "datetime-local" ] );
285
					break;
286
			}
287
		}
288
	}
289
290
	/**
291
	 * For doing something when $field is generated in form
292
	 *
293
	 * @param mixed $field
294
	 */
295
	public function onGenerateFormField($field, $nb) {
296
		if ($field instanceof HtmlFormInput) {
297
			if ($field->getDataField ()->getProperty ( 'type' ) == "datetime-local") {
298
				$v = $field->getDataField ()->getProperty ( 'value' );
299
				$field->getDataField ()->setValue ( date ( "Y-m-d\TH:i:s", strtotime ( $v ) ) );
300
			}
301
		}
302
		return;
303
	}
304
305
	/**
306
	 * Condition to determine if the edit or add form is modal for $model objects
307
	 *
308
	 * @param array $objects
309
	 * @param string $model
310
	 * @return boolean
311
	 */
312
	public function isModal($objects, $model) {
313
		return \count ( $objects ) > 5;
314
	}
315
316
	/**
317
	 * Returns the captions for form fields
318
	 *
319
	 * @param array $captions
320
	 * @param string $className
321
	 */
322
	public function getFormCaptions($captions, $className, $instance) {
323
		return \array_map ( "ucfirst", $captions );
324
	}
325
}
326
327