AppCtrlCustomSection::sections()   F
last analyzed

Complexity

Conditions 17
Paths 2848

Size

Total Lines 179
Code Lines 126

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 126
c 1
b 0
f 1
dl 0
loc 179
rs 0.8399
cc 17
nc 2848
nop 2

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
// OVIDENTIA http://www.ovidentia.org
5
// Ovidentia is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2, or (at your option)
8
// any later version.
9
//
10
// This program is distributed in the hope that it will be useful, but
11
// WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
// See the GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18
// USA.
19
// -------------------------------------------------------------------------
20
/**
21
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
22
 * @copyright Copyright (c) 2022 by SI4YOU ({@link https://www.siforyou.com})
23
 */
24
namespace Capwelton\LibApp\Ctrl;
25
26
use bab_charset;
27
use Capwelton\Widgets\Widgets\Form\WidgetForm;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Form\WidgetForm 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\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...
29
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...
30
use Capwelton\Widgets\Widgets\Layout\WidgetVBoxLayout;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Layout\WidgetVBoxLayout 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\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...
32
use Capwelton\LibApp\Ui\AppEditor;
33
use Capwelton\LibApp\Ui\Page\AppPage;
34
use Capwelton\LibApp\Exceptions\AppException;
35
use Capwelton\LibApp\Set\AppRecordSet;
36
use Capwelton\LibApp\Set\AppCustomSection;
37
use Capwelton\LibOrm\Interfaces\ORMBoolInterface;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Interfaces\ORMBoolInterface 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\MySql\ORMOneRelation;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\MySql\ORMOneRelation 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
/**
41
 * This controller manages actions that can be performed on custom sections
42
 *
43
 * @method Func_App App()
44
 * @method self proxy()
45
 */
46
class AppCtrlCustomSection extends AppCtrlRecord
47
{
48
    
49
    /**
50
     * @param string $itemId
51
     * @return WidgetVBoxLayout
52
     */
53
    public function availableDisplayFields($section = null, $itemId = null)
54
    {
55
        $W = bab_Widgets();
56
        $App = $this->App();
57
        
58
        $customSectionSet = $App->CustomSectionSet();
59
        $customSectionSet->container();
60
        
61
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
62
        
63
        $object = $customSection->container->object;
64
        if(strpos($object, $App->classPrefix) !== false){
65
            list (, $object) = explode($App->classPrefix, $object);
66
        }
67
        $objectCtrl = $App->Controller()->$object(false);
68
        
69
        $allViewSections = $customSectionSet->select($customSectionSet->view->is($customSection->view)
70
            ->_AND_($customSectionSet->object->is($customSection->object)));
71
        
72
        $allViewFieldNames = array();
73
        foreach ($allViewSections as $viewSection){
74
            $fields = $viewSection->getFields();
75
            foreach ($fields as $field){
76
                $allViewFieldNames[$field['fieldname']] = $viewSection->view . ',' . $viewSection->rank . ',' . $viewSection->id;
77
                foreach ($field['fields'] as $subField){
78
                    $allViewFieldNames[$subField['fieldname']] = $viewSection->view . ',' . $viewSection->rank . ',' . $viewSection->id;
79
                }
80
            }
81
        }
82
        
83
        $box = $W->VBoxItems();
84
        if(isset($itemId)){
85
            $box->setId($itemId);
86
        }
87
        
88
        $box->addItem($W->Link($App->translate('Create new field'), $App->Controller()
89
            ->CustomField()
90
            ->add($customSection->object))
91
            ->setOpenMode(WidgetLink::OPEN_DIALOG_AND_RELOAD)
92
            ->addClass('widget-actionbutton', 'icon', \Func_Icons::ACTIONS_LIST_ADD)
93
            ->setSizePolicy(\Func_Icons::ICON_LEFT_SYMBOLIC));
94
        
95
        $availableFields = $objectCtrl->getAvailableDisplayFields();
96
        
97
        \bab_Sort::asort($availableFields, 'description', \bab_Sort::CASE_INSENSITIVE);
98
        
99
        foreach ($availableFields as $field){
100
            $fieldName = $field['name'];
101
            $fieldDescription = $field['description'];
102
            
103
            $used = isset($allViewFieldNames[$fieldName]);
104
            $box->addItem($W->VBoxItems($W->Link($fieldDescription, $this->proxy()
0 ignored issues
show
Bug introduced by
$this->proxy()->saveDisp...d($section, $fieldName) of type true is incompatible with the type Widget_Action|bab_url|string expected by parameter $url of Func_Widgets::Link(). ( Ignorable by Annotation )

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

104
            $box->addItem($W->VBoxItems($W->Link($fieldDescription, /** @scrutinizer ignore-type */ $this->proxy()
Loading history...
105
                ->saveDisplayField($section, $fieldName))
106
                ->addClass('widget-close-dialog', ($used ? 'widget-strong' : ''))
107
                ->setTitle($fieldName)
108
                ->setAjaxAction(), $W->Hidden()
109
                ->setName(array(
110
                'sections',
111
                $field['name']
112
            )))
113
                ->setSizePolicy('widget-list-element'));
114
        }
115
        
116
        $box->addClass('widget-3columns');
117
        
118
        $box->setReloadAction($this->proxy()
119
            ->availableDisplayFields($section, $box->getId()));
120
        
121
        return $box;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $box returns the type Widget_VBoxLayout which is incompatible with the documented return type Capwelton\Widgets\Widgets\Layout\WidgetVBoxLayout.
Loading history...
122
    }
123
    
124
    /**
125
     */
126
    public function addDisplayField($section = null, $filter = null)
127
    {
128
        $App = $this->App();
129
        
130
        $page = $App->Ui()->Page();
131
        $page->setTitle($App->translate('Available fields'));
132
        
133
        $box = $this->availableDisplayFields($section);
134
        
135
        $page->addItem($box);
136
        return $page;
137
    }
138
    
139
    /**
140
     * @param int $section
141
     * @param string $fieldName
142
     * @return AppPage
143
     */
144
    public function editDisplayField($section, $fieldName)
145
    {
146
        $App = $this->App();
147
        $customSectionSet = $App->CustomSectionSet();
148
        $customSectionSet->container();
149
        
150
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
151
        
152
        $field = $customSection->getField($fieldName);
153
        
154
        if(! isset($field)){
155
            return null;
156
        }
157
        
158
        $W = bab_Widgets();
159
        
160
        $object = $customSection->container->object;
161
        $objectCtrl = $App->Controller()->$object(false);
162
        
163
        $originalFieldName = $fieldName;
164
        $fieldName = $field['fieldname'];
165
        $params = $field['parameters'];
166
        
167
        $availableFields = $objectCtrl->getAvailableDisplayFields();
168
        
169
        $field = $availableFields[$fieldName];
170
        $fieldDescription = $field['description'];
171
        if(substr($fieldName, 0, 1) !== '_'){
172
            $fieldDescription = $App->translate($fieldDescription);
173
        }
174
        
175
        if(empty($field)){
176
            // continue;
177
        }
178
        
179
        $page = $App->Ui()->Page();
180
        $page->setTitle($fieldDescription);
181
        
182
        $editor = new AppEditor($App);
183
        $editor->setHiddenValue('tg', $App->controllerTg);
184
        $editor->setHiddenValue('section', $section);
185
        $editor->setHiddenValue('fieldName', $fieldName == '_fieldsGroup' ? $originalFieldName : $fieldName);
186
        
187
        $box = $W->VBoxItems($W->LabelledWidget($App->translate('Type'), $W->Select()
188
            ->setName(array(
189
            'parameters',
190
            'type'
191
        ))
192
            ->addOption('', '')
193
            ->addOption('title1', $App->translate('Title 1'))
194
            ->addOption('title2', $App->translate('Title 2'))
195
            ->addOption('title3', $App->translate('Title 3'))), $W->LabelledWidget($App->translate('Label'), $W->LineEdit()
196
            ->setName(array(
197
            'parameters',
198
            'label'
199
        ))), $W->LabelledWidget($App->translate('Class'), $W->LineEdit()
200
            ->setName(array(
201
            'parameters',
202
            'classname'
203
        ))), $W->LabelledWidget($App->translate('Transparent background'), $W->CheckBox()
204
            ->setName(array(
205
            'parameters',
206
            'transparentBackground'
207
        ))), $W->LabelledWidget($App->translate('Size policy'), $W->LineEdit()
208
            ->setName(array(
209
            'parameters',
210
            'sizePolicy'
211
        ))))
212
            ->setVerticalSpacing(1, 'em');
213
        
214
        $editor->setValues($params, array(
215
            'parameters'
216
        ));
217
        
218
        $editor->addItem($box);
219
        
220
        $editor->setSaveAction($this->proxy()
221
            ->saveDisplayField());
222
        
223
        $editor->isAjax = true;
224
        
225
        $page->addItem($editor);
226
        
227
        return $page;
228
    }
229
    
230
    /**
231
     * @param int $section
232
     * @param string $fieldName
233
     * @return AppPage
234
     */
235
    public function editGroupFieldDisplayField($section, $fieldGroupName, $fieldName)
236
    {
237
        $App = $this->App();
238
        $customSectionSet = $App->CustomSectionSet();
239
        $customSectionSet->container();
240
        
241
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
242
        
243
        $groupField = $customSection->getField($fieldGroupName);
244
        
245
        if(! isset($groupField)){
246
            return null;
247
        }
248
        
249
        $field = $groupField['fields'][$fieldName];
250
        if(! isset($field)){
251
            return null;
252
        }
253
        
254
        $W = bab_Widgets();
255
        
256
        $object = $customSection->container->object;
257
        $objectCtrl = $App->Controller()->$object(false);
258
        
259
        $fieldName = $field['fieldname'];
260
        $params = $field['parameters'];
261
        
262
        $availableFields = $objectCtrl->getAvailableDisplayFields();
263
        
264
        $field = $availableFields[$fieldName];
265
        $fieldDescription = $field['description'];
266
        if(substr($fieldName, 0, 1) !== '_'){
267
            $fieldDescription = $App->translate($fieldDescription);
268
        }
269
        
270
        if(empty($field)){
271
            // continue;
272
        }
273
        
274
        $page = $App->Ui()->Page();
275
        $page->setTitle($fieldDescription);
276
        
277
        $editor = new AppEditor($App);
278
        $editor->setHiddenValue('tg', $App->controllerTg);
279
        $editor->setHiddenValue('section', $section);
280
        $editor->setHiddenValue('fieldGroupName', $fieldGroupName);
281
        $editor->setHiddenValue('fieldName', $fieldName);
282
        
283
        $box = $W->VBoxItems($W->LabelledWidget($App->translate('Type'), $W->Select()
284
            ->setName(array(
285
            'parameters',
286
            'type'
287
        ))
288
            ->addOption('', '')
289
            ->addOption('title1', $App->translate('Title 1'))
290
            ->addOption('title2', $App->translate('Title 2'))
291
            ->addOption('title3', $App->translate('Title 3'))), $W->LabelledWidget($App->translate('Label'), $W->LineEdit()
292
            ->setName(array(
293
            'parameters',
294
            'label'
295
        ))), $W->LabelledWidget($App->translate('Class'), $W->LineEdit()
296
            ->setName(array(
297
            'parameters',
298
            'classname'
299
        ))), $W->LabelledWidget($App->translate('Transparent background'), $W->CheckBox()
300
            ->setName(array(
301
            'parameters',
302
            'transparentBackground'
303
        )), null, $App->translate('If the group field has a transparent background, this option will have no effect')), $W->LabelledWidget($App->translate('Size policy'), $W->LineEdit()
304
            ->setName(array(
305
            'parameters',
306
            'sizePolicy'
307
        ))))
308
            ->setVerticalSpacing(1, 'em');
309
        
310
        $editor->setValues($params, array(
311
            'parameters'
312
        ));
313
        
314
        $editor->addItem($box);
315
        
316
        $editor->setSaveAction($this->proxy()
317
            ->saveDisplayFieldToGroup());
318
        
319
        $editor->isAjax = true;
320
        
321
        $page->addItem($editor);
322
        
323
        return $page;
324
    }
325
    
326
    public function addDisplayFieldToGroup($section = null, $fieldGroupName = null, $filter = null)
327
    {
328
        $App = $this->App();
329
        
330
        $page = $App->Ui()->Page();
331
        $page->setTitle($App->translate('Available fields'));
332
        
333
        $box = $this->availableDisplayFieldsForGroup($section, $fieldGroupName);
334
        
335
        $page->addItem($box);
336
        return $page;
337
    }
338
    
339
    /**
340
     * @param string $itemId
341
     * @return WidgetVBoxLayout
342
     */
343
    public function availableDisplayFieldsForGroup($section = null, $fieldGroupName = null, $itemId = null)
344
    {
345
        $W = bab_Widgets();
346
        $App = $this->App();
347
        
348
        $customSectionSet = $App->CustomSectionSet();
349
        $customSectionSet->container();
350
        
351
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
352
        $fields = $customSection->getFields();
353
        if(! isset($fields[$fieldGroupName])){
354
            throw new AppException($App->translate('This fields group does not seem to exist'));
355
        }
356
        
357
        $object = $customSection->container->object;
358
        if(strpos($object, $App->classPrefix) !== false){
359
            list (, $object) = explode($App->classPrefix, $object);
360
        }
361
        
362
        $objectCtrl = $App->Controller()->$object(false);
363
        
364
        $allViewSections = $customSectionSet->select($customSectionSet->view->is($customSection->view)
365
            ->_AND_($customSectionSet->object->is($customSection->object)));
366
        
367
        $allViewFieldNames = array();
368
        foreach ($allViewSections as $viewSection){
369
            $fields = $viewSection->getFields();
370
            foreach ($fields as $field){
371
                $allViewFieldNames[$field['fieldname']] = $viewSection->view . ',' . $viewSection->rank . ',' . $viewSection->id;
372
                foreach ($field['fields'] as $subField){
373
                    $allViewFieldNames[$subField['fieldname']] = $viewSection->view . ',' . $viewSection->rank . ',' . $viewSection->id;
374
                }
375
            }
376
        }
377
        
378
        $box = $W->VBoxItems();
379
        if(isset($itemId)){
380
            $box->setId($itemId);
381
        }
382
        
383
        $box->addItem($W->Link($App->translate('Create new field'), $App->Controller()
384
            ->CustomField()
385
            ->add($customSection->object))
386
            ->setOpenMode(WidgetLink::OPEN_DIALOG_AND_RELOAD)
387
            ->addClass('widget-actionbutton', 'icon', \Func_Icons::ACTIONS_LIST_ADD)
388
            ->setSizePolicy(\Func_Icons::ICON_LEFT_SYMBOLIC));
389
        
390
        $availableFields = $objectCtrl->getAvailableDisplayFields();
391
        unset($availableFields['_fieldsGroup']);
392
        unset($availableFields['_spacer']);
393
        
394
        \bab_Sort::asort($availableFields, 'description', \bab_Sort::CASE_INSENSITIVE);
395
        
396
        foreach ($availableFields as $field){
397
            $fieldName = $field['name'];
398
            $fieldDescription = $field['description'];
399
            
400
            $used = isset($allViewFieldNames[$fieldName]);
401
            $box->addItem($W->VBoxItems($W->Link($fieldDescription, $this->proxy()
0 ignored issues
show
Bug introduced by
$this->proxy()->saveDisp...dGroupName, $fieldName) of type true is incompatible with the type Widget_Action|bab_url|string expected by parameter $url of Func_Widgets::Link(). ( Ignorable by Annotation )

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

401
            $box->addItem($W->VBoxItems($W->Link($fieldDescription, /** @scrutinizer ignore-type */ $this->proxy()
Loading history...
402
                ->saveDisplayFieldToGroup($section, $fieldGroupName, $fieldName))
403
                ->addClass('widget-close-dialog', ($used ? 'widget-strong' : ''))
404
                ->setTitle($fieldName)
405
                ->setAjaxAction(), $W->Hidden()
406
                ->setName(array(
407
                'sections',
408
                $field['name']
409
            )))
410
                ->setSizePolicy('widget-list-element'));
411
        }
412
        
413
        $box->addClass('widget-3columns');
414
        $box->setReloadAction($this->proxy()
415
            ->availableDisplayFields($section, $box->getId()));
416
        
417
        return $box;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $box returns the type Widget_VBoxLayout which is incompatible with the documented return type Capwelton\Widgets\Widgets\Layout\WidgetVBoxLayout.
Loading history...
418
    }
419
    
420
    /**
421
     * @param int $section
422
     * @param string $fieldName
423
     * @return boolean
424
     */
425
    public function saveDisplayFieldToGroup($section = null, $fieldGroupName = null, $fieldName = null, $parameters = null)
426
    {
427
        $App = $this->App();
428
        $customSectionSet = $App->CustomSectionSet();
429
        
430
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
431
        $customSection->updateFieldGroup($fieldGroupName, $fieldName, $parameters);
432
        $customSection->save();
433
        
434
        $this->addReloadSelector('.depends-custom-sections');
435
        $this->addReloadSelector('.depends-fieldsGroupEditor');
436
        
437
        return true;
438
    }
439
    
440
    /**
441
     * @param int $section
442
     * @param string $fieldName
443
     * @return boolean
444
     */
445
    public function saveDisplayField($section = null, $fieldName = null, $parameters = null)
446
    {
447
        $App = $this->App();
448
        $customSectionSet = $App->CustomSectionSet();
449
        
450
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
451
        $customSection->updateField($fieldName, $parameters);
452
        $customSection->save();
453
        
454
        $this->addReloadSelector('.depends-custom-sections');
455
        
456
        return true;
457
    }
458
    
459
    /**
460
     * @param int $section
461
     * @param string $fieldName
462
     * @return boolean
463
     */
464
    public function removeDisplayField($section, $fieldName)
465
    {
466
        $App = $this->App();
467
        $customSectionSet = $App->CustomSectionSet();
468
        
469
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
470
        
471
        $customSection->removeField($fieldName);
472
        $customSection->save();
473
        $this->addReloadSelector('.depends-custom-sections');
474
        return true;
475
    }
476
    
477
    /**
478
     * @param int $section
479
     * @param string $fieldName
480
     * @return boolean
481
     */
482
    public function removeDisplayFieldFromGroup($section, $fieldGroupName, $fieldName)
483
    {
484
        $App = $this->App();
485
        $customSectionSet = $App->CustomSectionSet();
486
        
487
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
488
        
489
        $customSection->removeFieldFromGroup($fieldGroupName, $fieldName);
490
        $customSection->save();
491
        $this->addReloadSelector('.depends-custom-sections');
492
        return true;
493
    }
494
    
495
    /**
496
     * @param int $id
497
     * @return AppPage
498
     */
499
    public function edit($container, $id = null)
500
    {
501
        $App = $this->App();
502
        $W = bab_Widgets();
503
        
504
        $customContainerSet = $App->CustomContainerSet();
505
        $container = $customContainerSet->request($customContainerSet->id->is($container));
506
        
507
        $customSectionSet = $App->CustomSectionSet();
508
        if(isset($id)){
509
            $record = $customSectionSet->request($id);
510
        }
511
        else{
512
            $record = $customSectionSet->newRecord();
513
            $record->container = $container->id;
514
        }
515
        
516
        $page = $App->Ui()->Page();
517
        
518
        $page->setTitle($App->translate('Section'));
519
        $page->addClass('app-page-editor');
520
        
521
        $editor = new AppEditor($App);
522
        $editor->setHiddenValue('tg', $App->controllerTg);
523
        if($record->id){
524
            $editor->setHiddenValue('data[id]', $record->id);
525
        }
526
        $editor->setName('data');
527
        
528
        $editor->addItem($W->LabelledWidget($App->translate('Name'), $W->LineEdit()
529
            ->setName('name')));
530
        
531
        $containers = $customContainerSet->select($customContainerSet->all(array(
532
            $customContainerSet->object->is($container->object),
533
            $customContainerSet->view->is($container->view)
534
        )))
535
            ->orderAsc($customContainerSet->rank);
536
        
537
        $options = array();
538
        $rank = 1;
539
        foreach ($containers as $container){
0 ignored issues
show
introduced by
$container is overwriting one of the parameters of this function.
Loading history...
540
            $options[$container->id] = sprintf('%d (%s)', $rank, $container->name);
541
            $rank ++;
542
        }
543
        
544
        $containerSections = $customSectionSet->select($customSectionSet->container->is($container->id))
545
            ->orderDesc($customSectionSet->rank);
546
        
547
        $nbSections = 0;
548
        foreach ($containerSections as $containerSection){
549
            $nbSections = $containerSection->rank + 1;
550
            break;
551
        }
552
        
553
        $editor->addItem($W->HBoxItems($W->LabelledWidget($App->translate('Container'), $W->Select()
554
            ->setOptions($options), 'container'), $W->LabelledWidget($App->translate('Element position'), $W->NumberEdit()
555
            ->setMin(0)
556
            ->setValue($nbSections), 'rank')));
557
        
558
        $sizePolicyClassnames = array(
559
            'col-md-1' => '1',
560
            'col-md-2' => '2',
561
            'col-md-3' => '3',
562
            'col-md-4' => '4',
563
            'col-md-5' => '5',
564
            'col-md-6' => '6',
565
            'col-md-7' => '7',
566
            'col-md-8' => '8',
567
            'col-md-9' => '9',
568
            'col-md-10' => '10',
569
            'col-md-11' => '11',
570
            'col-md-12' => '12',
571
            'left-panel' => 'left',
572
            'right-panel' => 'right'
573
        );
574
        
575
        $editor->addItem($W->LabelledWidget($App->translate('Size policy'), $W->Select()
576
            ->addOptions($sizePolicyClassnames)
577
            ->setName('sizePolicy')));
578
        $editor->addItem($W->LabelledWidget($App->translate('Fields layout'), $W->Select()
579
            ->addOptions(AppCustomSection::getFieldsLayouts())
580
            ->setName('fieldsLayout')));
581
        $editor->addItem($W->LabelledWidget($App->translate('Foldable'), $foldableCheckBox = $W->CheckBox()
582
            ->setName('foldable')));
583
        $editor->addItem($foldedWidget = $W->LabelledWidget($App->translate('Folded'), $W->CheckBox()
584
            ->setName('folded')));
585
        $editor->addItem($W->LabelledWidget($App->translate('Editable'), $W->CheckBox()
586
            ->setName('editable')));
587
        $editor->addItem($W->LabelledWidget($App->translate('Class'), $W->LineEdit()
588
            ->setName('classname')));
589
        
590
        $foldableCheckBox->setAssociatedDisplayable($foldedWidget, array(
591
            true
592
        ));
593
        
594
        $editor->setValues($record->getFormOutputValues(), array(
595
            'data'
596
        ));
597
        
598
        $editor->addButton($W->SubmitButton(/*'save'*/)
599
            ->validate(true)
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $validate of Widget_SubmitButton::validate(). ( Ignorable by Annotation )

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

599
            ->validate(/** @scrutinizer ignore-type */ true)
Loading history...
600
            ->setAction($this->proxy()
0 ignored issues
show
Bug introduced by
$this->proxy()->save() of type true is incompatible with the type Widget_Action|null expected by parameter $action of Widget_SubmitButton::setAction(). ( Ignorable by Annotation )

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

600
            ->setAction(/** @scrutinizer ignore-type */ $this->proxy()
Loading history...
601
            ->save())
602
            ->setAjaxAction()
603
            ->setLabel($App->translate('Save')));
604
        
605
        $editor->addButton($W->SubmitButton(/*'cancel'*/)
606
            ->addClass('widget-close-dialog')
607
            ->setLabel($App->translate('Cancel')));
608
        
609
        $page->addItem($editor);
610
        
611
        return $page;
612
    }
613
    
614
    /**
615
     * @param int $id
616
     * @return AppPage
617
     */
618
    public function editVisibility($id = null)
619
    {
620
        $App = $this->App();
621
        $Ui = $App->Ui();
622
        
623
        $page = $Ui->Page();
624
        
625
        $page->setTitle($App->translate('Section visibility'));
626
        $page->addClass('app-page-editor');
627
        
628
        $recordSet = $this->getRecordSet();
629
        $record = $recordSet->request($id);
630
        
631
        $object = $record->object;
632
        if(empty($object)){
633
            $object = $record->container()->object;
634
        }
635
        if(strpos($object, $App->classPrefix) !== false){
636
            $object = str_replace($App->classPrefix, '', $object);
637
        }
638
        $object .= 'Set';
639
        
640
        /* @var $objectRecordSet AppRecordSet */
641
        $objectRecordSet = $App->$object();
642
        
643
        $editor = $Ui->CriteriaEditor($objectRecordSet->all());
644
        $editor->setHiddenValue('data[id]', $record->id);
645
        $editor->setName('data');
646
        
647
        $manySets = $objectRecordSet->getHasManyRelations();
648
        $oneSets = $objectRecordSet->getHasOneRelations();
649
        
650
        if(! empty($record->visibilityCriteria)){
651
            $arrCriteria = json_decode($record->visibilityCriteria, true);
652
            
653
            $data = array();
654
            foreach ($arrCriteria as $fieldName => $operation){
655
                $data['field'] = $fieldName;
656
                foreach ($operation as $condition => $value){
657
                    $data['condition']['default'] = $condition;
658
                    $data['condition']['bool'] = $condition;
659
                    if(is_array($value)){
660
                        foreach ($value as $key => $subValue){
661
                            foreach ($manySets as $manyFieldName => $manyRelation){
662
                                if($key . 'Set' == $manyRelation->getForeignSetClassName()){
663
                                    foreach ($subValue as $subFieldName => $subConditions){
664
                                        if($subFieldName === '_foreignField'){
665
                                            continue;
666
                                        }
667
                                        $data['field'] = "{$manyFieldName}/{$subFieldName}";
668
                                        foreach ($subConditions as $subCondition => $subConditionValue){
669
                                            $data['condition']['default'] = $subCondition;
670
                                            $data['condition']['bool'] = $subCondition;
671
                                            $value = $subConditionValue;
672
                                        }
673
                                    }
674
                                    break;
675
                                }
676
                            }
677
                            foreach ($oneSets as $oneFieldName => $oneRelation){
678
                                if($key . 'Set' == $oneRelation->getForeignSetClassName()){
679
                                    foreach ($subValue as $subFieldName => $subConditions){
680
                                        if($subFieldName === '_foreignField'){
681
                                            continue;
682
                                        }
683
                                        $data['field'] = "{$oneFieldName}/{$subFieldName}";
684
                                        foreach ($subConditions as $subCondition => $subConditionValue){
685
                                            $data['condition']['default'] = $subCondition;
686
                                            $data['condition']['bool'] = $subCondition;
687
                                            $value = $subConditionValue;
688
                                        }
689
                                    }
690
                                    break;
691
                                }
692
                            }
693
                        }
694
                    }
695
                    $data['value'] = $value;
696
                }
697
            }
698
            
699
            $editor->setValues($data, array(
700
                'data'
701
            ));
702
        }
703
        
704
        $editor->setSaveAction($this->proxy()
705
            ->saveVisibility());
706
        $editor->isAjax = bab_isAjaxRequest();
707
        
708
        $page->addItem($editor);
709
        
710
        return $page;
711
    }
712
    
713
    /**
714
     * {@inheritdoc}
715
     * @see AppController::save()
716
     */
717
    public function save($data = null)
718
    {
719
        if(! isset($data['id']) && isset($data['container']) && $data['container'] != 0 && ! isset($data['rank'])){
720
            $set = $this->getRecordSet();
721
            $data['rank'] = $set->select($set->container->is($data['container']))
722
                ->count();
723
        }
724
        parent::save($data);
725
        
726
        $this->addReloadSelector('.depends-custom-sections');
727
        
728
        return true;
729
    }
730
    
731
    protected function postSave($record, $data)
732
    {
733
        parent::postSave($record, $data);
734
        $set = $record->getParentSet();
735
        
736
        $beforeSections = $set->select($set->all(array(
737
            $set->container->is($record->container),
738
            $set->id->isNot($record->id),
739
            $set->rank->lessThan($record->rank)
740
        )));
741
        
742
        $position = $beforeSections->count();
743
        $record->rank = $position;
744
        $record->save();
745
        
746
        $afterSections = $set->select($set->all(array(
747
            $set->container->is($record->container),
748
            $set->id->isNot($record->id),
749
            $set->rank->greaterThanOrEqual($record->rank)
750
        )));
751
        
752
        $position ++;
753
        foreach ($afterSections as $afterSection){
754
            $afterSection->rank = $position;
755
            $afterSection->save();
756
            $position ++;
757
        }
758
    }
759
    
760
    /**
761
     * {@inheritdoc}
762
     * @see AppCtrlRecord::delete()
763
     */
764
    public function delete($id)
765
    {
766
        parent::delete($id);
767
        
768
        $this->addReloadSelector('.depends-custom-sections');
769
        
770
        return true;
771
    }
772
    
773
    /**
774
     * @param array $data
775
     */
776
    public function saveVisibility($data = null)
777
    {
778
        $App = $this->App();
779
        
780
        $recordSet = $this->getRecordSet();
781
        $record = $recordSet->request($data['id']);
782
        
783
        $object = $record->object;
784
        if(empty($object)){
785
            $object = $record->container()->object;
786
        }
787
        if(strpos($object, $App->classPrefix) !== false){
788
            $object = str_replace($App->classPrefix, '', $object);
789
        }
790
        $object .= 'Set';
791
        
792
        $objectRecordSet = $App->$object();
793
        
794
        $field = $data['field'];
795
        $condition = $data['condition'];
796
        
797
        if(strpos($field, '/') !== false){
798
            // The selected field is a hasMany or a hasOne relation
799
            list ($selectedRelation, $selectedField) = explode('/', $field);
800
            $classPrefix = $App->classPrefix;
801
            
802
            $manyRelations = $objectRecordSet->getHasManyRelations();
803
            foreach ($manyRelations as $manyRelation){
804
                if($selectedRelation != $manyRelation->getOwnerSetFieldName()){
805
                    continue;
806
                }
807
                $foreignSetName = str_replace($classPrefix, '', $manyRelation->getForeignSetClassName());
808
                $foreignSet = $App->$foreignSetName();
809
                
810
                $visibilityCriteria = '';
811
                
812
                if($foreignSet){
813
                    $selectedManyField = $foreignSet->$selectedField;
814
                    
815
                    if($selectedManyField instanceof ORMBoolInterface){
816
                        $condition = $condition['bool'];
817
                    }
818
                    else{
819
                        $condition = $condition['default'];
820
                    }
821
                    
822
                    $criteria = $objectRecordSet->id->in($selectedManyField->{$condition}($data['value']), $manyRelation->getForeignFieldName());
823
                    
824
                    $visibilityCriteria = $criteria->toJson();
825
                }
826
                break;
827
            }
828
            
829
            $oneRelations = $objectRecordSet->getHasOneRelations();
830
            foreach ($oneRelations as $oneRelation){
831
                /* @var $oneRelation ORMOneRelation*/
832
                if($selectedRelation != $oneRelation->getOwnerSetFieldName()){
833
                    continue;
834
                }
835
                $foreignSetClassName = $oneRelation->getForeignSetClassName();
836
                $foreignSetName = str_replace($classPrefix, '', $foreignSetClassName);
837
                $foreignSet = $App->$foreignSetName();
838
                
839
                $visibilityCriteria = '';
840
                
841
                if($foreignSet){
842
                    $selectedOneField = $foreignSet->$selectedField;
843
                    
844
                    if($selectedOneField instanceof ORMBoolInterface){
845
                        $condition = $condition['bool'];
846
                    }
847
                    else{
848
                        $condition = $condition['default'];
849
                    }
850
                    
851
                    $criteria = $objectRecordSet->$selectedRelation()->$selectedField->{$condition}($data['value']);
852
                    $visibilityCriteria = $criteria->toJson();
853
                }
854
                break;
855
            }
856
        }
857
        else{
858
            
859
            $field = $objectRecordSet->$field;
860
            
861
            if($field instanceof ORMBoolInterface){
862
                $condition = $condition['bool'];
863
            }
864
            else{
865
                $condition = $condition['default'];
866
            }
867
            
868
            $visibilityCriteria = '';
869
            
870
            if(! empty($condition)){
871
                $criteria = $field->{$condition}($data['value']);
872
                $visibilityCriteria = $criteria->toJson();
873
            }
874
        }
875
        
876
        $record->visibilityCriteria = $visibilityCriteria;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $visibilityCriteria does not seem to be defined for all execution paths leading up to this point.
Loading history...
877
        
878
        $record->save();
879
        
880
        $this->addReloadSelector('.depends-custom-sections');
881
        
882
        return true;
883
    }
884
    
885
    /**
886
     * @param int $container
887
     * @param string $itemId
888
     * @return WidgetForm
889
     */
890
    public function sections($container, $itemId = null)
891
    {
892
        $W = bab_Widgets();
893
        $App = $this->App();
894
        
895
        $customContainerSet = $App->CustomContainerSet();
896
        $customContainer = $customContainerSet->request($container);
897
        
898
        $object = $customContainer->object;
899
        if(strpos($object, $App->classPrefix) !== false){
900
            list (, $object) = explode($App->classPrefix, $object);
901
        }
902
        
903
        $objectCtrl = $App->Controller()->$object(false);
904
        
905
        $availableFields = $objectCtrl->getAvailableDisplayFields();
906
        
907
        $sectionsSection = $W->VBoxItems();
908
        
909
        $customSectionCtrl = $App->Controller()->CustomSection();
910
        
911
        $customSectionSet = $App->CustomSectionSet();
912
        $customSections = $customSectionSet->select($customSectionSet->container->is($container));
913
        $customSections->orderAsc($customSectionSet->rank);
914
        
915
        $sectionsBoxes = array();
916
        /* @var $rows WidgetLayout[] */
917
        $rows = array();
918
        
919
        $currentColumn = 0;
920
        $row = $W->FlowItems()->addClass('connectedSortable'); // ->setSizePolicy('row');
921
        $row->addClass('widget-sameheight-elements');
922
        $rows[] = $row;
923
        
924
        $nbCol = 0;
925
        
926
        foreach ($customSections as $customSection){
927
            
928
            list (, , $nbCol) = explode('-', $customSection->sizePolicy);
929
            
930
            $currentColumn += $nbCol;
931
            
932
            $sectionSection = $W->Section($customSection->name . ' (' . $customSection->rank . ')', $sectionBox = $W->VBoxItems($W->Hidden()
933
                ->setName('#' . $customSection->id)));
934
            $sectionSection->addClass('app-custom-section');
935
            $sectionSection->addClass($customSection->classname);
936
            $sectionSection->setSizePolicy($customSection->sizePolicy . ' widget-sameheight');
937
            
938
            $row->addItem($sectionSection);
939
            
940
            $menu = $sectionSection->addContextMenu('inline');
941
            $menu->addItem($W->HBoxItems($W->Link('', $customSectionCtrl->addDisplayField($customSection->id))
942
                ->addClass('icon', \Func_Icons::ACTIONS_LIST_ADD)
943
                ->setOpenMode(WidgetLink::OPEN_DIALOG)
944
                ->setDialogClass($customSection->classname), $W->Link('', $customSectionCtrl->edit($container, $customSection->id))
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

944
                ->/** @scrutinizer ignore-call */ setDialogClass($customSection->classname), $W->Link('', $customSectionCtrl->edit($container, $customSection->id))

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...
945
                ->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_EDIT)
946
                ->setOpenMode(WidgetLink::OPEN_DIALOG)
947
                ->setDialogClass($customSection->classname), $W->Link('', $customSectionCtrl->editVisibility($customSection->id))
948
                ->addClass('icon', \Func_Icons::ACTIONS_SET_ACCESS_RIGHTS)
949
                ->setOpenMode(WidgetLink::OPEN_DIALOG)
950
                ->setDialogClass($customSection->classname), $W->Link('', $customSectionCtrl->confirmDelete($customSection->id))
951
                ->addClass('icon', \Func_Icons::ACTIONS_EDIT_DELETE)
952
                ->setOpenMode(WidgetLink::OPEN_DIALOG)
953
                ->setDialogClass('box red')));
954
            if(! empty($customSection->visibilityCriteria)){
955
                $sectionBox->addItem($W->HBoxItems($W->Label($App->translate('This section has a visibility condition')))
956
                    ->setSizePolicy('alert alert-warning widget-100pc'));
957
            }
958
            $fields = $customSection->getFields();
959
            if(count($fields) == 0){
960
                $sectionBox->addItem($W->HBoxItems($W->Label($App->translate('This section does not contain any field')))
961
                    ->setSizePolicy('alert alert-warning'));
962
            }
963
            foreach ($fields as $fieldId => $field){
964
                if(empty($field)){
965
                    continue;
966
                }
967
                
968
                $fieldName = $field['fieldname'];
969
                
970
                $isFieldsGroup = false;
971
                if(strpos($fieldName, '_fieldsGroup') !== false){
972
                    $fieldName = '_fieldsGroup';
973
                    $isFieldsGroup = true;
974
                }
975
                
976
                $field = $availableFields[$fieldName];
977
                $fieldDescription = $field['description'];
978
                if(substr($fieldName, 0, 1) !== '_'){
979
                    $fieldDescription = $App->translate($fieldDescription);
980
                }
981
                
982
                if(empty($field)){
983
                    continue;
984
                }
985
                
986
                $fieldName = $field['name'];
987
                if($isFieldsGroup){
988
                    $fieldName = $fieldId;
989
                }
990
                
991
                $flexFields = array();
992
                
993
                $fieldItem = $W->HBoxItems($W->VBoxItems($W->Label($fieldDescription)
994
                    ->addClass('icon', \Func_Icons::ACTIONS_ZOOM_FIT_HEIGHT), $fieldGroupBox = $W->FlexItems()
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

994
                    ->addClass('icon', \Func_Icons::ACTIONS_ZOOM_FIT_HEIGHT), $fieldGroupBox = $W->/** @scrutinizer ignore-call */ FlexItems()

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...
995
                    ->setGrowable(true)
996
                    ->setWrap(WidgetFlexLayout::FLEX_WRAP_WRAP))
997
                    ->setSizePolicy('maximum'), $btnBox = $W->HBoxItems($W->Hidden()
998
                    ->setName($customSection->id . '.' . $fieldId)
999
                    ->setValue($fieldName))
1000
                    ->addClass('widget-actions'))
1001
                    ->setSizePolicy('widget-list-element widget-actions-target')
1002
                    ->addClass(\Func_Icons::ICON_LEFT_16);
1003
                if(strpos($field['name'], '_fieldsGroup') !== false){
1004
                    $btnBox->addItem($W->Link('', $customSectionCtrl->addDisplayFieldToGroup($customSection->id, $fieldName))
1005
                        ->addClass('icon', \Func_Icons::ACTIONS_LIST_ADD)
1006
                        ->setOpenMode(WidgetLink::OPEN_DIALOG));
1007
                    $groupedFields = $fields[$fieldName]['fields'];
1008
                    foreach ($groupedFields as $groupedField){
1009
                        $groupedFieldDetails = $availableFields[$groupedField['fieldname']];
1010
                        $fieldGroupBox->addItem($flexField = $W->FlowItems($W->Hidden(null, array(
0 ignored issues
show
Bug introduced by
array($customSection->id...upedField['fieldname']) of type array<integer,mixed|string> is incompatible with the type string expected by parameter $name of Func_Widgets::Hidden(). ( Ignorable by Annotation )

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

1010
                        $fieldGroupBox->addItem($flexField = $W->FlowItems($W->Hidden(null, /** @scrutinizer ignore-type */ array(
Loading history...
1011
                            $customSection->id . '.fieldsGroups',
1012
                            $fieldName,
1013
                            $groupedField['fieldname']
1014
                        ), $groupedField['fieldname']), $W->Label($groupedFieldDetails['description']), $W->FlowItems($W->Link('', $customSectionCtrl->editGroupFieldDisplayField($customSection->id, $fieldName, $groupedField['fieldname']))
1015
                            ->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_EDIT)
1016
                            ->setOpenMode(WidgetLink::OPEN_DIALOG), $W->Link('', $customSectionCtrl->removeDisplayFieldFromGroup($customSection->id, $fieldName, $groupedField['fieldname']))
1017
                            ->addClass('icon', \Func_Icons::ACTIONS_LIST_REMOVE)
1018
                            ->setAjaxAction()))
1019
                            ->addClass('app-customsection-groupedfield'));
1020
                        $flexFields[] = $flexField;
1021
                    }
1022
                }
1023
                
1024
                $fieldGroupBox->sortable(true, $flexFields);
1025
                $fieldGroupBox->setMetadata('samePlaceholderSize', true);
1026
                
1027
                $btnBox->addItems($W->Link('', $customSectionCtrl->editDisplayField($customSection->id, $fieldName))
1028
                    ->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_EDIT)
1029
                    ->setOpenMode(WidgetLink::OPEN_DIALOG), $W->Link('', $customSectionCtrl->removeDisplayField($customSection->id, $fieldName))
1030
                    ->addClass('icon', \Func_Icons::ACTIONS_LIST_REMOVE)
1031
                    ->setAjaxAction());
1032
                
1033
                $sectionBox->addItem($fieldItem);
1034
            }
1035
            
1036
            $sectionsBoxes[] = $sectionBox;
1037
        }
1038
        
1039
        if($currentColumn + $nbCol > 0){
1040
            $sectionsSection->addItem($row);
1041
        }
1042
        
1043
        foreach ($sectionsBoxes as $sectionsBox){
1044
            $sectionsBox->sortable(true, $sectionsBoxes);
1045
            $sectionsBox->setMetadata('samePlaceholderSize', true);
1046
        }
1047
        
1048
        foreach ($rows as $row){
1049
            $row->sortable(true, $rows);
1050
            $row->setMetadata('samePlaceholderSize', true);
1051
        }
1052
        
1053
        $form = $W->Form();
1054
        
1055
        if(isset($itemId)){
1056
            $form->setId($itemId);
1057
        }
1058
        $form->setHiddenValue('tg', $App->controllerTg);
1059
        $form->setName('sections');
1060
        $form->addItem($sectionsSection);
1061
        $form->setAjaxAction($this->proxy()
0 ignored issues
show
Bug introduced by
$this->proxy()->saveSections() of type true is incompatible with the type Widget_Action|null expected by parameter $action of Widget_Widget::setAjaxAction(). ( Ignorable by Annotation )

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

1061
        $form->setAjaxAction(/** @scrutinizer ignore-type */ $this->proxy()
Loading history...
1062
            ->saveSections(), $sectionsSection, 'sortstop');
1063
        $form->setReloadAction($this->proxy()
1064
            ->sections($container, $form->getId()));
1065
        
1066
        $form->addClass('depends-custom-sections');
1067
        
1068
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type Widget_Form which is incompatible with the documented return type Capwelton\Widgets\Widgets\Form\WidgetForm.
Loading history...
1069
    }
1070
    
1071
    /**
1072
     * @param string $view
1073
     */
1074
    public function exportSections($container)
1075
    {
1076
        $App = $this->App();
1077
        $customSectionSet = $App->CustomSectionSet();
1078
        
1079
        $customSections = $customSectionSet->select($customSectionSet->container->is($container));
1080
        
1081
        $sectionsValues = array();
1082
        foreach ($customSections as $customSection){
1083
            $values = $customSection->getValues();
1084
            unset($values['id']);
1085
            unset($values['createdBy']);
1086
            unset($values['createdOn']);
1087
            unset($values['modifiedBy']);
1088
            unset($values['modifiedOn']);
1089
            unset($values['deletedBy']);
1090
            unset($values['deletedOn']);
1091
            unset($values['deleted']);
1092
            $sectionsValues[] = $values;
1093
        }
1094
        
1095
        header('Content-type: application/json');
1096
        header('Content-Disposition: attachment; filename="' . $container->object . '.' . ($container->view === '' ? 'default' : $container->view) . '.' . $container->name . '.json"' . "\n");
1097
        
1098
        $json = bab_json_encode($sectionsValues);
1099
        $json = bab_convertStringFromDatabase($json, \bab_charset::UTF_8);
1100
        
1101
        die($json);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1102
    }
1103
    
1104
    /**
1105
     * @param string $view
1106
     * @return AppPage
1107
     */
1108
    public function importSectionsConfirm($container)
1109
    {
1110
        $App = $this->App();
1111
        $W = bab_Widgets();
1112
        
1113
        $page = $App->Ui()->Page();
1114
        
1115
        $page->setTitle($App->translate('Import sections layout'));
1116
        
1117
        $editor = new AppEditor($App);
1118
        $editor->setHiddenValue('tg', $App->controllerTg);
1119
        $editor->setHiddenValue('container', $container);
1120
        
1121
        $editor->addItem($W->LabelledWidget($App->translate('View layout name'), $W->LineEdit(), 'view'));
1122
        
1123
        $editor->addItem($W->LabelledWidget($App->translate('File'), $W->FilePicker(), 'sectionsfile'));
1124
        
1125
        $editor->setSaveAction($this->proxy()
1126
            ->importSections());
1127
        
1128
        $page->addItem($editor);
1129
        
1130
        return $page;
1131
    }
1132
    
1133
    /**
1134
     * @param string $view
1135
     * @param string $sectionsfile
1136
     * @return bool
1137
     */
1138
    public function importSections($container = null, $sectionsfile = null)
1139
    {
1140
        $App = $this->App();
1141
        $W = bab_Widgets();
1142
        
1143
        $files = $W->FilePicker()->getFolder();
1144
        $files->push('sectionsfile');
1145
        $files->push($sectionsfile['uid']);
1146
        
1147
        $data = null;
1148
        foreach ($files as $f){
1149
            $data = file_get_contents($f->toString());
1150
            break;
1151
        }
1152
        
1153
        if(! isset($data)){
1154
            $this->addError($App->translate('Unable to get file content'));
1155
            return true;
1156
        }
1157
        
1158
        $sectionsValues = json_decode($data, true);
1159
        
1160
        $App = $this->App();
1161
        $customSectionSet = $App->CustomSectionSet();
1162
        
1163
        $customSectionSet->delete($customSectionSet->container->is($container));
1164
        
1165
        foreach ($sectionsValues as $sectionValues){
1166
            $customSection = $customSectionSet->newRecord();
1167
            $customSection->setValues($sectionValues);
1168
            $customSection->container = $container;
1169
            $customSection->save();
1170
        }
1171
        
1172
        return true;
1173
    }
1174
    
1175
    /**
1176
     * @param int $container
1177
     * @return bool
1178
     */
1179
    public function deleteSections($container)
1180
    {
1181
        $App = $this->App();
1182
        $customSectionSet = $App->CustomSectionSet();
1183
        
1184
        $customSectionSet->delete($customSectionSet->container->is($container));
1185
        
1186
        return true;
1187
    }
1188
    
1189
    /**
1190
     * Display an user interface to edit sections associated to a specific container.
1191
     *
1192
     * @param int $container
1193
     * @return AppPage
1194
     */
1195
    public function editSections($container)
1196
    {
1197
        $App = $this->App();
1198
        $W = bab_Widgets();
1199
        $Ui = $App->Ui();
1200
        
1201
        $customContainerSet = $App->CustomContainerSet();
1202
        $customContainer = $customContainerSet->request($container);
1203
        
1204
        $object = $customContainer->object;
0 ignored issues
show
Unused Code introduced by
The assignment to $object is dead and can be removed.
Loading history...
1205
        
1206
        $page = $Ui->Page();
1207
        
1208
        $page->setTitle(sprintf($App->translate('Edit view layout %s'), $customContainer->view));
1209
        
1210
        $toolbar = $Ui->Toolbar();
1211
        
1212
        $toolbar->addItem($W->Link($App->translate('Delete view layout'), $this->proxy()
0 ignored issues
show
Bug introduced by
$this->proxy()->deleteSections($container) of type true is incompatible with the type Widget_Action|bab_url|string expected by parameter $url of Func_Widgets::Link(). ( Ignorable by Annotation )

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

1212
        $toolbar->addItem($W->Link($App->translate('Delete view layout'), /** @scrutinizer ignore-type */ $this->proxy()
Loading history...
1213
            ->deleteSections($container))
1214
            ->addClass('widget-actionbutton', 'icon', \Func_Icons::ACTIONS_EDIT_DELETE));
1215
        
1216
        $toolbar->addItem($W->Link($App->translate('Export view layout'), $this->proxy()
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->proxy()->exportSections($container) targeting Capwelton\LibApp\Ctrl\Ap...ction::exportSections() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1217
            ->exportSections($container))
1218
            ->addClass('widget-actionbutton', 'icon', \Func_Icons::ACTIONS_DOCUMENT_DOWNLOAD));
1219
        
1220
        $toolbar->addItem($W->Link($App->translate('Add a section'), $this->proxy()
1221
            ->edit($container))
1222
            ->addClass('widget-actionbutton', 'icon', \Func_Icons::ACTIONS_LIST_ADD)
1223
            ->setOpenMode(WidgetLink::OPEN_DIALOG));
1224
        
1225
        $form = $this->sections($container);
1226
        
1227
        $page->addItem($toolbar);
1228
        $page->addItem($form);
1229
        
1230
        return $page;
1231
    }
1232
    
1233
    public function saveSections($sections = null)
1234
    {
1235
        $App = $this->App();
1236
        $customSectionSet = $App->CustomSectionSet();
1237
        
1238
        $oldSectionId = null;
1239
        $rawSectionData = array();
1240
        $ranks = array();
1241
        $rank = 0;
1242
        
1243
        foreach ($sections as $key => $value){
1244
            // Sections ids start with #, while section fields start with their original section id
1245
            if(substr($key, 0, 1) === '#'){
1246
                $currentSectionId = substr($key, 1);
1247
                $rawSectionData[$currentSectionId] = array();
1248
                if(! isset($oldSectionId)){
1249
                    $oldSectionId = $currentSectionId;
1250
                }
1251
                if(isset($currentSection) && $oldSectionId != $currentSectionId){
1252
                    $oldSectionId = $currentSectionId;
1253
                }
1254
                $ranks[$currentSectionId] = $rank;
1255
                $rank ++;
1256
                $currentSection = $customSectionSet->get($customSectionSet->id->is($currentSectionId));
1257
                continue;
1258
            }
1259
            if(! isset($currentSection)){
1260
                continue;
1261
            }
1262
            list ($fieldSectionId, $fieldName) = explode('.', $key);
1263
            if($fieldSectionId == $currentSectionId){
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $currentSectionId seems to be defined later in this foreach loop on line 1246. Are you sure it is defined here?
Loading history...
1264
                $field = $currentSection->getField($fieldName);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $currentSection seems to be defined later in this foreach loop on line 1256. Are you sure it is defined here?
Loading history...
1265
                if(strpos($fieldName, '_fieldsGroup') !== false){
1266
                    $rawSectionData[$currentSectionId][$fieldName]['block'] = $field['block'];
1267
                    $rawSectionData[$currentSectionId][$fieldName]['fieldname'] = '_fieldsGroup';
1268
                    $rawSectionData[$currentSectionId][$fieldName]['parameters'] = $field['parameters'];
1269
                    foreach ($sections[$currentSection->id . '.fieldsGroups'][$fieldName] as $subKey => $subValue){
1270
                        $rawSectionData[$currentSectionId][$fieldName]['fields'][$subKey] = $field['fields'][$subKey];
1271
                    }
1272
                }
1273
                elseif($fieldName != 'fieldsGroups'){
1274
                    $rawSectionData[$currentSectionId][$fieldName] = $field;
1275
                }
1276
            }
1277
            else{
1278
                $field = null;
1279
                $tmpSection = $customSectionSet->get($customSectionSet->id->is($fieldSectionId));
1280
                if($tmpSection){
1281
                    $field = $tmpSection->getField($fieldName);
1282
                }
1283
                if(isset($field)){
1284
                    $rawSectionData[$currentSectionId][$fieldName] = $field;
1285
                }
1286
            }
1287
        }
1288
        
1289
        foreach ($rawSectionData as $sectionId => $fields){
1290
            $section = $customSectionSet->get($customSectionSet->id->is($sectionId));
1291
            if($section){
1292
                if(bab_charset::getIso() != bab_charset::UTF_8){
1293
                    $fields = app_utf8Encode($fields);
1294
                }
1295
                $section->fields = json_encode($fields);
1296
                $section->rank = isset($ranks[$sectionId]) ? $ranks[$sectionId] : 0;
1297
                $section->save();
1298
                $rank ++;
1299
            }
1300
        }
1301
        
1302
        $this->addReloadSelector('.depends-custom-sections');
1303
        return true;
1304
    }
1305
}
1306