Passed
Branchlaucho_customsections (e208bd)
by Laurent
03:37
created

app_CtrlCustomSection::saveSections()   B

Complexity

Conditions 8
Paths 30

Size

Total Lines 52
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 31
nc 30
nop 1
dl 0
loc 52
rs 8.1795
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->FlowItems(
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->FlowItems(
589
                    $W->Label($fieldDescription)->setSizePolicy(Func_Icons::ICON_LEFT_16 . ' widget-80pc' ),
590
                    $W->FlowItems(
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
                    )->setSizePolicy(Func_Icons::ICON_LEFT_16 . ' widget-20pc widget-align-right widget-actions' )
599
                )->setSizePolicy('widget-list-element  widget-actions-target');
600
601
                $sectionBox->addItem($fieldItem);
602
            }
603
604
            $sectionsBoxes[] = $sectionBox;
605
        }
606
607
        if ($currentColumn + $nbCol > 0) {
608
            $sectionsSection->addItem($row);
609
        }
610
611
        foreach ($sectionsBoxes as $sectionsBox) {
612
            $sectionsBox->sortable(true, $sectionsBoxes);
613
            $sectionsBox->setMetadata('samePlaceholderSize', true);
614
        }
615
616
        foreach ($rows as $row) {
617
            $row->sortable(true, $rows);
618
            $row->setMetadata('samePlaceholderSize', true);
619
        }
620
621
        $form = $W->Form();
622
623
        if (isset($itemId)) {
624
            $form->setId($itemId);
625
        }
626
        $form->setHiddenValue('tg', $App->controllerTg);
627
        $form->setName('sections');
628
        $form->addItem($sectionsSection);
629
        $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

629
        $form->setAjaxAction($this->proxy()->/** @scrutinizer ignore-call */ saveSections(), $sectionsSection, 'sortstop');
Loading history...
630
        $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

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

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

808
                $this->proxy()->/** @scrutinizer ignore-call */ deleteSections($object, $view)
Loading history...
809
            )->addClass('widget-actionbutton', 'icon', Func_Icons::ACTIONS_EDIT_DELETE)
810
        );
811
812
        $toolbar->addItem(
813
            $W->Link(
814
                $App->translate('Export view layout'),
815
                $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

815
                $this->proxy()->/** @scrutinizer ignore-call */ exportSections($object, $view)
Loading history...
816
            )->addClass('widget-actionbutton', 'icon', Func_Icons::ACTIONS_DOCUMENT_DOWNLOAD)
817
        );
818
819
        $toolbar->addItem(
820
            $W->Link(
821
                $App->translate('Add a section'),
822
                $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

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