Passed
Pull Request — master ( #1 )
by Robin
02:24
created

app_CtrlRecord::modelView()   F

Complexity

Conditions 18
Paths 320

Size

Total Lines 90
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 18
eloc 49
c 4
b 0
f 0
nc 320
nop 4
dl 0
loc 90
rs 2.5333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
//-------------------------------------------------------------------------
3
// OVIDENTIA http://www.ovidentia.org
4
// Ovidentia is free software; you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation; either version 2, or (at your option)
7
// any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
// See the GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17
// USA.
18
//-------------------------------------------------------------------------
19
/**
20
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
21
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
22
 */
23
24
require_once dirname(__FILE__) . '/controller.class.php';
25
26
27
28
abstract class app_CtrlRecord extends app_Controller
29
{
30
    /**
31
     * This methods returns the Record classname managed by this controller.
32
     * The default method guess the record classname based on the controller name.
33
     * It can be overriden by inherited controllers.
34
     *
35
     * @return string
36
     */
37
    protected function getRecordClassName()
38
    {
39
        $App = $this->App();
40
        if($currentComponent = $App->getCurrentComponent()){
41
            return $currentComponent->getRecordClassName();
42
        }
43
        list(, $recordClassname) = explode('_Ctrl', $this->getClass());
44
        return $recordClassname;
45
    }
46
47
48
    /**
49
     * This methods returns the Record set managed by this controller.
50
     * The default method guess the record set based on the controller name.
51
     * It can be overriden by inherited controllers.
52
     *
53
     * @return app_RecordSet
54
     */
55
    protected function getRecordSet()
56
    {
57
        $App = $this->App();
58
        if($currentComponent = $App->getCurrentComponent()){
59
            return $currentComponent->recordSet();
60
        }
61
        $recordClassname = $this->getRecordClassName();
62
        $recordSetClassname = $recordClassname . 'Set';
63
64
        $recordSet = $App->$recordSetClassname();
65
        return $recordSet;
66
    }
67
68
69
    /**
70
     * @return app_RecordSet
71
     */
72
    protected function getEditRecordSet()
73
    {
74
        return $this->getRecordSet();
75
    }
76
77
78
    /**
79
     * This methods returns the Record set used to save records
80
     *
81
     * @return app_RecordSet
82
     */
83
    protected function getSaveRecordSet()
84
    {
85
        return $this->getRecordSet();
86
    }
87
88
    /**
89
     * This methods returns the Record set used to delete records
90
     *
91
     * @return app_RecordSet
92
     */
93
    protected function getDeleteRecordSet()
94
    {
95
        return $this->getSaveRecordSet();
96
    }
97
98
99
    /**
100
     *
101
     * @param Widget_Action|Widget_Link|Widget_Action[]|Widget_Link[]|array $actions
102
     * @param Widget_Item $box
103
     * @return string
104
     */
105
    protected function createMenu($actions, $icon = true, $showLabel = false)
106
    {
107
        $canvas = bab_Widgets()->HtmlCanvas();
108
        $html = '';
109
        if ($actions instanceof Widget_Action) {
110
            $text = '';
111
            if ($showLabel) {
112
                $text = $actions->getTitle();
113
            }
114
            $html = '<li><a class="icon ' . $actions->getIcon() .  '" href="' . $actions->url() . '">' . $text . '</a></li>';
115
        } elseif ($actions instanceof Widget_Link) {
116
            $html = '<li>' . $actions->display($canvas) . '</li>';
117
        } elseif (is_array($actions)) {
0 ignored issues
show
introduced by
The condition is_array($actions) is always true.
Loading history...
118
            if (isset($actions['items'])) {
119
                $items = $actions['items'];
120
            } else {
121
                $items = $actions;
122
            }
123
            foreach ($items as $action) {
124
                $html .= $this->createMenu($action, true, true);
125
            }
126
            if (isset($actions['icon'])) {
127
128
                $html = '<li class="dropdown">'
129
                    . '<a href="#" class="' . $actions['icon'] . ' icon dropdown-toogle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">'
130
                    . ($actions['icon'] === 'actions-context-menu'/*Func_Icons::ACTIONS_CONTEXT_MENU*/ ? '' : '<span class="caret"></span>')
131
                    . '</a>'
132
                    . '<ul class="dropdown-menu dropdown-menu-right ' . Func_Icons::ICON_LEFT_SYMBOLIC . '">'
133
                    . $html
134
                    . '</ul>';
135
            }
136
        }
137
138
        return $html;
139
    }
140
141
142
    /**
143
     *
144
     * @return string[]
145
     */
146
    protected function getAvailableModelViewTypes()
147
    {
148
        $App = $this->App();
149
        $Ui = $App->Ui();
150
151
        $types = array();
152
153
        $recordClassname = $this->getRecordClassName();
154
155
        $viewClassname =  $recordClassname . 'TableView';
156
        if (method_exists($Ui, $viewClassname)) {
157
            $types['table'] = array(
158
                'classname' => $viewClassname,
159
                'icon' => Func_Icons::ACTIONS_VIEW_LIST_TEXT,
160
                'label' => $App->translate('Detailed list')
161
            );
162
        }
163
164
        $viewClassname =  $recordClassname . 'CardsView';
165
        if (method_exists($Ui, $viewClassname)) {
166
            $types['cards'] = array(
167
                'classname' => $viewClassname,
168
                'icon' => 'actions-view-list-cards', //Func_Icons::ACTIONS_VIEW_LIST_CARDS
169
                'label' => $App->translate('Cards')
170
            );
171
        }
172
173
        $viewClassname =  $recordClassname . 'MapView';
174
        if (method_exists($Ui, $viewClassname)) {
175
            $types['map'] = array(
176
                'classname' => $viewClassname,
177
                'icon' => Func_Icons::APPS_PREFERENCES_SITE,
178
                'label' => $App->translate('Map')
179
            );
180
        }
181
182
        $viewClassname =  $recordClassname . 'CalendarView';
183
        if (method_exists($Ui, $viewClassname)) {
184
            $types['calendar'] = array(
185
                'classname' => $viewClassname,
186
                'icon' => Func_Icons::APPS_CALENDAR,
187
                'label' => $App->translate('Calendar')
188
            );
189
        }
190
191
        return $types;
192
    }
193
194
195
196
    /**
197
     * Returns an array of field names and descriptions that can be used in Full/CardFrames.
198
     *
199
     * @return string[]
200
     */
201
    public function getAvailableDisplayFields()
202
    {
203
        $App = $this->App();
204
        $recordSet = $this->getRecordSet();
205
206
        $availableFields = array();
207
208
        foreach ($recordSet->getFields() as $name => $field) {
209
            $fieldName = $field->getName();
210
            $fieldDescription = $field->getDescription();
211
            if (substr($fieldName, 0, 1) !== '_') {
212
                $fieldDescription = $App->translate($fieldDescription);
213
            }
214
            if (empty($fieldDescription)) {
215
                $fieldDescription = $fieldName;
216
            }
217
            $availableFields[$name] = array(
218
                'name' => $fieldName,
219
                'description' => $fieldDescription
220
            );
221
        }
222
223
        $availableFields['_spacer'] = array(
224
            'name' => '_spacer',
225
            'description' => '[Spacer]'
226
        );
227
228
        return $availableFields;
229
    }
230
231
232
233
    /**
234
     * Displays an editor of the record values corresponding to the fields of a custom section.
235
     *
236
     * @param int $id                   The id of the record to edit
237
     * @param int $customSectionId      The id of the section used to create the editor
238
     * @param string $itemId
239
     *
240
     * @throws app_AccessException
241
     * @return app_Page
242
     */
243
    public function editSection($id, $customSectionId, $itemId = null)
244
    {
245
        $W = bab_Widgets();
246
        $App = $this->App();
247
        $Ui = $App->Ui();
248
249
        $page = $App->Ui()->Page();
250
251
        $customSectionSet = $App->CustomSectionSet();
252
        $customSection = $customSectionSet->get(
253
            $customSectionSet->id->is($customSectionId)
254
        );
255
256
        $page->setTitle($customSection->name);
257
258
        $recordSet = $this->getEditRecordSet();
259
260
        $recordClassname = $this->getRecordClassName();
261
        $editorClassname =  $recordClassname . 'SectionEditor';
262
        /* @var $editor app_RecordEditor */
263
        $editor = $Ui->$editorClassname();
264
        if (!isset($itemId)) {
265
            $itemId = $this->getClass() . '_' . __FUNCTION__;
266
        }
267
        $editor->setId($itemId);
0 ignored issues
show
Bug introduced by
The method setId() does not exist on app_RecordEditor. 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

267
        $editor->/** @scrutinizer ignore-call */ 
268
                 setId($itemId);
Loading history...
268
        $editor->setHiddenValue('tg', $App->controllerTg);
269
        $editor->setSaveAction($this->proxy()->save());
0 ignored issues
show
Bug introduced by
The method save() does not exist on app_Controller. 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

269
        $editor->setSaveAction($this->proxy()->/** @scrutinizer ignore-call */ save());
Loading history...
270
        $editor->setName('data');
0 ignored issues
show
Bug introduced by
The method setName() does not exist on app_RecordEditor. 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

270
        $editor->/** @scrutinizer ignore-call */ 
271
                 setName('data');
Loading history...
271
        $editor->addItem($W->Hidden()->setName('id'));
272
273
        $editor->recordSet = $recordSet;
274
        $section = $editor->sectionContent($customSectionId);
275
        $section->setSizePolicy('widget-60em');
276
277
        $editor->addItem($section);
278
279
        if (isset($id)) {
280
            $record = $recordSet->request($id);
281
            if (!$record->isUpdatable()) {
282
                throw new app_AccessException($App->translate('You do not have access to this page.'));
283
            }
284
            $editor->setRecord($record);
285
        } else {
286
            if (!$recordSet->isCreatable()) {
287
                throw new app_AccessException($App->translate('You do not have access to this page.'));
288
            }
289
            $record = $recordSet->newRecord();
290
            $editor->setRecord($record);
291
        }
292
293
        $editor->isAjax = bab_isAjaxRequest();
294
295
        $page->addItem($editor);
296
297
        return $page;
298
    }
299
300
301
    /**
302
     * @param string $itemId
303
     * @return string
304
     */
305
    public function getModelViewDefaultId($itemId = null)
306
    {
307
        if (!isset($itemId)) {
308
            $itemId = $this->getClass() . '_modelView';
309
        }
310
311
        return $itemId;
312
    }
313
314
    /**
315
     * Returns the xxxModelView associated to the RecordSet.
316
     *
317
     * @param array|null    $filter
318
     * @param string        $type
319
     * @param array|null    $columns    Optional list of columns. array($columnPath] => '1' | '0').
320
     * @param string|null   $itemId     Widget item id
321
     * @return app_TableModelView
322
     */
323
    protected function modelView($filter = null, $type = null, $columns = null, $itemId = null)
324
    {
325
        $App = $this->App();
326
        if($currentComponent = $App->getCurrentComponent()){
327
            $Ui = $currentComponent->ui();
328
        }
329
        else{
330
            $Ui = $App->Ui();
331
        }
332
333
        $recordSet = $this->getRecordSet();
334
335
        $recordClassname = $this->getRecordClassName();
336
337
        $itemId = $this->getModelViewDefaultId($itemId);
338
339
        if (!isset($type)) {
340
            $type = $this->getFilteredViewType($itemId);
341
        }
342
343
        //$types = $this->getAvailableModelViewTypes();
344
345
        switch ($type) {
346
            case 'cards':
347
                $tableviewClassname =  $currentComponent ? 'cardsView' : $recordClassname . 'CardsView';
348
                break;
349
350
            case 'map':
351
                $tableviewClassname =  $currentComponent ? 'mapView' : $recordClassname . 'MapView';
352
                break;
353
354
            case 'calendar':
355
                $tableviewClassname =  $currentComponent ? 'calendarView' : $recordClassname . 'CalendarView';
356
                break;
357
358
            case 'table':
359
            default:
360
                $tableviewClassname =  $currentComponent ? 'tableView' : $recordClassname . 'TableView';
361
                break;
362
        }
363
364
365
        /* @var $tableview widget_TableModelView */
366
        $tableview = $Ui->$tableviewClassname();
367
368
        $tableview->setRecordController($this);
0 ignored issues
show
Bug introduced by
The method setRecordController() does not exist on widget_TableModelView. It seems like you code against a sub-type of widget_TableModelView such as app_TableModelView. ( Ignorable by Annotation )

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

368
        $tableview->/** @scrutinizer ignore-call */ 
369
                    setRecordController($this);
Loading history...
369
370
        $tableview->setId($itemId);
371
372
        $tableview->setRecordSet($recordSet);
373
        $tableview->addDefaultColumns($recordSet);
374
        if (isset($filter)) {
375
            $tableview->setFilterValues($filter);
376
        }
377
        $filter = $tableview->getFilterValues();
378
379
        if (isset($filter['showTotal']) && $filter['showTotal']) {
380
            $tableview->displaySubTotalRow(true);
381
        }
382
383
        $conditions = $tableview->getFilterCriteria($filter);
384
385
        $conditions = $conditions->_AND_(
386
            $recordSet->isReadable()
387
        );
388
389
        $records = $recordSet->select($conditions);
390
391
//         print_r($records->getSelectQuery());
392
393
        $tableview->setDataSource($records);
0 ignored issues
show
Bug introduced by
$records of type app_Record[] is incompatible with the type ORM_Iterator expected by parameter $iterator of widget_TableModelView::setDataSource(). ( Ignorable by Annotation )

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

393
        $tableview->setDataSource(/** @scrutinizer ignore-type */ $records);
Loading history...
394
395
396
397
        if (isset($columns)) {
398
            $availableColumns = $tableview->getVisibleColumns();
399
400
            $remainingColumns = array();
401
            foreach ($availableColumns as $availableColumn) {
402
                $colPath = $availableColumn->getFieldPath();
403
                if (isset($columns[$colPath]) && $columns[$colPath] == '1') {
404
                    $remainingColumns[] = $availableColumn;
405
                }
406
            }
407
            $tableview->setColumns($remainingColumns);
408
        }
409
410
        $tableview->allowColumnSelection();
411
412
        return $tableview;
413
    }
414
415
416
417
418
    /**
419
     * @return app_Editor
420
     */
421
    protected function recordEditor($itemId = null)
422
    {
423
        $App = $this->App();
424
        $Ui = $App->Ui();
425
        if($currentComponent = $App->getCurrentComponent()){
426
            $editor = $currentComponent->ui()->editor();
427
        }
428
        else{
429
430
            $recordClassname = $this->getRecordClassName();
431
            $editorClassname =  $recordClassname . 'Editor';
432
            $editor = $Ui->$editorClassname();
433
        }
434
435
        if (!isset($itemId)) {
436
            $itemId = $this->getClass() . '_' . __FUNCTION__;
437
        }
438
        $editor->setId($itemId);
439
        $editor->setHiddenValue('tg', $App->controllerTg);
440
        $editor->setSaveAction($this->proxy()->save());
441
        $editor->setName('data');
442
443
        $editor->isAjax = bab_isAjaxRequest();
444
445
        return $editor;
446
    }
447
448
449
450
    /**
451
     * @param widget_TableModelView $tableView
452
     * @return app_Toolbar
453
     */
454
    protected function toolbar($tableView)
455
    {
456
        $W = bab_Widgets();
457
        $App = $this->App();
458
459
        $proxy = $this->proxy();
460
461
        $filter = $tableView->getFilterValues();
462
463
        $toolbar = $W->FlowItems();
464
        $toolbar->addClass('widget-toolbar', Func_Icons::ICON_LEFT_16);
465
466
        $viewTypes = $this->getAvailableModelViewTypes();
467
468
        if (count($viewTypes) > 1) {
469
            $viewsBox = $W->Items();
470
            $viewsBox->setSizePolicy('pull-right');
471
//            $viewsBox->addClass('btn-group', Func_Icons::ICON_LEFT_16);
472
            $toolbar->addItem($viewsBox);
473
474
            $filteredViewType = $this->getFilteredViewType($tableView->getId());
475
476
            foreach ($viewTypes as $viewTypeId => $viewType) {
477
                $viewsBox->addItem(
478
                    $W->Link(
479
                        '',
480
                        $proxy->setFilteredViewType($tableView->getId(), $viewTypeId)
0 ignored issues
show
Bug introduced by
The method setFilteredViewType() does not exist on app_Controller. 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

480
                        $proxy->/** @scrutinizer ignore-call */ 
481
                                setFilteredViewType($tableView->getId(), $viewTypeId)
Loading history...
481
                    )->addClass('icon', $viewType['icon'] . ($filteredViewType=== $viewTypeId ? ' active' : ''))
482
//                    ->setSizePolicy('btn btn-xs btn-default ' . ($filteredViewType === $viewTypeId ? 'active' : ''))
483
                    ->setTitle($viewType['label'])
484
                    ->setAjaxAction()
485
                );
486
            }
487
        }
488
489
        if (method_exists($proxy, 'exportSelect')) {
490
            $toolbar->addItem(
491
                $W->Link(
492
                    $App->translate('Export'),
493
                    $proxy->exportSelect($filter)
0 ignored issues
show
Bug introduced by
The method exportSelect() does not exist on app_Controller. 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

493
                    $proxy->/** @scrutinizer ignore-call */ 
494
                            exportSelect($filter)
Loading history...
494
                )->addClass('icon', Func_Icons::ACTIONS_DOCUMENT_DOWNLOAD)
495
                ->setOpenMode(Widget_Link::OPEN_DIALOG)
496
            );
497
        }
498
499
        if (method_exists($proxy, 'printList')) {
500
            $toolbar->addItem(
501
                $W->Link(
502
                    $App->translate('Print'),
503
                    $proxy->printList($filter)
0 ignored issues
show
Bug introduced by
The method printList() does not exist on app_Controller. 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

503
                    $proxy->/** @scrutinizer ignore-call */ 
504
                            printList($filter)
Loading history...
504
                )->addClass('icon', Func_Icons::ACTIONS_DOCUMENT_PRINT)
505
                ->setOpenMode(Widget_Link::OPEN_POPUP)
506
            );
507
        }
508
509
        return $toolbar;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $toolbar returns the type Widget_FlowLayout which is incompatible with the documented return type app_Toolbar.
Loading history...
510
    }
511
512
513
514
515
    /**
516
     * @param string $itemId
517
     * @return boolean
518
     */
519
    public function toggleFilterVisibility($itemId)
520
    {
521
        $W = bab_Widgets();
522
523
        $filterVisibility = $this->getFilterVisibility($itemId);
524
        $filterVisibility = !$filterVisibility;
525
        $W->setUserConfiguration($itemId . '/filterVisibility', $filterVisibility);
526
527
        return true;
528
    }
529
530
531
    /**
532
     * @param string $itemId
533
     * @return boolean
534
     */
535
    protected function getFilterVisibility($itemId)
536
    {
537
        $W = bab_Widgets();
538
        $filterVisibility = $W->getUserConfiguration($itemId . '/filterVisibility');
539
        if (!isset($filterVisibility)) {
540
            $filterVisibility = false;
541
            $W->setUserConfiguration($itemId . '/filterVisibility', $filterVisibility);
542
        }
543
        return $filterVisibility;
544
    }
545
546
547
    /**
548
     * Returns the current filtered view type (table, cards...)
549
     * @param string        $itemId     The model view widget id
550
     * @return string
551
     */
552
    protected function getFilteredViewType($itemId)
553
    {
554
        $W = bab_Widgets();
555
        $type = $W->getUserConfiguration($itemId . '/viewType');
556
        if (!isset($type)) {
557
            $type = 'table';
558
        }
559
        return $type;
560
    }
561
562
563
    /**
564
     * Sets the current filtered view type (table, cards...)
565
     * @param string        $itemId     The model view widget id
566
     * @param string        $type       'table, 'cards'...
567
     */
568
    public function setFilteredViewType($itemId, $type = null)
569
    {
570
        $W = bab_Widgets();
571
        $W->setUserConfiguration($itemId . '/viewType', $type);
572
573
        return true;
574
    }
575
576
577
    /**
578
     * @param array     $filter
579
     * @param string    $type
580
     * @param string    $itemId
581
     */
582
    public function filteredView($filter = null, $type = null, $itemId = null)
583
    {
584
        $W = bab_Widgets();
585
586
        $view = $this->modelView($filter, $type, null, $itemId);
587
        $view->setAjaxAction();
588
589
        $filter = $view->getFilterValues();
590
591
        $filterPanel = $view->advancedFilterPanel($filter);
592
593
        if ($this->getFilterVisibility($itemId)) {
594
            $filterPanel->addClass('show-filter');
595
        } else {
596
            $filterPanel->addClass('hide-filter');
597
        }
598
        $toolbar = $this->toolbar($view);
599
600
601
        if ($view->isColumnSelectionAllowed()) {
602
            $columnSelectionMenu = $view->columnSelectionMenu($view->getVisibleColumns());
603
            $toolbar->addItem($columnSelectionMenu);
604
        }
605
606
        $box = $W->VBoxItems(
607
            $toolbar,
608
            $filterPanel
609
        );
610
        $box->setReloadAction($this->proxy()->filteredView(null, null, $view->getId()));
0 ignored issues
show
Bug introduced by
The method filteredView() does not exist on app_Controller. 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

610
        $box->setReloadAction($this->proxy()->/** @scrutinizer ignore-call */ filteredView(null, null, $view->getId()));
Loading history...
611
612
        return $box;
613
    }
614
615
616
617
    /**
618
     * @param array $filter
619
     * @param string $type
620
     * @return array
621
     */
622
    protected function getListItemMenus($filter = null, $type = null)
623
    {
624
        $itemMenus = array();
625
626
//         $tabs = $this->getTabs();
627
628
//         if (count($tabs) > 0) {
629
//             $itemMenus['all'] = array (
630
//                 'label' => $App->translate('All'),
631
//                 'action' => $this->proxy()->setCurrentTab('all')
632
//             );
633
//         }
634
//         foreach ($tabs as $tab) {
635
//             $itemMenus[$tab] = array(
636
//                 'label' => $tab,
637
//                 'action' => $this->proxy()->setCurrentTab($tab)
638
//             );
639
//         }
640
641
        return $itemMenus;
642
    }
643
644
645
646
    /**
647
     * @param array	$filter
648
     * @param string $type
649
     * @return Widget_Page
650
     */
651
    public function displayList($filter = null, $type = null)
652
    {
653
        $W = bab_Widgets();
654
655
        $page = $W->BabPage();
656
        $page->addClass('app-page-list');
657
658
        $itemMenus = $this->getListItemMenus();
659
660
        foreach ($itemMenus as $itemMenuId => $itemMenu) {
661
            $page->addItemMenu($itemMenuId, $itemMenu['label'], $itemMenu['action']);
0 ignored issues
show
Deprecated Code introduced by
The function Widget_BabPage::addItemMenu() has been deprecated: Replaced by Widget_Tabs ( Ignorable by Annotation )

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

661
            /** @scrutinizer ignore-deprecated */ $page->addItemMenu($itemMenuId, $itemMenu['label'], $itemMenu['action']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
662
        }
663
664
        $filteredView = $this->filteredView($filter, $type);
665
666
        $page->addItem($filteredView);
667
668
        return $page;
669
    }
670
671
672
    /**
673
     *
674
     * @param array $filter
675
     * @return Widget_Page
676
     */
677
    public function exportSelect($filter = null)
678
    {
679
        $App = $this->App();
680
        $Ui = $App->Ui();
681
682
        $page = $App->Ui()->Page();
683
        $page->addClass('app-page-editor');
684
685
        $page->setTitle($App->translate('Export list'));
686
687
        $tableview = $this->modelView($filter, 'table');
688
689
        $editor = $Ui->ExportSelectEditor(__METHOD__, $tableview, $filter);
690
691
        $editor->setSaveAction(
692
            $this->proxy()->exportList(),
0 ignored issues
show
Bug introduced by
The method exportList() does not exist on app_Controller. 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

692
            $this->proxy()->/** @scrutinizer ignore-call */ exportList(),
Loading history...
693
            $App->translate('Export')
694
        );
695
        $page->addItem($editor);
696
697
        return $page;
698
    }
699
700
701
702
703
704
    /**
705
     * @param	array	$filter
706
     */
707
    public function exportList($filter = null, $format = 'csv', $columns = null, $inline = true, $filename = 'export')
708
    {
709
        $App = $this->App();
710
711
        $page = $App->Ui()->Page();
712
        $page->addClass('app-page-list');
713
714
        $tableview = $this->modelView($filter, 'table', $columns);
715
        $tableview->allowColumnSelection(false);
716
717
        switch ($format) {
718
            case 'xlsx':
719
                $tableview->downloadXlsx($filename . '.xlsx');
720
                break;
721
            case 'xls':
722
                $tableview->downloadExcel($filename . '.xls');
723
                break;
724
            case 'ssv':
725
                $tableview->downloadCsv($filename . '.csv', ';', $inline, 'Windows-1252');
726
                break;
727
            case 'csv':
728
            default:
729
                $tableview->downloadCsv($filename . '.csv', ',', $inline, bab_charset::getIso());
730
                break;
731
        }
732
    }
733
734
735
    /**
736
     * Returns a page with the record information.
737
     *
738
     * @param int	$id
739
     * @return app_Page
740
     */
741
    public function display($id, $view = '')
742
    {
743
        $App = $this->App();
744
        $page = $App->Ui()->Page();
745
746
        $recordSet = $this->getRecordSet();
747
748
        $record = $recordSet->request($id);
749
750
        if (!$record->isReadable()) {
751
            throw new app_AccessException($App->translate('You do not have access to this page.'));
752
        }
753
754
        $W = bab_Widgets();
755
        $Ui = $App->Ui();
756
757
        $recordClassname = $this->getRecordClassName();
758
        $fullFrameClassname =  $recordClassname . 'FullFrame';
759
        $fullFrame = $Ui->$fullFrameClassname($record, $view);
760
761
762
        $maxHistory = 8;
763
        $historyFrame = $W->VBoxItems(
764
            $App->Controller()->Search(false)->history($record->getRef(), $maxHistory, 0, true)
0 ignored issues
show
Bug introduced by
The method Search() does not exist on app_Controller. 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

764
            $App->Controller()->/** @scrutinizer ignore-call */ Search(false)->history($record->getRef(), $maxHistory, 0, true)
Loading history...
765
        );
766
        $fullFrame->addItem(
767
            $W->Section(
768
                $App->translate('History'),
769
                $historyFrame,
770
                2
771
            )->setFoldable(true)
772
            ->addClass('compact')
773
        );
774
775
        $page->addItem($fullFrame);
776
777
778
        // Actions
779
        $page->addContextItem($this->getDisplayActionFrame($page, $record));
780
781
        return $page;
782
    }
783
784
785
786
    protected function getDisplayActionFrame(Widget_Page $page, app_Record $record)
787
    {
788
        $actionsFrame = $page->ActionsFrame();
0 ignored issues
show
Bug introduced by
The method ActionsFrame() does not exist on Widget_Page. It seems like you code against a sub-type of Widget_Page such as app_Page. ( Ignorable by Annotation )

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

788
        /** @scrutinizer ignore-call */ 
789
        $actionsFrame = $page->ActionsFrame();
Loading history...
789
        return $actionsFrame;
790
    }
791
792
793
794
    /**
795
     * Returns a page containing an editor for the record.
796
     *
797
     * @param string|null id    A record id or null for a new record editor.
0 ignored issues
show
Bug introduced by
The type id 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...
798
     * @return Widget_Page
799
     */
800
    public function edit($id = null, $view = '')
801
    {
802
        $W = bab_Widgets();
803
        $App = $this->App();
804
805
        $recordSet = $this->getEditRecordSet();
806
807
        $page = $W->BabPage();
808
        $page->addClass('app-page-editor');
809
810
        $page->setTitle($App->translate($recordSet->getDescription()));
811
812
        $editor = $this->recordEditor();
813
814
        if (isset($id)) {
815
            $record = $recordSet->request($id);
816
            if (!$record->isUpdatable()) {
817
                throw new app_AccessException($App->translate('You do not have access to this page.'));
818
            }
819
        } else {
820
            if (!$recordSet->isCreatable()) {
821
                throw new app_AccessException($App->translate('You do not have access to this page.'));
822
            }
823
            $record = $recordSet->newRecord();
824
        }
825
        $editor->setRecord($record);
826
827
        $page->addItem($editor);
828
829
        return $page;
830
    }
831
832
    /**
833
     * Returns a page containing an editor for the tags record.
834
     *
835
     * @param string|null id    A record id or null for a new record editor.
836
     * @return Widget_Page
837
     */
838
    public function editTags($id = null, $view = '')
839
    {
840
        $W = bab_Widgets();
841
        $App = $this->App();
842
        $Ui = $App->Ui();
843
844
        $recordSet = $this->getEditRecordSet();
845
846
        $page = $W->BabPage();
847
        $page->addClass('app-page-editor');
848
849
        $page->setTitle($App->translate($recordSet->getDescription()));
850
851
        $editor = $Ui->TagsEditor();
0 ignored issues
show
Bug introduced by
The method TagsEditor() 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

851
        /** @scrutinizer ignore-call */ 
852
        $editor = $Ui->TagsEditor();

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...
852
853
        if (isset($id)) {
854
            $record = $recordSet->request($id);
855
            if (!$record->isUpdatable()) {
856
                throw new app_AccessException($App->translate('You do not have access to this page.'));
857
            }
858
            $editor->setRecord($record);
859
        } else {
860
            if (!$recordSet->isCreatable()) {
861
                throw new app_AccessException($App->translate('You do not have access to this page.'));
862
            }
863
            $record = $recordSet->newRecord();
864
            $editor->setRecord($record);
865
        }
866
867
        $page->addItem($editor);
868
869
        return $page;
870
    }
871
872
873
    public function ok()
874
    {
875
        return true;
876
    }
877
878
879
880
    /**
881
     *
882
     * @param  $data
883
     */
884
    public function create($data)
885
    {
886
887
    }
888
889
890
    /**
891
     *
892
     * @param  $data
893
     */
894
    public function update($data)
895
    {
896
897
    }
898
899
900
901
    /**
902
     *
903
     */
904
    public function read($id)
905
    {
906
907
    }
908
909
910
    /**
911
     * Get the message to display on delete next page
912
     * @return string | true
913
     */
914
    protected function getDeletedMessage(ORM_Record $record)
915
    {
916
        $App = $this->App();
917
        $recordSet = $this->getRecordSet();
918
919
        $recordTitle = $record->getRecordTitle();
920
921
        $message = sprintf($App->translate('%s has been deleted'), $App->translate($recordSet->getDescription()) . ' "' . $recordTitle . '"');
922
        return $message;
923
    }
924
925
    /**
926
     * Get the message to display on create next page
927
     * @return string | true
928
     */
929
    protected function getCreatedMessage()
930
    {
931
        return true;
932
    }
933
934
    /**
935
     * Get the message to display on modification next page
936
     * @param app_Record $record The record before the modification
937
     * @return string | true
938
     */
939
    protected function getModifedMessage(ORM_Record $record)
940
    {
941
        return true;
942
    }
943
944
945
    /**
946
     * Method to check reord before saving
947
     * @param app_Record $record
948
     */
949
    protected function preSave(ORM_Record $record, $data)
950
    {
951
952
    }
953
954
955
    /**
956
     * Method for post save actions on record
957
     * @param app_Record $record
958
     */
959
    protected function postSave(ORM_Record $record, $data)
960
    {
961
962
    }
963
964
965
    /**
966
     * Save a record
967
     *
968
     * @requireSaveMethod
969
     *
970
     * @param array $data
971
     */
972
    public function save($data = null)
973
    {
974
        $this->requireSaveMethod();
975
        $App = $this->App();
976
        $recordSet = $this->getSaveRecordSet();
977
        $pk = $recordSet->getPrimaryKey();
978
        $message = null;
979
980
        if (!empty($data[$pk])) {
981
            $record = $recordSet->request($data[$pk]);
982
            unset($data[$pk]);
983
984
            if (!$record->isUpdatable()) {
985
                throw new app_AccessException('Access denied');
986
            }
987
988
            $message = $this->getModifedMessage($record);
989
        } else {
990
991
            $record = $recordSet->newRecord();
992
993
            if (!$recordSet->isCreatable()) {
994
                throw new app_AccessException('Access denied');
995
            }
996
997
            $message = $this->getCreatedMessage();
998
        }
999
1000
        if (!isset($record)) {
1001
            throw new app_SaveException($App->translate('The record does not exists'));
1002
        }
1003
1004
1005
        if (!isset($data)) {
1006
            throw new app_SaveException($App->translate('Nothing to save'));
1007
        }
1008
1009
        $record->setFormInputValues($data);
1010
1011
1012
        $this->preSave($record, $data);
1013
        if ($record->save()) {
1014
            $this->postSave($record, $data);
1015
            if (is_string($message)) {
0 ignored issues
show
introduced by
The condition is_string($message) is always false.
Loading history...
1016
                $this->addMessage($message);
1017
            }
1018
1019
            $this->addReloadSelector('.depends-' . $this->getRecordClassName());
1020
            return true;
1021
        }
1022
1023
        return true;
1024
    }
1025
1026
1027
    /**
1028
     * Deletes the specified record.
1029
     *
1030
     * @requireDeleteMethod
1031
     *
1032
     * @param string $id        The record id
1033
     * @return boolean
1034
     */
1035
    public function delete($id)
1036
    {
1037
        $this->requireDeleteMethod();
1038
        $recordSet = $this->getDeleteRecordSet();
1039
1040
        $record = $recordSet->request($id);
1041
1042
        if (!$record->isDeletable()) {
1043
            throw new app_AccessException('Sorry, You are not allowed to perform this operation');
1044
        }
1045
        $deletedMessage = $this->getDeletedMessage($record);
1046
1047
        if ($record->delete()) {
1048
            $this->addMessage($deletedMessage);
1049
        }
1050
1051
        $this->addReloadSelector('.depends-' . $record->getClassName());
1052
1053
        return true;
1054
    }
1055
1056
1057
    /**
1058
     * Displays a page asking to confirm the deletion of a record.
1059
     *
1060
     * @param int $id
1061
     */
1062
    public function confirmDelete($id)
1063
    {
1064
        $W = bab_Widgets();
1065
        $App = $this->App();
1066
        $Ui = $App->Ui();
1067
1068
        $recordSet = $this->getRecordSet();
1069
        $record = $recordSet->get($id);
1070
1071
        $page = $Ui->Page();
1072
1073
        $page->addClass('app-page-editor');
1074
        $page->setTitle($App->translate('Deletion'));
1075
1076
        if (!isset($record)) {
1077
            $page->addItem(
1078
                $W->Label($App->translate('This element does not exists.'))
1079
            );
1080
            $page->addClass('alert', 'alert-warning');
1081
            return $page;
1082
        }
1083
1084
1085
        $form = new app_Editor($App);
1086
1087
        $form->addItem($W->Hidden()->setName('id'));
1088
1089
        $recordTitle = $record->getRecordTitle();
1090
1091
        $subTitle = $App->translate($recordSet->getDescription()) . ' "' . $recordTitle . '"';
1092
        $form->addItem($W->Title($subTitle, 5));
1093
1094
        $form->addItem($W->Title($App->translate('Confirm delete?'), 6));
1095
1096
        $form->addItem($W->Html(bab_toHtml($App->translate('It will not be possible to undo this deletion.'))));
1097
1098
        $confirmedAction = $this->proxy()->delete($id);
0 ignored issues
show
Bug introduced by
The method delete() does not exist on app_Controller. 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

1098
        $confirmedAction = $this->proxy()->/** @scrutinizer ignore-call */ delete($id);
Loading history...
1099
        $parameters = $confirmedAction->getParameters();
1100
        foreach ($parameters as $key => $value) {
1101
            $form->setHiddenValue($key, $value);
1102
        }
1103
        $form->addButton(
1104
            $W->SubmitButton()
1105
                ->setAjaxAction($confirmedAction)
1106
                ->setLabel($App->translate('Delete'))
1107
         );
1108
        $form->addButton($W->SubmitButton()->setLabel($App->translate('Cancel'))->addClass('widget-close-dialog'));
1109
        $page->addItem($form);
1110
1111
        return $page;
1112
    }
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
    /**
1123
     * Deletes the specified record.
1124
     *
1125
     * @requireDeleteMethod
1126
     *
1127
     * @param string $id        The record id
1128
     * @return boolean
1129
     */
1130
    public function remove($id)
1131
    {
1132
        $this->requireDeleteMethod();
1133
        $recordSet = $this->getDeleteRecordSet();
1134
1135
        $record = $recordSet->request($id);
1136
1137
        if (!$record->isRemovable()) {
1138
            throw new app_AccessException('Sorry, You are not allowed to perform this operation');
1139
        }
1140
1141
        $App = $this->App();
1142
        $deletedMessage = $App->translate('The element has been moved to the trash');
1143
1144
        if ($recordSet->delete($recordSet->id->is($record->id), app_TraceableRecord::DELETED_STATUS_IN_TRASH)) {
0 ignored issues
show
Unused Code introduced by
The call to ORM_RecordSet::delete() has too many arguments starting with app_TraceableRecord::DELETED_STATUS_IN_TRASH. ( Ignorable by Annotation )

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

1144
        if ($recordSet->/** @scrutinizer ignore-call */ delete($recordSet->id->is($record->id), app_TraceableRecord::DELETED_STATUS_IN_TRASH)) {

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1145
            if (is_string($deletedMessage)) {
0 ignored issues
show
introduced by
The condition is_string($deletedMessage) is always true.
Loading history...
1146
                $this->addMessage($deletedMessage);
1147
            }
1148
        }
1149
1150
        $this->addReloadSelector('.depends-' . $record->getClassName());
1151
1152
        return true;
1153
    }
1154
1155
1156
    /**
1157
     * Displays a page asking to confirm the deletion of a record.
1158
     *
1159
     * @param int $id
1160
     */
1161
    public function confirmRemove($id)
1162
    {
1163
        $W = bab_Widgets();
1164
        $App = $this->App();
1165
        $Ui = $App->Ui();
1166
1167
        $recordSet = $this->getRecordSet();
1168
        $record = $recordSet->get($id);
1169
1170
        $page = $Ui->Page();
1171
1172
        $page->addClass('app-page-editor');
1173
        $page->setTitle($App->translate('Move to trash'));
1174
1175
        $form = new app_Editor($App);
1176
1177
        $recordTitle = $record->getRecordTitle();
1178
1179
        $subTitle = $App->translate($recordSet->getDescription()) . ' "' . $recordTitle . '"';
1180
        $form->addItem($W->Title($subTitle, 5));
1181
1182
        $form->addItem($W->Title($App->translate('Confirm delete?'), 6));
1183
1184
//         $form->addItem($W->Html(bab_toHtml($App->translate('It will not be possible to undo this deletion.'))));
1185
1186
        $confirmedAction = $this->proxy()->remove($id);
0 ignored issues
show
Bug introduced by
The method remove() does not exist on app_Controller. 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

1186
        $confirmedAction = $this->proxy()->/** @scrutinizer ignore-call */ remove($id);
Loading history...
1187
        $parameters = $confirmedAction->getParameters();
1188
        foreach ($parameters as $key => $value) {
1189
            $form->setHiddenValue($key, $value);
1190
        }
1191
        $form->addButton(
1192
            $W->SubmitButton()
1193
            ->setAjaxAction($confirmedAction)
1194
            ->setLabel($App->translate('Move to trash'))
1195
            );
1196
        $form->addButton($W->SubmitButton()->setLabel($App->translate('Cancel'))->addClass('widget-close-dialog'));
1197
        $page->addItem($form);
1198
1199
        return $page;
1200
    }
1201
1202
1203
1204
1205
    /**
1206
     * Restores the specified record.
1207
     *
1208
     * @requireDeleteMethod
1209
     *
1210
     * @param string $id        The record id
1211
     * @return boolean
1212
     */
1213
    public function restore($id)
1214
    {
1215
        $this->requireSaveMethod();
1216
        $recordSet = $this->getRecordSet();
1217
1218
        $records = $recordSet->select($recordSet->id->is($id), true);
0 ignored issues
show
Unused Code introduced by
The call to app_RecordSet::select() has too many arguments starting with true. ( Ignorable by Annotation )

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

1218
        /** @scrutinizer ignore-call */ 
1219
        $records = $recordSet->select($recordSet->id->is($id), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1219
1220
        $record = null;
1221
        foreach ($records as $record) {
1222
        }
1223
        if (! isset($record)) {
1224
            throw new app_AccessException('Sorry, You are not allowed to perform this operation');
1225
        }
1226
        if (!$record->isRestorable()) {
1227
            throw new app_AccessException('Sorry, You are not allowed to perform this operation');
1228
        }
1229
1230
        $App = $this->App();
1231
        $deletedMessage = $App->translate('The element has been restored from the trash');
1232
1233
        $record->deleted = app_TraceableRecord::DELETED_STATUS_EXISTING;
0 ignored issues
show
Bug Best Practice introduced by
The property deleted does not exist on app_Record. Since you implemented __set, consider adding a @property annotation.
Loading history...
1234
        $record->save();
1235
        $this->addMessage($deletedMessage);
1236
1237
        $this->addReloadSelector('.depends-' . $record->getClassName());
1238
1239
        return true;
1240
    }
1241
1242
    /**
1243
     * Displays a page asking to confirm the deletion of a record.
1244
     *
1245
     * @param int $id
1246
     */
1247
    public function confirmRestore($id)
1248
    {
1249
        $W = bab_Widgets();
1250
        $App = $this->App();
1251
        $Ui = $App->Ui();
1252
1253
        $recordSet = $this->getRecordSet();
1254
        $records = $recordSet->select($recordSet->id->is($id), true);
0 ignored issues
show
Unused Code introduced by
The call to app_RecordSet::select() has too many arguments starting with true. ( Ignorable by Annotation )

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

1254
        /** @scrutinizer ignore-call */ 
1255
        $records = $recordSet->select($recordSet->id->is($id), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1255
1256
        $record = null;
1257
        foreach ($records as $record) {
1258
        }
1259
        if (! isset($record)) {
1260
            throw new app_AccessException('Sorry, You are not allowed to perform this operation');
1261
        }
1262
1263
        $page = $Ui->Page();
1264
1265
        $page->addClass('app-page-editor');
1266
        $page->setTitle($App->translate('Restore from trash'));
1267
1268
        $form = new app_Editor($App);
1269
1270
        $recordTitle = $record->getRecordTitle();
1271
1272
        $subTitle = $App->translate($recordSet->getDescription()) . ' "' . $recordTitle . '"';
1273
        $form->addItem($W->Title($subTitle, 5));
1274
1275
        $confirmedAction = $this->proxy()->restore($id);
0 ignored issues
show
Bug introduced by
The method restore() does not exist on app_Controller. 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

1275
        $confirmedAction = $this->proxy()->/** @scrutinizer ignore-call */ restore($id);
Loading history...
1276
        $parameters = $confirmedAction->getParameters();
1277
        foreach ($parameters as $key => $value) {
1278
            $form->setHiddenValue($key, $value);
1279
        }
1280
        $form->addButton(
1281
            $W->SubmitButton()
1282
                ->setAjaxAction($confirmedAction)
1283
                ->setLabel($App->translate('Restore from trash'))
1284
        );
1285
        $form->addButton($W->SubmitButton()->setLabel($App->translate('Cancel'))->addClass('widget-close-dialog'));
1286
        $page->addItem($form);
1287
1288
        return $page;
1289
    }
1290
1291
    /**
1292
     * @param array     $filter
1293
     * @param string    $type
1294
     * @param string    $itemId
1295
     */
1296
    public function filteredTrash($filter = null, $type = null, $itemId = null)
1297
    {
1298
        $W = bab_Widgets();
1299
1300
        $view = $this->modelView($filter, $type, null, $itemId);
1301
        $view->setAjaxAction();
1302
1303
        if (isset($filter)) {
1304
            $view->setFilterValues($filter);
1305
        }
1306
        $filter = $view->getFilterValues();
1307
1308
        if (isset($filter['showTotal']) && $filter['showTotal']) {
1309
            $view->displaySubTotalRow(true);
1310
        }
1311
1312
1313
        $recordSet = $this->getRecordSet();
1314
        $view->setRecordSet($recordSet);
1315
        $view->addDefaultColumns($recordSet);
1316
1317
        $conditions = $view->getFilterCriteria($filter);
1318
        $conditions = $conditions->_AND_(
1319
            $recordSet->isReadable()
1320
        );
1321
1322
        $conditions = $conditions->_AND_(
1323
            $recordSet->deleted->is(app_TraceableRecord::DELETED_STATUS_IN_TRASH)
0 ignored issues
show
Bug Best Practice introduced by
The property deleted does not exist on app_RecordSet. Since you implemented __get, consider adding a @property annotation.
Loading history...
1324
        );
1325
1326
        $records = $recordSet->select($conditions, true);
0 ignored issues
show
Unused Code introduced by
The call to app_RecordSet::select() has too many arguments starting with true. ( Ignorable by Annotation )

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

1326
        /** @scrutinizer ignore-call */ 
1327
        $records = $recordSet->select($conditions, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1327
1328
        $view->setDataSource($records);
0 ignored issues
show
Bug introduced by
$records of type app_Record[] is incompatible with the type ORM_Iterator expected by parameter $iterator of widget_TableModelView::setDataSource(). ( Ignorable by Annotation )

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

1328
        $view->setDataSource(/** @scrutinizer ignore-type */ $records);
Loading history...
1329
1330
        $view->allowColumnSelection();
1331
1332
        $filterPanel = $view->advancedFilterPanel($filter);
1333
1334
//         $toolbar = $this->toolbar($view);
1335
1336
        $box = $W->VBoxItems(
1337
//             $toolbar,
1338
            $filterPanel
1339
        );
1340
        $box->setReloadAction($this->proxy()->filteredTrash(null, null, $view->getId()));
0 ignored issues
show
Bug introduced by
The method filteredTrash() does not exist on app_Controller. 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

1340
        $box->setReloadAction($this->proxy()->/** @scrutinizer ignore-call */ filteredTrash(null, null, $view->getId()));
Loading history...
1341
1342
        return $box;
1343
    }
1344
1345
1346
1347
    public function displayTrash()
1348
    {
1349
        $App = $this->App();
1350
        $Ui = $App->Ui();
1351
1352
        $page = $Ui->Page();
1353
1354
//         $page->setTitle($App->translate('Trash'));
1355
1356
1357
        $trashView = $this->filteredTrash();
1358
1359
        $page->addItem($trashView);
1360
1361
        $itemMenus = $this->getListItemMenus();
1362
        foreach ($itemMenus as $itemMenuId => $itemMenu) {
1363
            $page->addItemMenu($itemMenuId, $itemMenu['label'], $itemMenu['action']);
0 ignored issues
show
Deprecated Code introduced by
The function Widget_BabPage::addItemMenu() has been deprecated: Replaced by Widget_Tabs ( Ignorable by Annotation )

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

1363
            /** @scrutinizer ignore-deprecated */ $page->addItemMenu($itemMenuId, $itemMenu['label'], $itemMenu['action']);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1364
        }
1365
        $page->setCurrentItemMenu('displayTrash');
0 ignored issues
show
Deprecated Code introduced by
The function Widget_BabPage::setCurrentItemMenu() has been deprecated: Replaced by Widget_Tabs ( Ignorable by Annotation )

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

1365
        /** @scrutinizer ignore-deprecated */ $page->setCurrentItemMenu('displayTrash');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
1366
1367
        return $page;
1368
    }
1369
1370
    protected function getClass()
1371
    {
1372
        return get_class($this);
1373
    }
1374
1375
1376
        /**
1377
     * @return string[]
1378
     */
1379
    public function getFilterNames()
1380
    {
1381
        $id = $this->getModelViewDefaultId();
1382
1383
        $filters = array();
1384
1385
        $registry = bab_getRegistryInstance();
1386
1387
        $userId = '0';
1388
        $registry->changeDirectory('/widgets/user/' . $userId . '/' . $id. '/filters');
1389
1390
        while ($filterName = $registry->fetchChildKey()) {
1391
            $filters[] = $filterName;
1392
        }
1393
1394
        $userId = bab_getUserId();
1395
        $registry->changeDirectory('/widgets/user/' . $userId . '/' . $id. '/filters');
1396
1397
        while ($filterName = $registry->fetchChildKey()) {
1398
            $filters[] = $filterName;
1399
        }
1400
1401
        return $filters;
1402
    }
1403
1404
1405
1406
    /**
1407
     * Sets the currently used filter for the page.
1408
     *
1409
     * @param string $filterName
1410
     * @return boolean
1411
     */
1412
    public function setCurrentFilterName($filterName)
1413
    {
1414
        $W = bab_Widgets();
1415
        $tableview = $this->modelView(null, 'table');
1416
        $W->setUserConfiguration($tableview->getId(). '/currentFilterName', $filterName, 'widgets', false);
1417
1418
        $registry = bab_getRegistryInstance();
1419
        $userId = '0';
1420
        $registry->changeDirectory('/widgets/user/' . $userId . '/' . $tableview->getId() . '/filters');
1421
        $filterValues = $registry->getValue($filterName);
1422
1423
        if (!$filterValues) {
1424
            $filterValues = $W->getUserConfiguration($tableview->getId() . '/filters/' . $filterName, 'widgets', false);
1425
        }
1426
1427
        $tableview = $this->modelView($filterValues, 'table');
1428
        $tableview->setFilterValues($filterValues['values']);
1429
1430
        return true;
1431
    }
1432
1433
1434
1435
    /**
1436
     *
1437
     * @return string|null
1438
     */
1439
    protected function getCurrentFilterName()
1440
    {
1441
        $W = bab_Widgets();
1442
        $id = $this->getModelViewDefaultId();
1443
        $filter = $W->getUserConfiguration($id. '/currentFilterName', 'widgets', false);
1444
1445
        return $filter;
1446
    }
1447
1448
1449
1450
    /**
1451
     * @return boolean
1452
     */
1453
    public function resetFilters($name = null)
1454
    {
1455
        if (isset($name)) {
1456
            $W = bab_Widgets();
1457
            $filter = $W->getUserConfiguration($tableview->getId(). '/filters/' . $name, 'widgets', false);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tableview seems to be never defined.
Loading history...
1458
            $filterValues = $filter['values'];
1459
        } else {
1460
            $filterValues = null;
1461
        }
1462
1463
        $tableview = $this->modelView($filterValues, 'table');
1464
        $tableview->setFilterValues($filterValues);
1465
1466
        return true;
1467
    }
1468
1469
1470
1471
    /**
1472
     * Saves the values of the current view filter under the specified name.
1473
     *
1474
     * @param string $name
1475
     * @return boolean
1476
     */
1477
    public function saveCurrentFilter($name = null, $description = null)
1478
    {
1479
        $W = bab_Widgets();
1480
        $tableview = $this->modelView(null, 'table');
1481
        $filterValues = $tableview->getFilterValues();
1482
1483
        $data = array(
1484
            'description' => $description,
1485
            'values' => $filterValues,
1486
        );
1487
1488
        $W->setUserConfiguration($tableview->getId(). '/filters/' . $name, $data, 'widgets', false);
1489
1490
        return true;
1491
    }
1492
1493
1494
    /**
1495
     * Display a dialog to propose saving the current view filter under a specific name.
1496
     *
1497
     * @return app_Page
1498
     */
1499
    public function confirmSaveCurrentFilter()
1500
    {
1501
        $W = bab_Widgets();
1502
        $App = $this->App();
1503
        $Ui = $App->Ui();
1504
1505
        $currentFilterName = $this->getCurrentFilterName();
1506
        $filter = $W->getUserConfiguration($this->getModelViewDefaultId() . '/filters/' . $currentFilterName, 'widgets', false);
1507
1508
        $page = $Ui->Page();
1509
1510
        $page->addClass('crm-page-editor');
1511
        $page->setTitle($App->translate('Save current filter'));
1512
1513
        $form = new app_Editor($App);
1514
1515
1516
        $form->addItem(
1517
            $W->Html(bab_toHtml($App->translate('Save the current filter values so that you can reuse them later.')))
1518
        );
1519
1520
        $form->addItem(
1521
            $W->LabelledWidget(
1522
                $App->translate('Name'),
1523
                $W->LineEdit()->setValue($currentFilterName),
1524
                'name'
1525
            )
1526
        );
1527
        $form->addItem(
1528
            $W->LabelledWidget(
1529
                $App->translate('Description'),
1530
                $W->TextEdit()->setValue($filter['description']),
1531
                'description'
1532
            )
1533
        );
1534
1535
        $confirmedAction = $this->proxy()->saveCurrentFilter();
0 ignored issues
show
Bug introduced by
The method saveCurrentFilter() does not exist on app_Controller. 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

1535
        $confirmedAction = $this->proxy()->/** @scrutinizer ignore-call */ saveCurrentFilter();
Loading history...
1536
        $form->addButton(
1537
            $W->SubmitButton()
1538
                ->setAjaxAction($confirmedAction)
1539
                ->setLabel($App->translate('Save'))
1540
        );
1541
1542
        $page->addItem($form);
1543
1544
        return $page;
1545
    }
1546
1547
1548
    /**
1549
     * Display a dialog to propose saving the current view filter under a specific name.
1550
     *
1551
     * @return app_Page
1552
     */
1553
    public function editFilter($name)
1554
    {
1555
        $W = bab_Widgets();
1556
        $App = $this->App();
1557
        $Ui = $App->Ui();
1558
1559
        $filter = $W->getUserConfiguration($this->getModelViewDefaultId() . '/filters/' . $name, 'widgets', false);
1560
1561
        $page = $Ui->Page();
1562
1563
        $page->addClass('crm-page-editor');
1564
        $page->setTitle($App->translate('Edit filter'));
1565
1566
        $form = new app_Editor($App);
1567
1568
        $form->addItem(
1569
            $W->LabelledWidget(
1570
                $App->translate('Name'),
1571
                $W->LineEdit()->setValue($name),
1572
                'name'
1573
            )
1574
        );
1575
        $form->addItem(
1576
            $W->LabelledWidget(
1577
                $App->translate('Description'),
1578
                $W->TextEdit()->setValue($filter['description']),
1579
                'description'
1580
            )
1581
        );
1582
1583
        $confirmedAction = $this->proxy()->saveCurrentFilter();
1584
        $form->addButton(
1585
            $W->SubmitButton()
1586
                ->setAjaxAction($confirmedAction)
1587
                ->setLabel($App->translate('Save'))
1588
        );
1589
1590
        $page->addItem($form);
1591
1592
        return $page;
1593
    }
1594
1595
1596
    public function manageFilters()
1597
    {
1598
        $App = $this->App();
1599
        $Ui = $App->Ui();
1600
        $W = bab_Widgets();
1601
        $page = $Ui->Page();
1602
1603
        $page->setTitle($App->translate('Manage filters'));
1604
1605
        $filtersBox = $W->VBoxItems();
1606
1607
        $page->addItem($filtersBox);
1608
1609
        $filterNames = $this->getFilterNames();
1610
        foreach ($filterNames as $filterName) {
1611
            $filter = $W->getUserConfiguration($this->getModelViewDefaultId() . '/filters/' . $filterName, 'widgets', false);
1612
1613
            $filterBox = $W->FlowItems()
1614
                ->setVerticalAlign('top')
1615
                ->setSizePolicy('widget-list-element');
1616
            $filterBox->addItem(
1617
                $W->VBoxItems(
1618
                    $W->Label($filterName)
1619
                        ->addClass('widget-strong'),
1620
                    $W->Label($filter['description'])
1621
                )->setSizePolicy('widget-90pc')
1622
            );
1623
            $filterBox->addItem(
1624
                $W->FlowItems(
1625
                    $W->Link('', $this->proxy()->editFilter($filterName))
0 ignored issues
show
Bug introduced by
The method editFilter() does not exist on app_Controller. 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

1625
                    $W->Link('', $this->proxy()->/** @scrutinizer ignore-call */ editFilter($filterName))
Loading history...
1626
                        ->setOpenMode(Widget_Link::OPEN_DIALOG_AND_RELOAD)
1627
                        ->addClass('icon', Func_Icons::ACTIONS_DOCUMENT_EDIT),
1628
                    $W->Link('', $this->proxy()->confirmDeleteFilter($filterName))
0 ignored issues
show
Bug introduced by
The method confirmDeleteFilter() does not exist on app_Controller. 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

1628
                    $W->Link('', $this->proxy()->/** @scrutinizer ignore-call */ confirmDeleteFilter($filterName))
Loading history...
1629
                        ->setOpenMode(Widget_Link::OPEN_DIALOG_AND_RELOAD)
1630
                        ->addClass('icon', Func_Icons::ACTIONS_EDIT_DELETE)
1631
                )->setSizePolicy('widget-10pc')
1632
                ->addClass(Func_Icons::ICON_LEFT_16)
1633
            );
1634
            $filtersBox->addItem($filterBox);
1635
        }
1636
1637
        $page->setReloadAction($this->proxy()->manageFilters());
0 ignored issues
show
Bug introduced by
The method manageFilters() does not exist on app_Controller. 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

1637
        $page->setReloadAction($this->proxy()->/** @scrutinizer ignore-call */ manageFilters());
Loading history...
1638
1639
        return $page;
1640
    }
1641
1642
1643
1644
    /**
1645
     * Display a dialog to propose deleting a view filter.
1646
     *
1647
     * @param string $name
1648
     * @return app_Page
1649
     */
1650
    public function confirmDeleteFilter($name)
1651
    {
1652
        $W = bab_Widgets();
1653
        $App = $this->App();
1654
        $Ui = $App->Ui();
1655
1656
        $filter = $W->getUserConfiguration($this->getModelViewDefaultId() . '/filters/' . $name, 'widgets', false);
1657
1658
        $page = $Ui->Page();
1659
1660
        $page->addClass('crm-page-editor');
1661
        $page->setTitle($App->translate('Delete filter'));
1662
1663
        $form = new app_Editor($App);
1664
1665
        $form->addItem(
1666
            $W->Html(bab_toHtml($filter['description']))
1667
        );
1668
1669
        $form->setHiddenValue('name', $name);
1670
1671
        $confirmedAction = $this->proxy()->deleteFilter();
0 ignored issues
show
Bug introduced by
The method deleteFilter() does not exist on app_Controller. 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

1671
        $confirmedAction = $this->proxy()->/** @scrutinizer ignore-call */ deleteFilter();
Loading history...
1672
        $form->addButton(
1673
            $W->SubmitButton()
1674
                ->setAjaxAction($confirmedAction)
1675
                ->setLabel($App->translate('Delete'))
1676
        );
1677
1678
        $page->addItem($form);
1679
1680
        return $page;
1681
    }
1682
1683
1684
    /**
1685
     *
1686
     * @param string $name
1687
     */
1688
    public function deleteFilter($name = null)
1689
    {
1690
        $this->requireDeleteMethod();
1691
1692
        $W = bab_Widgets();
1693
        $W->deleteUserConfiguration($this->getModelViewDefaultId() . '/filters/' . $name, 'widgets', false);
1694
1695
        return true;
1696
    }
1697
}
1698