Passed
Push — master ( 3da5e2...bdc2db )
by Laurent
06:49 queued 02:09
created

app_CtrlCustomSection::editDisplayField()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 73
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 47
nc 5
nop 2
dl 0
loc 73
rs 9.1563
c 0
b 0
f 0

How to fix   Long Method   

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) 2008 by CANTICO ({@link http://www.cantico.fr})
22
 */
23
24
25
require_once APP_CTRL_PATH . '/record.ctrl.php';
26
27
28
/**
29
 * This controller manages actions that can be performed on custom sections
30
 *
31
 * @method Func_App App()
32
 */
33
class app_CtrlCustomSection extends app_CtrlRecord
34
{
35
    /**
36
     * @param string $itemId
37
     * @return Widget_VBoxLayout
38
     */
39
    public function availableDisplayFields($section = null, $itemId = null)
40
    {
41
        $W = bab_Widgets();
42
        $App = $this->App();
43
44
        $customSectionSet = $App->CustomSectionSet();
45
46
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
47
48
        $object = $customSection->object;
49
        $objectCtrl = $App->Controller()->$object(false);
50
51
        $allViewSections = $customSectionSet->select(
52
            $customSectionSet->view->is($customSection->view)->_AND_(
53
                $customSectionSet->object->is($customSection->object)
54
            )
55
        );
56
57
        $allViewFieldNames = array();
58
        foreach ($allViewSections as $viewSection) {
59
            $fields = $viewSection->getFields();
60
            foreach ($fields as $field) {
61
                $allViewFieldNames[$field['fieldname']] = $viewSection->view . ',' . $viewSection->rank . ',' . $viewSection->id;
62
            }
63
        }
64
65
        $box = $W->VBoxItems();
66
        if (isset($itemId)) {
67
            $box->setId($itemId);
68
        }
69
70
        $box->addItem(
71
            $W->Link(
72
                $App->translate('Create new field'),
73
                $App->Controller()->CustomField()->add($customSection->object)
0 ignored issues
show
Bug introduced by
The method add() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomField. ( Ignorable by Annotation )

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

73
                $App->Controller()->CustomField()->/** @scrutinizer ignore-call */ add($customSection->object)
Loading history...
74
            )->setOpenMode(widget_Link::OPEN_DIALOG_AND_RELOAD)
75
            ->addClass('widget-actionbutton', 'icon', Func_Icons::ACTIONS_LIST_ADD)
76
            ->setSizePolicy(Func_Icons::ICON_LEFT_SYMBOLIC)
77
        );
78
79
        $availableFields = $objectCtrl->getAvailableDisplayFields();
80
81
        bab_Sort::asort($availableFields, 'description', bab_Sort::CASE_INSENSITIVE);
82
83
        foreach ($availableFields as $field) {
84
            $fieldName =  $field['name'];
85
            $fieldDescription = $field['description'];
86
87
            $used = isset($allViewFieldNames[$fieldName]);
88
            $box->addItem(
89
                $W->VBoxItems(
90
                    $W->Link(
91
                        $fieldDescription,
92
                        $this->proxy()->saveDisplayField($section, $fieldName)
0 ignored issues
show
Bug introduced by
The method saveDisplayField() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

92
                        $this->proxy()->/** @scrutinizer ignore-call */ saveDisplayField($section, $fieldName)
Loading history...
93
                    )->addClass('widget-close-dialog', ($used ? 'widget-strong' : ''))
94
                    ->setTitle($fieldName)
95
                    ->setAjaxAction(),
96
                    $W->Hidden()->setName(array('sections', $field['name']))
97
                )->setSizePolicy('widget-list-element')
98
            );
99
        }
100
101
        $box->addClass('widget-3columns');
102
103
        $box->setReloadAction($this->proxy()->availableDisplayFields($section, $box->getId()));
0 ignored issues
show
Bug introduced by
The method availableDisplayFields() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

103
        $box->setReloadAction($this->proxy()->/** @scrutinizer ignore-call */ availableDisplayFields($section, $box->getId()));
Loading history...
104
105
        return $box;
106
    }
107
108
109
    /**
110
     *
111
     */
112
    public function addDisplayField($section = null, $filter = null)
113
    {
114
        $App = $this->App();
115
116
        $page = $App->Ui()->Page();
117
        $page->setTitle($App->translate('Available fields'));
118
119
        $box = $this->availableDisplayFields($section);
120
121
        $page->addItem($box);
122
        return $page;
123
    }
124
125
126
    /**
127
     *
128
     * @param int $section
129
     * @param string $fieldName
130
     * @return app_Page
131
     */
132
    public function editDisplayField($section, $fieldName)
133
    {
134
        $App = $this->App();
135
        $customSectionSet = $App->CustomSectionSet();
136
137
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
138
139
        $field = $customSection->getField($fieldName);
140
141
        if (!isset($field)) {
142
            return null;
143
        }
144
145
        $W = bab_Widgets();
146
147
        $object = $customSection->object;
148
        $objectCtrl = $App->Controller()->$object(false);
149
150
        $fieldName = $field['fieldname'];
151
        $params = $field['parameters'];
152
153
        $availableFields = $objectCtrl->getAvailableDisplayFields();
154
        $field = $availableFields[$fieldName];
155
        $fieldDescription = $field['description'];
156
        if (substr($fieldName, 0, 1) !== '_') {
0 ignored issues
show
Bug introduced by
$fieldName of type array is incompatible with the type string expected by parameter $string of substr(). ( Ignorable by Annotation )

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

156
        if (substr(/** @scrutinizer ignore-type */ $fieldName, 0, 1) !== '_') {
Loading history...
157
            $fieldDescription = $App->translate($fieldDescription);
158
        }
159
160
        if (empty($field)) {
161
            //continue;
162
        }
163
164
        $page = $App->Ui()->Page();
165
        $page->setTitle($fieldDescription);
166
167
        $editor = new app_Editor($App);
168
        $editor->setHiddenValue('tg', $App->controllerTg);
169
        $editor->setHiddenValue('section', $section);
170
        $editor->setHiddenValue('fieldName', $fieldName);
171
172
        $box = $W->VBoxItems(
173
            $W->LabelledWidget(
174
                $App->translate('Type'),
175
                $W->Select()
176
                    ->setName(array('parameters', 'type'))
177
                    ->addOption('', '')
178
                    ->addOption('title1', $App->translate('Title 1'))
179
                    ->addOption('title2', $App->translate('Title 2'))
180
                    ->addOption('title3', $App->translate('Title 3'))
181
            ),
182
            $W->LabelledWidget(
183
                $App->translate('Label'),
184
                $W->LineEdit()
185
                    ->setName(array('parameters', 'label'))
186
            ),
187
            $W->LabelledWidget(
188
                $App->translate('Class'),
189
                $W->LineEdit()
190
                    ->setName(array('parameters', 'classname'))
191
            )
192
        )->setVerticalSpacing(1, 'em');
193
194
        $editor->setValues($params, array('parameters'));
195
196
        $editor->addItem($box);
197
198
        $editor->setSaveAction($this->proxy()->saveDisplayField());
199
200
        $editor->isAjax = true;
201
202
        $page->addItem($editor);
203
204
        return $page;
205
    }
206
207
208
209
    /**
210
     *
211
     * @param int $section
212
     * @param string $fieldName
213
     * @return boolean
214
     */
215
    public function saveDisplayField($section = null, $fieldName = null, $parameters = null)
216
    {
217
        $App = $this->App();
218
        $customSectionSet = $App->CustomSectionSet();
219
220
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
221
        $customSection->removeField($fieldName);
222
        $customSection->addField($fieldName, $parameters);
223
        $customSection->save();
224
225
        $this->addReloadSelector('.depends-custom-sections');
226
227
        return true;
228
    }
229
230
231
    /**
232
     *
233
     * @param int $section
234
     * @param string $fieldName
235
     * @return boolean
236
     */
237
    public function removeDisplayField($section, $fieldName)
238
    {
239
        $App = $this->App();
240
        $customSectionSet = $App->CustomSectionSet();
241
242
        $customSection = $customSectionSet->request($customSectionSet->id->is($section));
243
244
        $customSection->removeField($fieldName);
245
        $customSection->save();
246
        $this->addReloadSelector('.depends-custom-sections');
247
        return true;
248
    }
249
250
251
252
253
    /**
254
     * @param string    $view
255
     * @param int       $id
256
     * @param string    $object
257
     * @return app_Page
258
     */
259
    public function edit($view, $id = null, $object = null)
260
    {
261
        $App = $this->App();
262
        $W = bab_Widgets();
263
264
        $customSectionSet = $App->CustomSectionSet();
265
        if (isset($id)) {
266
            $record = $customSectionSet->request($id);
267
        } else {
268
            $record = $customSectionSet->newRecord();
269
            $record->object = $object;
270
        }
271
272
        $page = $App->Ui()->Page();
273
274
        $page->setTitle($App->translate('Section'));
275
        $page->addClass('app-page-editor');
276
277
        $editor = new app_Editor($App);
278
        $editor->setHiddenValue('tg', $App->controllerTg);
279
        $editor->setHiddenValue('data[view]', $view);
280
        if ($record->id) {
281
            $editor->setHiddenValue('data[id]', $record->id);
282
        }
283
        $editor->setName('data');
0 ignored issues
show
Bug introduced by
The method setName() does not exist on app_Editor. 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

283
        $editor->/** @scrutinizer ignore-call */ 
284
                 setName('data');
Loading history...
284
        $editor->addItem(
285
            $W->Hidden()->setName('object')
286
        );
287
288
        $editor->addItem(
289
            $W->LabelledWidget(
290
                $App->translate('Name'),
291
                $W->LineEdit()->setName('name')
292
            )
293
        );
294
295
        $sizePolicyClassnames = array(
296
            'col-md-1' => '1',
297
            'col-md-2' => '2',
298
            'col-md-3' => '3',
299
            'col-md-4' => '4',
300
            'col-md-5' => '5',
301
            'col-md-6' => '6',
302
            'col-md-7' => '7',
303
            'col-md-8' => '8',
304
            'col-md-9' => '9',
305
            'col-md-10' => '10',
306
            'col-md-11' => '11',
307
            'col-md-12' => '12',
308
        );
309
310
311
        $editor->addItem(
312
            $W->LabelledWidget(
313
                $App->translate('Size policy'),
314
                $W->Select()
315
                    ->addOptions($sizePolicyClassnames)
316
                    ->setName('sizePolicy')
317
            )
318
        );
319
        $editor->addItem(
320
            $W->LabelledWidget(
321
                $App->translate('Fields layout'),
322
                $W->Select()
323
                    ->addOptions(app_CustomSection::getFieldsLayouts())
324
                    ->setName('fieldsLayout')
325
            )
326
        );
327
        $editor->addItem(
328
            $W->LabelledWidget(
329
                $App->translate('Foldable'),
330
                $foldableCheckBox = $W->CheckBox()->setName('foldable')
331
            )
332
        );
333
        $editor->addItem(
334
            $foldedWidget = $W->LabelledWidget(
335
                $App->translate('Folded'),
336
                $W->CheckBox()->setName('folded')
337
            )
338
        );
339
        $editor->addItem(
340
            $W->LabelledWidget(
341
                $App->translate('Editable'),
342
                $W->CheckBox()->setName('editable')
343
            )
344
        );
345
        $editor->addItem(
346
            $W->LabelledWidget(
347
                $App->translate('Class'),
348
                $W->LineEdit()->setName('classname')
349
            )
350
        );
351
352
        $foldableCheckBox->setAssociatedDisplayable($foldedWidget, array(true));
353
354
        $editor->setValues($record->getFormOutputValues(), array('data'));
355
356
        $editor->addButton(
357
            $W->SubmitButton(/*'save'*/)
358
                ->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

358
                ->validate(/** @scrutinizer ignore-type */ true)
Loading history...
359
                ->setAction($this->proxy()->save())
0 ignored issues
show
introduced by
The method save() does not exist on app_Controller. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

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

359
                ->setAction($this->proxy()->/** @scrutinizer ignore-call */ save())
Loading history...
360
                ->setAjaxAction()
361
            ->setLabel($App->translate('Save'))
362
        );
363
364
        $editor->addButton(
365
            $W->SubmitButton(/*'cancel'*/)
366
                ->addClass('widget-close-dialog')
367
            ->setLabel($App->translate('Cancel'))
368
        );
369
370
        $page->addItem($editor);
371
372
        return $page;
373
    }
374
375
376
    /**
377
     *
378
     * @param int $id
379
     * @return app_Page
380
     */
381
    public function editVisibility($id = null)
382
    {
383
        $App = $this->App();
384
385
        $page = $App->Ui()->Page();
386
387
        $page->setTitle($App->translate('Section visibility'));
388
        $page->addClass('app-page-editor');
389
390
        $recordSet = $this->getRecordSet();
391
        $record = $recordSet->request($id);
392
393
        $object = $record->object . 'Set';
0 ignored issues
show
Bug Best Practice introduced by
The property object does not exist on app_Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
394
395
        $objectRecordSet = $App->$object();
396
397
398
        $editor = $App->Ui()->CriteriaEditor($objectRecordSet->all());
0 ignored issues
show
Bug introduced by
The method CriteriaEditor() does not exist on app_Ui. ( Ignorable by Annotation )

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

398
        $editor = $App->Ui()->/** @scrutinizer ignore-call */ CriteriaEditor($objectRecordSet->all());

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...
399
        $editor->setHiddenValue('data[id]', $record->id);
0 ignored issues
show
Bug Best Practice introduced by
The property id does not exist on app_Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
400
        $editor->setName('data');
401
402
        if (!empty($record->visibilityCriteria)) {
0 ignored issues
show
Bug Best Practice introduced by
The property visibilityCriteria does not exist on app_Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
403
            $arrCriteria = json_decode($record->visibilityCriteria, true);
404
405
            $data = array();
406
            foreach ($arrCriteria as $fieldName => $operation) {
407
                $data['field'] = $fieldName;
408
                foreach ($operation as $condition => $value) {
409
                    $data['condition']['default'] = $condition;
410
                    $data['condition']['bool'] = $condition;
411
                    $data['value'] = $value;
412
                }
413
            }
414
415
            $editor->setValues($data, array('data'));
416
        }
417
418
419
        $editor->setSaveAction($this->proxy()->saveVisibility());
0 ignored issues
show
Bug introduced by
The method saveVisibility() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

419
        $editor->setSaveAction($this->proxy()->/** @scrutinizer ignore-call */ saveVisibility());
Loading history...
420
        $editor->isAjax = bab_isAjaxRequest();
421
422
        $page->addItem($editor);
423
424
        return $page;
425
    }
426
427
428
429
    /**
430
     * {@inheritDoc}
431
     * @see app_Controller::save()
432
     */
433
    public function save($data = null)
434
    {
435
        parent::save($data);
436
437
        $this->addReloadSelector('.depends-custom-sections');
438
439
        return true;
440
    }
441
442
443
    /**
444
     * {@inheritDoc}
445
     * @see app_CtrlRecord::delete()
446
     */
447
    public function delete($id)
448
    {
449
        parent::delete($id);
450
451
        $this->addReloadSelector('.depends-custom-sections');
452
453
        return true;
454
    }
455
456
457
    /**
458
     * @param array $data
459
     */
460
    public function saveVisibility($data = null)
461
    {
462
        $App = $this->App();
463
464
        $recordSet = $this->getRecordSet();
465
        $record = $recordSet->request($data['id']);
466
467
        $object = $record->object . 'Set';
0 ignored issues
show
Bug Best Practice introduced by
The property object does not exist on app_Record. Since you implemented __get, consider adding a @property annotation.
Loading history...
468
469
        $objectRecordSet = $App->$object();
470
471
        $field = $data['field'];
472
473
        $field = $objectRecordSet->$field;
474
475
        $condition = $data['condition'];
476
477
        if ($field instanceof ORM_BoolInterface) {
478
            $condition = $condition['bool'];
479
        } else {
480
            $condition = $condition['default'];
481
        }
482
483
        $criteria = $field->{$condition}($data['value']);
484
485
        $record->visibilityCriteria = $criteria->toJson();
0 ignored issues
show
Bug Best Practice introduced by
The property visibilityCriteria does not exist on app_Record. Since you implemented __set, consider adding a @property annotation.
Loading history...
486
487
        $record->save();
488
489
        $this->addReloadSelector('.depends-custom-sections');
490
491
        return true;
492
    }
493
494
495
496
497
498
499
    /**
500
     *
501
     * @param string $view
502
     * @param string $itemId
503
     * @return Widget_Form
504
     */
505
    public function sections($object, $view, $itemId = null)
506
    {
507
        $W = bab_Widgets();
508
        $App = $this->App();
509
510
        $objectCtrl = $App->Controller()->$object(false);
511
512
        $availableFields = $objectCtrl->getAvailableDisplayFields();
513
514
        $sectionsSection = $W->VBoxItems();
515
516
        $customSectionCtrl = $App->Controller()->CustomSection();
517
518
        $customSectionSet = $App->CustomSectionSet();
519
        $customSections = $customSectionSet->select(
520
            $customSectionSet->all(
521
                $customSectionSet->object->is($object),
522
                $customSectionSet->view->is($view)
523
            )
524
        );
525
        $customSections->orderAsc($customSectionSet->rank);
526
527
        $sectionsBoxes = array();
528
        /* @var $rows Widget_Layout[] */
529
        $rows = array();
530
531
        $currentColumn = 0;
532
        $row = $W->FlowItems()->addClass('connectedSortable'); //->setSizePolicy('row');
533
        $row->addClass('widget-sameheight-elements');
534
        $rows[] = $row;
535
536
        $nbCol = 0;
537
        foreach ($customSections as $customSection) {
538
539
            list(, , $nbCol) = explode('-', $customSection->sizePolicy);
540
541
            $currentColumn += $nbCol;
542
543
            $sectionSection = $W->Section(
544
                $customSection->name . ' (' . $customSection->rank . ')',
545
                $sectionBox = $W->VBoxItems($W->Hidden()->setName('#' . $customSection->id))
546
            );
547
            $sectionSection->addClass('app-custom-section');
548
            $sectionSection->addClass($customSection->classname);
549
            $sectionSection->setSizePolicy($customSection->sizePolicy . ' widget-sameheight');
550
551
            $row->addItem($sectionSection);
552
553
            $menu = $sectionSection->addContextMenu('inline');
554
            $menu->addItem(
555
                $W->HBoxItems(
556
                    $W->Link('', $customSectionCtrl->addDisplayField($customSection->id))
557
                        ->addClass('icon', Func_Icons::ACTIONS_LIST_ADD)
558
                        ->setOpenMode(Widget_Link::OPEN_DIALOG),
559
                    $W->Link('', $customSectionCtrl->edit($view, $customSection->id))
560
                        ->addClass('icon', Func_Icons::ACTIONS_DOCUMENT_EDIT)
561
                        ->setOpenMode(Widget_Link::OPEN_DIALOG),
562
                    $W->Link('', $customSectionCtrl->editVisibility($customSection->id))
563
                        ->addClass('icon', Func_Icons::ACTIONS_SET_ACCESS_RIGHTS)
564
                        ->setOpenMode(Widget_Link::OPEN_DIALOG),
565
                    $W->Link('', $customSectionCtrl->confirmDelete($customSection->id))
566
                        ->addClass('icon', Func_Icons::ACTIONS_EDIT_DELETE)
567
                        ->setOpenMode(Widget_Link::OPEN_DIALOG)
568
                )
569
            );
570
            $fields = $customSection->getFields();
571
            foreach ($fields as $fieldId => $field) {
572
                if (empty($field)) {
573
                    continue;
574
                }
575
576
                $fieldName = $field['fieldname'];
577
578
                $field = $availableFields[$fieldName];
579
                $fieldDescription = $field['description'];
580
                if (substr($fieldName, 0, 1) !== '_') {
581
                    $fieldDescription = $App->translate($fieldDescription);
582
                }
583
584
                if (empty($field)) {
585
                    continue;
586
                }
587
588
                $fieldItem = $W->HBoxItems(
589
                    $W->Label($fieldDescription)->setSizePolicy('maximum')->addClass('icon', Func_Icons::ACTIONS_ZOOM_FIT_HEIGHT),
590
                    $W->HBoxItems(
591
                        $W->Hidden()->setName($customSection->id . '.' . $fieldId)->setValue($field['name']),
592
                        $W->Link('', $customSectionCtrl->editDisplayField($customSection->id, $field['name']))
593
                            ->addClass('icon', Func_Icons::ACTIONS_DOCUMENT_EDIT)
594
                            ->setOpenMode(Widget_Link::OPEN_DIALOG),
595
                        $W->Link('', $customSectionCtrl->removeDisplayField($customSection->id, $field['name']))
596
                            ->addClass('icon', Func_Icons::ACTIONS_LIST_REMOVE)
597
                            ->setAjaxAction()
598
                    )->addClass('widget-actions')
599
                )->setSizePolicy('widget-list-element widget-actions-target')
600
                ->addClass(Func_Icons::ICON_LEFT_16);
601
602
                $sectionBox->addItem($fieldItem);
603
            }
604
605
            $sectionsBoxes[] = $sectionBox;
606
        }
607
608
        if ($currentColumn + $nbCol > 0) {
609
            $sectionsSection->addItem($row);
610
        }
611
612
        foreach ($sectionsBoxes as $sectionsBox) {
613
            $sectionsBox->sortable(true, $sectionsBoxes);
614
            $sectionsBox->setMetadata('samePlaceholderSize', true);
615
        }
616
617
        foreach ($rows as $row) {
618
            $row->sortable(true, $rows);
619
            $row->setMetadata('samePlaceholderSize', true);
620
        }
621
622
        $form = $W->Form();
623
624
        if (isset($itemId)) {
625
            $form->setId($itemId);
626
        }
627
        $form->setHiddenValue('tg', $App->controllerTg);
628
        $form->setName('sections');
629
        $form->addItem($sectionsSection);
630
        $form->setAjaxAction($this->proxy()->saveSections(), $sectionsSection, 'sortstop');
0 ignored issues
show
Bug introduced by
The method saveSections() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

630
        $form->setAjaxAction($this->proxy()->/** @scrutinizer ignore-call */ saveSections(), $sectionsSection, 'sortstop');
Loading history...
631
        $form->setReloadAction($this->proxy()->sections($object, $view, $form->getId()));
0 ignored issues
show
Bug introduced by
The method sections() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

631
        $form->setReloadAction($this->proxy()->/** @scrutinizer ignore-call */ sections($object, $view, $form->getId()));
Loading history...
632
633
        $form->addClass('depends-custom-sections');
634
635
        return $form;
636
    }
637
638
639
640
    /**
641
     *
642
     * @param string $view
643
     */
644
    public function exportSections($object, $view)
645
    {
646
        $App = $this->App();
647
        $customSectionSet = $App->CustomSectionSet();
648
649
        $customSections = $customSectionSet->select(
650
            $customSectionSet->view->is($view)->_AND_($customSectionSet->object->is($object))
651
        );
652
653
        $sectionsValues = array();
654
        foreach ($customSections as $customSection) {
655
            $values = $customSection->getValues();
656
            unset($values['id']);
657
            unset($values['createdBy']);
658
            unset($values['createdOn']);
659
            unset($values['modifiedBy']);
660
            unset($values['modifiedOn']);
661
            unset($values['deletedBy']);
662
            unset($values['deletedOn']);
663
            unset($values['deleted']);
664
            $sectionsValues[] = $values;
665
        }
666
667
        header('Content-type: application/json');
668
        header('Content-Disposition: attachment; filename="' . $object . '.' . ($view === '' ? 'default' : $view) . '.json"'."\n");
669
670
        $json = bab_json_encode($sectionsValues);
671
        $json = bab_convertStringFromDatabase($json, bab_charset::UTF_8);
672
673
        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...
674
    }
675
676
677
678
679
    /**
680
     * @param string $view
681
     * @return app_Page
682
     */
683
    public function importSectionsConfirm($object, $view = '')
684
    {
685
        $App = $this->App();
686
        $W = bab_Widgets();
687
688
        $page = $App->Ui()->Page();
689
690
        $page->setTitle($App->translate('Import sections layout'));
691
692
        $editor = new app_Editor($App);
693
        $editor->setHiddenValue('tg', $App->controllerTg);
694
        $editor->setHiddenValue('object', $object);
695
696
        $editor->addItem(
697
            $W->LabelledWidget(
698
                $App->translate('View layout name'),
699
                $W->LineEdit(),
700
                'view'
701
            )
702
        );
703
704
        $editor->addItem(
705
            $W->LabelledWidget(
706
                $App->translate('File'),
707
                $W->FilePicker(),
708
                'sectionsfile'
709
            )
710
        );
711
712
        $editor->setSaveAction($this->proxy()->importSections());
0 ignored issues
show
Bug introduced by
The method importSections() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

712
        $editor->setSaveAction($this->proxy()->/** @scrutinizer ignore-call */ importSections());
Loading history...
713
714
        $page->addItem($editor);
715
716
        return $page;
717
    }
718
719
720
    /**
721
     * @param string $view
722
     * @param string $sectionsfile
723
     * @return bool
724
     */
725
    public function importSections($object = null, $view = null, $sectionsfile = null)
726
    {
727
        $App = $this->App();
728
        $W = bab_Widgets();
729
730
        $files = $W->FilePicker()->getFolder();
731
        $files->push('sectionsfile');
732
        $files->push($sectionsfile['uid']);
733
734
        $data = null;
735
        foreach ($files as $f) {
736
            $data = file_get_contents($f->toString());
737
            break;
738
        }
739
740
        if (!isset($data)) {
741
            $this->addError($App->translate('Unable to get file content.'));
742
            return true;
743
        }
744
745
        $sectionsValues = json_decode($data, true);
746
747
        $App = $this->App();
748
        $customSectionSet = $App->CustomSectionSet();
749
750
        $customSectionSet->delete(
751
            $customSectionSet->view->is($view)->_AND_($customSectionSet->object->is($object))
752
        );
753
754
        foreach ($sectionsValues as $sectionValues) {
755
            $customSection = $customSectionSet->newRecord();
756
            $customSection->setValues($sectionValues);
757
            $customSection->object = $object;
758
            $customSection->view = $view;
759
            $customSection->save();
760
        }
761
762
        return true;
763
    }
764
765
766
767
    /**
768
     *
769
     * @param string $view
770
     * @return bool
771
     */
772
    public function deleteSections($object, $view)
773
    {
774
        $App = $this->App();
775
        $customSectionSet = $App->CustomSectionSet();
776
777
        $objectName = $this->getRecordClassName();
778
779
        $customSectionSet->delete(
780
            $customSectionSet->view->is($view)->_AND_($customSectionSet->object->is($objectName))
781
            );
782
783
        return true;
784
    }
785
786
787
    /**
788
     * Display an user interface to edit sections associated to a specific object.
789
     *
790
     * @param string $object
791
     * @param string $view
792
     * @return app_Page
793
     */
794
    public function editSections($object, $view)
795
    {
796
        $App = $this->App();
797
        $W = bab_Widgets();
798
        $Ui = $App->Ui();
799
800
        $page = $Ui->Page();
801
802
        $page->setTitle(sprintf($App->translate('Edit view layout %s'), $view));
803
804
        $toolbar = $Ui->Toolbar();
805
806
        $toolbar->addItem(
807
            $W->Link(
808
                $App->translate('Delete view layout'),
809
                $this->proxy()->deleteSections($object, $view)
0 ignored issues
show
Bug introduced by
The method deleteSections() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

809
                $this->proxy()->/** @scrutinizer ignore-call */ deleteSections($object, $view)
Loading history...
810
            )->addClass('widget-actionbutton', 'icon', Func_Icons::ACTIONS_EDIT_DELETE)
811
        );
812
813
        $toolbar->addItem(
814
            $W->Link(
815
                $App->translate('Export view layout'),
816
                $this->proxy()->exportSections($object, $view)
0 ignored issues
show
Bug introduced by
The method exportSections() does not exist on app_Controller. It seems like you code against a sub-type of app_Controller such as app_CtrlCustomSection. ( Ignorable by Annotation )

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

816
                $this->proxy()->/** @scrutinizer ignore-call */ exportSections($object, $view)
Loading history...
817
            )->addClass('widget-actionbutton', 'icon', Func_Icons::ACTIONS_DOCUMENT_DOWNLOAD)
818
        );
819
820
        $toolbar->addItem(
821
            $W->Link(
822
                $App->translate('Add a section'),
823
                $this->proxy()->edit($view, null, $object)
0 ignored issues
show
introduced by
The method edit() does not exist on app_Controller. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

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

823
                $this->proxy()->/** @scrutinizer ignore-call */ edit($view, null, $object)
Loading history...
824
            )->addClass('widget-actionbutton', 'icon', Func_Icons::ACTIONS_LIST_ADD)
825
            ->setOpenMode(Widget_Link::OPEN_DIALOG)
826
        );
827
828
        $form = $this->sections($object, $view);
829
830
        $page->addItem($toolbar);
831
        $page->addItem($form);
832
833
        return $page;
834
    }
835
836
837
838
    public function saveSections($sections = null)
839
    {
840
        $App = $this->App();
841
        $customSectionSet = $App->CustomSectionSet();
842
843
        $sectionsFields = array();
844
        $sectionsRawFields = array();
845
846
        $rank = 0;
847
        foreach (array_keys($sections) as $sectionFieldId) {
848
849
            if (substr($sectionFieldId, 0, 1) === '#') {
850
                $currentSectionId = substr($sectionFieldId, 1);
851
852
                $customSection = $customSectionSet->request($customSectionSet->id->is($currentSectionId));
853
854
                $sectionsFields[$currentSectionId] = array();
855
                $sectionsRawFields[$currentSectionId] = $customSection->getRawFields();
856
857
                $customSection->rank = $rank;
858
                $rank++;
859
                $customSection->save();
860
                continue;
861
            }
862
863
            $sectionsFields[$currentSectionId][] = $sectionFieldId;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $currentSectionId seems to be defined later in this foreach loop on line 850. Are you sure it is defined here?
Loading history...
864
        }
865
866
        foreach ($sectionsFields as $sectionId => $sectionFieldIds) {
867
            foreach ($sectionFieldIds as $sectionFieldId) {
868
                list($srcSectionId, $srcfieldId) = explode('.', $sectionFieldId);
869
                if (!isset($sectionsRawFields[$srcSectionId][$srcfieldId])) {
870
                    return true;
871
                }
872
            }
873
        }
874
875
        foreach ($sectionsFields as $sectionId => $sectionFieldIds) {
876
            $newRawFields = array();
877
            foreach ($sectionFieldIds as $sectionFieldId) {
878
                list($srcSectionId, $srcfieldId) = explode('.', $sectionFieldId);
879
                $newRawFields[] = $sectionsRawFields[$srcSectionId][$srcfieldId];
880
            }
881
882
            $customSection = $customSectionSet->request($customSectionSet->id->is($sectionId));
883
            $customSection->fields = implode(',', $newRawFields);
884
            $customSection->save();
885
        }
886
887
        $this->addReloadSelector('.depends-custom-sections');
888
889
        return true;
890
    }
891
}
892