AppRecordView::__fieldsGroup()   C
last analyzed

Complexity

Conditions 12
Paths 2

Size

Total Lines 51
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 35
c 1
b 0
f 0
dl 0
loc 51
rs 6.9666
cc 12
nc 2
nop 3

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
// OVIDENTIA http://www.ovidentia.org
4
// Ovidentia is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2, or (at your option)
7
// any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
// See the GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17
// USA.
18
//-------------------------------------------------------------------------
19
/**
20
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
21
 * @copyright Copyright (c) 2022 by SI4YOU ({@link https://www.siforyou.com})
22
 */
23
24
namespace Capwelton\LibApp\Ui;
25
26
use Capwelton\Widgets\Widgets\Interfaces\WidgetDisplayableInterface;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widget...getDisplayableInterface 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...
27
use Capwelton\Widgets\Widgets\Layout\WidgetFlexLayout;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Layout\WidgetFlexLayout 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...
28
use Capwelton\Widgets\Widgets\Layout\WidgetLayout;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Layout\WidgetLayout 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...
29
use Capwelton\Widgets\Widgets\Item\WidgetSection;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Item\WidgetSection 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...
30
use Capwelton\Widgets\Widgets\Item\WidgetLink;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Item\WidgetLink 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...
31
use Capwelton\LibApp\AppUiObject;
32
use Capwelton\LibApp\Ctrl\AppCtrlRecord;
33
use Capwelton\LibApp\Func_App;
34
use Capwelton\LibApp\Set\AppRecord;
35
use Capwelton\LibApp\Set\AppRecordSet;
36
use Capwelton\LibApp\Set\AppCustomSection;
37
use Capwelton\LibOrm\Exceptions\ORMException;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Exceptions\ORMException 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...
38
use Capwelton\LibOrm\Field\ORMCurrencyField;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Field\ORMCurrencyField 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...
39
40
class AppRecordView extends AppUiObject
41
{
42
    /**
43
     * @var AppRecord
44
     */
45
    protected $record = null;
46
    
47
    /**
48
     * @var AppRecordSet
49
     */
50
    protected $recordSet = null;
51
    
52
    /**
53
     * @var WidgetSection[]
54
     */
55
    protected $sections = array();
56
    
57
    protected $view = '';
58
    
59
    /**
60
     * @var AppCtrlRecord
61
     */
62
    protected $recordController = null;
63
    
64
    protected $recordIsReadable = false;
65
    protected $recordIsUpdateable = false;
66
    protected $recordIsDeletable = false;
67
    
68
    /**
69
     * @param Func_App $App
70
     * @param string $id
71
     * @param WidgetLayout $layout
72
     */
73
    public function __construct(Func_App $App, $id = null, WidgetLayout $layout = null)
74
    {
75
        parent::__construct($App);
76
        
77
        if (!isset($layout)) {
78
            $W = bab_Widgets();
79
            $layout = $W->Items();
80
        }
81
        
82
        $this->setInheritedItem($layout);
83
    }
84
    
85
    
86
    /**
87
     * @param AppRecord $record
88
     * @return self
89
     */
90
    public function setRecord(AppRecord $record)
91
    {
92
        $this->record = $record;
93
        $this->recordSet = $record->getParentSet();
94
        
95
        $this->recordIsReadable = $record->isReadable();
96
        $this->recordIsUpdateable = $record->isUpdatable();
97
        $this->recordIsDeletable = $record->isDeletable();
98
        
99
        return $this;
100
    }
101
    
102
    
103
    /**
104
     * @param string $view
105
     * @return self
106
     */
107
    public function setView($view)
108
    {
109
        $this->view = $view;
110
        return $this;
111
    }
112
    
113
    
114
    /**
115
     * @return string
116
     */
117
    public function getView()
118
    {
119
        return $this->view;
120
    }
121
    
122
    
123
    
124
    /**
125
     * Creates section in the editor.
126
     * If a section with the same header text (title) was already
127
     * created it is replaced by an empty section.
128
     *
129
     * @param string $headerText
130
     * @return WidgetSection
131
     */
132
    protected function addSection($id, $headerText, $layout = null)
133
    {
134
        $W = bab_Widgets();
135
        if (!isset($layout)) {
136
            $layout = $W->VBoxLayout();
137
        }
138
        $this->sections[$id] = $W->Section(
139
            $headerText,
140
            $layout
141
            )->setFoldable(true);
142
            
143
            return $this->sections[$id];
144
    }
145
    
146
    /**
147
     * Creates section in the editor.
148
     * If a section with the same header text (title) was already
149
     * created it is replaced by an empty section.
150
     *
151
     * @param string $headerText
152
     * @return WidgetSection
153
     */
154
    protected function createSection($headerText, $layout = null)
155
    {
156
        return $this->addSection($headerText, $headerText, $layout);
157
    }
158
    
159
    
160
    /**
161
     * Retrieves a section in the editor.
162
     *
163
     * @param string $headerText
164
     * @return WidgetSection
165
     */
166
    protected function getSection($id)
167
    {
168
        if (!isset($this->sections[$id])) {
169
            return null;
170
        }
171
        return $this->sections[$id];
172
    }
173
    
174
    
175
    /**
176
     * Returns the list of sections created via createSection().
177
     *
178
     * @return WidgetSection[]
179
     */
180
    public function getSections()
181
    {
182
        return $this->sections;
183
    }
184
    
185
    
186
    
187
    
188
    /**
189
     * @param string $textLabel
190
     * @param mixed $value
191
     * @param AppCustomSection $section
192
     * @return WidgetLayout
193
     */
194
    public function labelledWidget($textLabel, $value, AppCustomSection $section = null)
195
    {
196
        $W = bab_Widgets();
197
        
198
        if ($value instanceof WidgetDisplayableInterface) {
199
            $widget = $value;
200
        } else {
201
            $widget = $W->Label($value);
202
        }
203
        
204
        if (isset($section)) {
205
            if ($textLabel === '__') {
206
                $fieldLayout = AppCustomSection::FIELDS_LAYOUT_NO_LABEL;
207
            } else {
208
                $fieldLayout = $section->fieldsLayout;
209
            }
210
            switch ($fieldLayout) {
211
                case AppCustomSection::FIELDS_LAYOUT_HORIZONTAL_LABEL:
212
                    return $W->FlowItems(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $W->FlowItems($W-...setVerticalAlign('top') returns the type Widget_FlowLayout which is incompatible with the documented return type Capwelton\Widgets\Widgets\Layout\WidgetLayout.
Loading history...
213
                    $W->Label($textLabel)->addClass('crm-horizontal-display-label', 'widget-strong')
214
                    ->setSizePolicy('widget-25pc'),
215
                    $widget
216
                    )->addClass('widget-labelled-widget')
217
                    ->setHorizontalSpacing(1, 'ex')
218
                    ->setVerticalAlign('top');
219
                    
220
                case AppCustomSection::FIELDS_LAYOUT_WIDE_HORIZONTAL_LABEL:
221
                    return $W->FlowItems(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $W->FlowItems($W-...setVerticalAlign('top') returns the type Widget_FlowLayout which is incompatible with the documented return type Capwelton\Widgets\Widgets\Layout\WidgetLayout.
Loading history...
222
                    $W->Label($textLabel)->addClass('crm-horizontal-display-label', 'widget-strong')
223
                    ->setSizePolicy('widget-50pc'),
224
                    $widget
225
                    )->addClass('widget-labelled-widget')
226
                    ->setHorizontalSpacing(1, 'ex')
227
                    ->setVerticalAlign('top');
228
                    
229
                case AppCustomSection::FIELDS_LAYOUT_NO_LABEL:
230
                    return $widget;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $widget also could return the type Widget_Label which is incompatible with the documented return type Capwelton\Widgets\Widgets\Layout\WidgetLayout.
Loading history...
231
                    
232
                case AppCustomSection::FIELDS_LAYOUT_VERTICAL_LABEL:
233
                default:
234
                    return $W->LabelledWidget($textLabel, $widget);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $W->LabelledWidget($textLabel, $widget) returns the type Widget_LabelledWidget which is incompatible with the documented return type Capwelton\Widgets\Widgets\Layout\WidgetLayout.
Loading history...
235
            }
236
        }
237
    }
238
    
239
    
240
    public function labelledWidgetOptional($textLabel, $displayedValue, $value = null, AppCustomSection $section = null)
241
    {
242
        if (!isset($value)) {
243
            $value = $displayedValue;
244
        }
245
        if (!isset($value) || is_numeric($value) && $value == 0 || is_string($value) && trim($value) == '' || ($value instanceof WidgetLayout && count($value->getItems()) <= 0)) {
246
            return null;
247
        }
248
        return $this->labelledWidget($textLabel, $displayedValue, $section);
249
    }
250
    
251
    
252
    
253
    protected function fieldOutput($field, $record, $fieldName)
254
    {
255
        if ($field instanceof ORMCurrencyField) {
256
            $App = $this->App();
257
            $value = $App->shortFormatWithUnit($this->record->$fieldName, $App->translate('_euro_'));
258
        } else {
259
            $value = $field->output($this->record->$fieldName);
260
        }
261
        return $value;
262
    }
263
    
264
    protected function addSections($view = '')
265
    {
266
        $App = $this->App();
267
        $W = bab_Widgets();
268
        
269
        $objectName = $this->getViewObjectName();
270
        
271
        $customContainerSet = $App->CustomContainerSet();
272
        $customContainers = $customContainerSet->select(
273
            $customContainerSet->object->is($objectName)->_AND_($customContainerSet->view->is($view))
274
            );
275
        $customContainers->orderAsc($customContainerSet->rank);
276
        
277
        
278
        $customSectionSet = $App->CustomSectionSet();
279
        
280
        foreach ($customContainers as $customContainer) {
281
            
282
            if (isset($this->record) && !$customContainer->isVisibleForRecord($this->record)) {
283
                continue;
284
            }
285
            
286
            $container = $W->Items()
287
            ->addClass($customContainer->classname)
288
            ->setSizePolicy("app-container {$customContainer->sizePolicy}");
289
            
290
            $this->addItem($container);
291
            
292
            $customSections = $customSectionSet->select(
293
                $customSectionSet->container->is($customContainer->id)
294
                );
295
            $customSections->orderAsc($customSectionSet->rank);
296
            
297
            $currentColumn = 0;
298
            $nbCol = 0;
299
            $row = $W->Items()->setSizePolicy('row');
300
            $row->addClass('row');
301
            
302
            foreach ($customSections as $customSection) {
303
                
304
                if (isset($this->record) && !$customSection->isVisibleForRecord($this->record)) {
305
                    continue;
306
                }
307
                
308
                list(, , $nbCol) = explode('-', $customSection->sizePolicy);
309
                
310
                if ($currentColumn + $nbCol > 12) {
311
                    $container->addItem($row);
312
                    $row = $W->Items()->setSizePolicy('row');
313
                    $row->addClass('row');
314
                    $currentColumn = 0;
315
                }
316
                $currentColumn += $nbCol;
317
                
318
                if (strpos($customSection->classname, 'horizontal') !== false) {
319
                    $box = $W->FlowItems()
320
                    ->setVerticalAlign('top')
321
                    ->setSpacing(1, 'em');
322
                } else {
323
                    $box = null;
324
                }
325
                
326
                $section = $this->getSection($customSection->id);
327
                if (!isset($section)) {
328
                    $section = $this->addSection($customSection->id, $customSection->name, $box);
329
                    $section->addClass($customSection->classname);
330
                    $section->setSizePolicy($customSection->sizePolicy);
331
                    
332
                    $menu = $section->addContextMenu('inline');
333
                    $menu->addClass(\Func_Icons::ICON_LEFT_16);
334
                    
335
                    if ($customSection->editable && $this->recordIsUpdateable) {
336
                        $menu->addItem(
337
                            $W->Link(
338
                                '',
339
                                $this->record->getController()->editSection($this->record->id, $customSection->id)
0 ignored issues
show
Bug introduced by
The method editSection() does not exist on Capwelton\LibApp\Ctrl\AppController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

339
                                $this->record->getController()->/** @scrutinizer ignore-call */ editSection($this->record->id, $customSection->id)
Loading history...
340
                                )->addClass('widget-actionbutton', 'section-button', 'icon', \Func_Icons::ACTIONS_DOCUMENT_EDIT)
341
                            ->setOpenMode(WidgetLink::OPEN_DIALOG)->setDialogClass('customSectionEditorDialog '.$customSection->classname)
0 ignored issues
show
Bug introduced by
The method setDialogClass() does not exist on Widget_Link. ( Ignorable by Annotation )

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

341
                            ->setOpenMode(WidgetLink::OPEN_DIALOG)->/** @scrutinizer ignore-call */ setDialogClass('customSectionEditorDialog '.$customSection->classname)

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
342
                            );
343
                    }
344
                    
345
                    $section->setFoldable($customSection->foldable, $customSection->folded);
346
                    $row->addItem($section);
347
                }
348
                
349
                
350
                
351
                $displayFields = $customSection->getFields();
352
                
353
                foreach ($displayFields as $displayFieldId => $displayField) {
354
                    $isGroupField = strpos($displayFieldId, '_fieldsGroup') !== false;
355
                    $item = null;
356
                    $displayFieldName = $displayField['fieldname'];
357
                    $parameters = $displayField['parameters'];
358
                    $classname = isset($parameters['classname']) ? $parameters['classname'] : '';
359
                    $label = isset($parameters['label']) && !empty($parameters['label']) ? $parameters['label'] : null;
360
                    $sizePolicy = 'customsection-field-box ';
361
                    $sizePolicy .= isset($parameters['sizePolicy']) ? $parameters['sizePolicy'] : '';
362
                    $sizePolicy .= isset($parameters['transparentBackground']) && $parameters['transparentBackground'] ? 'customsection-field-box-transparentBackground' : '';
363
                    
364
                    $displayFieldMethod = '_' . $displayFieldName;
365
                    if (!$isGroupField && method_exists($this, $displayFieldMethod)) {
366
                        $item = $this->$displayFieldMethod($customSection, $label);
367
                    }
368
                    else {
369
                        if($isGroupField){
370
                            list(, $groupId) = explode('_fieldsGroup', $displayFieldId);
371
                            if (method_exists($this, '__fieldsGroup')) {
372
                                $item = $this->__fieldsGroup($customSection, $groupId, $label);
373
                            }
374
                            $sizePolicy .= ' customsection-fieldsgroup-box';
375
                        }
376
                        else{
377
                            try {
378
                                $field = $this->recordSet->getField($displayFieldName);
379
                                $value = $this->fieldOutput($field, $this->record, $displayFieldName);
0 ignored issues
show
Unused Code introduced by
The assignment to $value is dead and can be removed.
Loading history...
380
                                if (!isset($label)) {
381
                                    $label = $App->translate($field->getDescription());
382
                                }
383
                                
384
                                $outputWidget = $field->outputWidget($this->record->$displayFieldName);
385
                                
386
                                $item = $this->labelledWidget(
387
                                    $label,
388
                                    $outputWidget,
389
                                    $customSection
390
                                    );
391
                            } catch (ORMException $e) {
392
                                $item = null;
393
                            }
394
                        }
395
                    }
396
                    if (isset($item) && $item instanceof WidgetDisplayableInterface) {
397
                        $item->setSizePolicy($sizePolicy);
398
                        $item->addClass($classname);
399
                        $section->addItem($item);
400
                    }
401
                }
402
            }
403
            
404
            if ($currentColumn + $nbCol> 0) {
405
                $container->addItem($row);
406
            }
407
        }
408
    }
409
    
410
    
411
    protected function __spacer()
412
    {
413
        $W = bab_Widgets();
414
        return $W->Label('')->addClass('spacer');
415
    }
416
    
417
    protected function getObjectName()
418
    {
419
        return $this->record->getClassName();
420
    }
421
    
422
    protected function getViewObjectName()
423
    {
424
        return $this->getObjectName();
425
    }
426
    
427
    protected function __fieldsGroup(AppCustomSection $customSection, $groupId = 0, $label = null)
428
    {
429
        $W = bab_Widgets();
430
        $App = $this->App();
431
        
432
        $box = $W->FlexItems()->setGrowable(true)->setWrap(WidgetFlexLayout::FLEX_WRAP_WRAP);
0 ignored issues
show
Bug introduced by
The method FlexItems() does not exist on Func_Widgets. ( Ignorable by Annotation )

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

432
        $box = $W->/** @scrutinizer ignore-call */ FlexItems()->setGrowable(true)->setWrap(WidgetFlexLayout::FLEX_WRAP_WRAP);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
433
        $groupField = $customSection->getField('_fieldsGroup'.$groupId);
434
        $originalFieldsLayout = $customSection->fieldsLayout;
435
        $customSection->fieldsLayout = AppCustomSection::FIELDS_LAYOUT_VERTICAL_LABEL;
436
        if(isset($groupField['fields'])){
437
            foreach ($groupField['fields'] as $field){
438
                $item = null;
439
                $parameters = $field['parameters'];
440
                $labelField = isset($parameters['label']) ? $parameters['label'] : '';
441
                $itemClass = isset($parameters['classname']) ? $parameters['classname'] : '';
442
                $itemClass .= isset($parameters['sizePolicy']) ? $parameters['sizePolicy'] : '';
443
                $itemClass .= isset($parameters['transparentBackground']) && $parameters['transparentBackground'] ? 'customsection-field-box-transparentBackground' : '';
444
                
445
                $displayFieldName = $field['fieldname'];
446
                
447
                $displayFieldMethod = '_' . $displayFieldName;
448
                if (method_exists($this, $displayFieldMethod)) {
449
                    $item = $this->$displayFieldMethod($customSection, $labelField);
450
                }
451
                else{
452
                    try {
453
                        $field = $this->recordSet->getField($displayFieldName);
454
                        $value = $this->fieldOutput($field, $this->record, $displayFieldName);
0 ignored issues
show
Unused Code introduced by
The assignment to $value is dead and can be removed.
Loading history...
455
                        
456
                        $outputWidget = $field->outputWidget($this->record->$displayFieldName);
457
                        
458
                        $item = $this->labelledWidget(
459
                            !empty($labelField) ? $labelField : $App->translate($field->getDescription()),
460
                            $outputWidget,
461
                            $customSection
462
                            );
463
                    } catch (ORMException $e) {
464
                        $item = null;
465
                    }
466
                }
467
                if(isset($item)){
468
                    $item->addClass('app-customsection-groupedfield');
469
                    $item->addClass($itemClass);
470
                }
471
                
472
                $box->addItem($item);
473
            }
474
        }
475
        $customSection->fieldsLayout = $originalFieldsLayout;
476
        
477
        return $box;
478
    }
479
}