AppTableModelView::initHeaderRow()   F
last analyzed

Complexity

Conditions 23
Paths 1521

Size

Total Lines 105
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 69
c 2
b 0
f 0
dl 0
loc 105
rs 0
cc 23
nc 1521
nop 1

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
// -------------------------------------------------------------------------
4
// OVIDENTIA http://www.ovidentia.org
5
// Ovidentia is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2, or (at your option)
8
// any later version.
9
//
10
// This program is distributed in the hope that it will be useful, but
11
// WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
// See the GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18
// USA.
19
// -------------------------------------------------------------------------
20
/**
21
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
22
 * @copyright Copyright (c) 2022 by SI4YOU ({@link https://www.siforyou.com})
23
 */
24
namespace Capwelton\LibApp\Ui;
25
26
use Capwelton\Widgets\Widgets\Abstracts\WidgetItem;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Abstracts\WidgetItem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Capwelton\Widgets\Widgets\Form\WidgetForm;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Form\WidgetForm was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Capwelton\Widgets\Widgets\Interfaces\WidgetDisplayableInterface;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widget...getDisplayableInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use Capwelton\Widgets\Widgets\Item\WidgetFilter;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Item\WidgetFilter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use Capwelton\Widgets\Widgets\Item\WidgetLabel;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Item\WidgetLabel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use Capwelton\Widgets\Widgets\Item\WidgetLink;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Item\WidgetLink was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use Capwelton\Widgets\Widgets\Layout\WidgetFlexLayout;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widgets\Layout\WidgetFlexLayout was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
33
use Capwelton\Widgets\Widgets\Table\WidgetTableModelView;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widget...le\WidgetTableModelView 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...
34
use Capwelton\Widgets\Widgets\Table\WidgetTableModelViewColumn;
0 ignored issues
show
Bug introduced by
The type Capwelton\Widgets\Widget...getTableModelViewColumn 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...
35
use Capwelton\LibApp\Ctrl\AppCtrlRecord;
36
use Capwelton\LibApp\Func_App;
37
use Capwelton\LibApp\Set\AppRecordSet;
38
use Capwelton\LibOrm\Field\ORMField;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Field\ORMField was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
39
use Capwelton\LibOrm\Field\ORMFkField;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\Field\ORMFkField 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...
40
use Capwelton\LibOrm\ORMRecordSet;
0 ignored issues
show
Bug introduced by
The type Capwelton\LibOrm\ORMRecordSet 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...
41
use function Capwelton\Widgets\widget_translate;
0 ignored issues
show
introduced by
The function Capwelton\Widgets\widget_translate was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
42
43
class AppTableModelView extends WidgetTableModelView
44
{
45
    
46
    /**
47
     * Filter form reset button
48
     */
49
    protected $reset = null;
50
    
51
    protected $highlightRows = null;
52
    
53
    /**
54
     * @var Func_App
55
     */
56
    private $app = null;
57
    
58
    /**
59
     * @var AppCtrlRecord
60
     */
61
    protected $recordController = null;
62
    
63
    /**
64
     * @var AppCtrlRecord
65
     */
66
    protected $recordControllerProxy = null;
67
    
68
    protected $filterBaseUrl = null;
69
    
70
    protected $displayAdvancedForm = true;
71
    
72
    /**
73
     * @param Func_App $app
74
     * @param string $id
75
     */
76
    public function __construct(Func_App $app = null, $id = null)
77
    {
78
        parent::__construct($id);
79
        $this->setApp($app);
80
        $this->displayAdvancedForm(true);
81
    }
82
    
83
    public function displayAdvancedForm($displayAdvancedForm = true)
84
    {
85
        $this->displayAdvancedForm = $displayAdvancedForm;
86
        return $this;
87
    }
88
    
89
    public function isAdvancedFormDisplayed()
90
    {
91
        return $this->displayAdvancedForm;
92
    }
93
    
94
    /**
95
     * Called before data rows
96
     *
97
     * @return void
98
     */
99
    protected function initHeaderRow(ORMRecordSet $set)
100
    {
101
        require_once $GLOBALS['babInstallPath'] . 'utilit/urlincl.php';
102
        
103
        \bab_functionality::includefile('Icons');
0 ignored issues
show
Bug introduced by
The method includefile() does not exist on bab_functionality. It seems like you code against a sub-type of bab_functionality such as Capwelton\LibApp\Func_App. ( Ignorable by Annotation )

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

103
        \bab_functionality::/** @scrutinizer ignore-call */ 
104
                            includefile('Icons');
Loading history...
104
        
105
        $W = bab_Widgets();
106
        
107
        $this->addHeaderSection();
108
        $this->setCurrentSection('header');
109
        
110
        $col = 0;
111
        
112
        $this->toggleCheckAllBox = null;
0 ignored issues
show
Bug Best Practice introduced by
The property toggleCheckAllBox does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
113
        $this->displayedIds = array();
0 ignored issues
show
Bug Best Practice introduced by
The property displayedIds does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
114
        
115
        $filterValues = $this->getFilterValues();
116
        
117
        foreach ($this->visibleColumns as $columnPath => $column){
118
            
119
            if(! isset($this->columnsDescriptions[$columnPath])){
120
                $this->columnsDescriptions[$columnPath] = $column->getDescription();
0 ignored issues
show
Bug Best Practice introduced by
The property columnsDescriptions does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
121
            }
122
            
123
            $columnLabel = $this->columnsDescriptions[$columnPath];
124
            
125
            $columnIcon = $column->getIcon();
126
            $isSortable = $column->isSortable();
127
            $isSearchable = $column->isSearchable() && $this->getFilterInputWidget($columnPath, $column->getField());
128
            
129
            $sizePolicy = 'widget-actions-target';
130
            
131
            if($this->isMultiSelect() && $columnPath === '_select_'){
132
                $this->toggleCheckAllBox = $W->CheckBox();
133
                $this->toggleCheckAllBox->setName('toggleCheckAllBox');
134
                $this->toggleCheckAllBox->setTitle(widget_translate('Select all on page'));
135
                $this->toggleCheckAllBox->setSizePolicy('condensed');
136
                $this->toggleCheckAllBox->setCheckedValue(true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $value of Widget_CheckBox::setCheckedValue(). ( Ignorable by Annotation )

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

136
                $this->toggleCheckAllBox->setCheckedValue(/** @scrutinizer ignore-type */ true);
Loading history...
137
                if(isset($_SESSION['toggleCheckAllBox'][$this->getId()]) && ! empty($_SESSION['toggleCheckAllBox'][$this->getId()]) && $_SESSION['toggleCheckAllBox'][$this->getId()] == 'on'){
138
                    $this->toggleCheckAllBox->setValue(true);
139
                }
140
                $isSearchable = false;
141
                $isSortable = false;
142
                $columnItem = $W->FlexItems($this->toggleCheckAllBox);
0 ignored issues
show
Bug introduced by
The method FlexItems() does not exist on Func_Widgets. ( Ignorable by Annotation )

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

142
                /** @scrutinizer ignore-call */ 
143
                $columnItem = $W->FlexItems($this->toggleCheckAllBox);

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...
143
            }
144
            elseif(isset($this->sortParameterName) && self::getRecordSetField($set, $columnPath) && $isSortable){
145
                if(! isset($this->sortBaseUrl)){
146
                    $this->sortBaseUrl = \bab_url::request_gp();
0 ignored issues
show
Bug Best Practice introduced by
The property sortBaseUrl does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
147
                }
148
                
149
                if($this->sortField === $columnPath && $this->sortAscending){
150
                    $direction = ':down';
151
                }
152
                else{
153
                    $direction = ':up';
154
                }
155
                
156
                $url = \bab_url::mod($this->sortBaseUrl, $this->sortParameterName, $columnPath . $direction);
157
                if($anchor = $this->getAnchor()){
158
                    $url .= '#' . urlencode($anchor);
159
                }
160
                
161
                $columnItem = $W->Link($W->FlexItems($W->Label($columnLabel), $W->Items()
162
                    ->addClass('widget-table-column-sorting-icons'))
163
                    ->setAlignItems(WidgetFlexLayout::FLEX_ALIGN_CONTENT_CENTER), $url)
164
                    ->addClass('widget-table-column-sorting-action');
165
                if($this->sortAjaxAction){
166
                    $columnItem->setAjaxAction($this->sortAjaxAction->setParameter('sort', $columnPath . $direction), '');
167
                }
168
                $columnItem = $W->FlexItems($columnItem);
169
            }
170
            else{
171
                $columnItem = $W->FlexItems($W->Label($columnLabel), $W->Label(''));
172
            }
173
            
174
            $columnItem->setAlignItems(WidgetFlexLayout::FLEX_ALIGN_CONTENT_CENTER)->setJustifyContent(WidgetFlexLayout::FLEX_JUSTIFY_CONTENT_SPACE_BETWEEN);
175
            $columnItem->addClass('widget-table-column-header-item');
176
            
177
            if(isset($columnIcon)){
178
                $columnItem->addClass('icon', $columnIcon)->setSizePolicy(\Func_Icons::ICON_LEFT_16);
179
            }
180
            
181
            if($isSortable){
182
                $sizePolicy .= ' widget-table-column-sortable';
183
            }
184
            if($isSearchable){
185
                if(! isset($this->filterBaseUrl)){
186
                    $this->filterBaseUrl = $this->getRecordControllerProxy()->displayListFilter();
187
                }
188
                $url = $this->filterBaseUrl;
189
                $url->setParameter('col', $columnPath);
190
                $url->setParameter('key', $this->getId());
191
                $columnItem->addItem($W->Link('', $url->url())
192
                    ->setOpenMode(WidgetLink::OPEN_DIALOG)
193
                    ->addClass('widget-table-column-search-action')
194
                    ->setDialogClass('box blue'), 0);
0 ignored issues
show
Bug introduced by
The method setDialogClass() does not exist on Widget_Link. ( Ignorable by Annotation )

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

194
                    ->/** @scrutinizer ignore-call */ setDialogClass('box blue'), 0);

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...
195
                $sizePolicy .= ' widget-table-column-searchable';
196
                if(isset($filterValues[$columnPath]) && ! empty($filterValues[$columnPath])){
197
                    $sizePolicy .= ' widget-table-column-searched';
198
                }
199
            }
200
            $items = $W->Items()->setSizePolicy($sizePolicy);
201
            $items->addItem($columnItem);
202
            
203
            $this->addItem($items, 0, $col ++);
204
        }
205
    }
206
    
207
    protected function initRow($record, $row)
208
    {
209
        if($this->highlightRows == null){
210
            $this->highlightRows = $this->getHighlightedRows();
211
        }
212
        
213
        if(in_array($record->id, $this->highlightRows)){
214
            $this->addRowClass($row, "app_highlightRow");
215
        }
216
        $this->addRowClass($row, "app_highlightAvailable");
217
        return parent::initRow($record, $row);
218
    }
219
    
220
    /**
221
     * Forces the \Func_App object to which this object is 'linked'.
222
     *
223
     * @param Func_App $app
224
     * @return self
225
     */
226
    public function setApp(Func_App $app = null)
227
    {
228
        $this->app = $app;
229
        return $this;
230
    }
231
    
232
    /**
233
     * Get App object to use with this SET
234
     *
235
     * @return Func_App
236
     */
237
    public function App()
238
    {
239
        if(! isset($this->app)){
240
            // If the app object was not specified (through the setApp() method)
241
            // we try to select one according to the classname prefix.
242
            list ($prefix) = explode('_', get_class($this));
243
            $functionalityName = ucwords($prefix);
244
            $this->app = @\bab_functionality::get('App/' . $functionalityName);
0 ignored issues
show
Documentation Bug introduced by
@bab_functionality::get(...' . $functionalityName) is of type bab_functionality, but the property $app was declared to be of type Capwelton\LibApp\Func_App. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
245
            if(! $this->app){
246
                $this->app = @\bab_functionality::get('App');
247
            }
248
        }
249
        return $this->app;
250
    }
251
    
252
    protected function addCustomFields(AppRecordSet $recordSet)
253
    {
254
        $customFields = $recordSet->getCustomFields();
255
        
256
        foreach ($customFields as $customField){
257
            $fieldname = $customField->fieldname;
258
            $this->addColumn(app_TableModelViewColumn($recordSet->$fieldname, $customField->name)->setSortable(true)
259
                ->setExportable(true)
260
                ->setSearchable($customField->searchable)
261
                ->setVisible($customField->visible));
262
        }
263
    }
264
    
265
    /**
266
     * Get a generic filter panel
267
     * Use setPageLength to define the default number of items per page
268
     *
269
     * @param array $filter
270
     *            Filter values
271
     * @param string $name
272
     *            filter form name
273
     * @param string $anchor
274
     *            anchor in destination page of filter, the can be a WidgetTab id
275
     * @return WidgetFilter
276
     */
277
    public function filterPanel($filter = null, $name = null)
278
    {
279
        $W = bab_Widgets();
280
        
281
        $filterPanel = $W->Filter();
282
        $filterPanel->setLayout($W->VBoxLayout());
283
        if(isset($name)){
284
            $filterPanel->setName($name);
285
        }
286
        
287
        $pageLength = $this->getPageLength();
288
        if(null === $pageLength){
289
            $pageLength = 15;
290
        }
291
        
292
        $pageNumber = $this->getCurrentPage();
293
        if(null === $pageNumber){
294
            $pageNumber = 0;
295
        }
296
        
297
        $this->setPageLength(isset($filter['pageSize']) ? $filter['pageSize'] : $pageLength);
298
        $this->setCurrentPage(isset($filter['pageNumber']) ? $filter['pageNumber'] : $pageNumber);
299
        
300
        if(isset($name)){
301
            $this->sortParameterName = $name . '[filter][sort]';
0 ignored issues
show
Bug Best Practice introduced by
The property sortParameterName does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
302
        }
303
        else{
304
            $this->sortParameterName = 'filter[sort]';
305
        }
306
        
307
        if(isset($filter['sort'])){
308
            $this->setSortField($filter['sort']);
309
        }
310
        elseif(! isset($this->sortField)){
311
            
312
            if(method_exists($this, 'getDefaultSortField')){
313
                $this->setSortField($this->getDefaultSortField());
314
            }
315
            else{
316
                $columns = $this->getVisibleColumns();
317
                $sortField = key($columns);
318
                $this->setSortField($sortField);
319
            }
320
        }
321
        
322
        $form = $this->getFilterForm();
323
        
324
        if(isset($filter)){
325
            if(isset($name)){
326
                $path = array(
327
                    $name,
328
                    'filter'
329
                );
330
            }
331
            else{
332
                $path = array(
333
                    'filter'
334
                );
335
            }
336
            $form->setValues($filter, $path);
337
        }
338
        
339
        $filterPanel->setFilter($form);
340
        $filterPanel->setFiltered($this);
341
        
342
        return $filterPanel;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $filterPanel returns the type Widget_Filter which is incompatible with the documented return type Capwelton\Widgets\Widgets\Item\WidgetFilter.
Loading history...
343
    }
344
    
345
    /**
346
     * Add the filter fields to the filter form
347
     *
348
     * @param WidgetForm $form
349
     *
350
     */
351
    protected function handleAdvancedFilterFields(WidgetItem $form)
352
    {
353
    }
354
    
355
    protected function isFilterFieldSpecified($filter, $fieldPath)
356
    {
357
        if(isset($filter[$fieldPath])){
358
            $value = $filter[$fieldPath];
359
            if(is_array($value)){
360
                foreach ($value as $val){
361
                    $val = trim($val);
362
                    if(! empty($val)){
363
                        return true;
364
                    }
365
                }
366
                return false;
367
            }
368
            
369
            if(trim($value) !== ''){
370
                return true;
371
            }
372
        }
373
        
374
        return false;
375
    }
376
    
377
    protected function handleFilterInputWidget($name, ORMField $field = null)
378
    {
379
        if(null === $field){
380
            return null;
381
        }
382
        
383
        $W = bab_Widgets();
384
        
385
        if($field instanceof ORMFkField){            
386
            $App = $this->App();
387
            $setName = $field->getForeignSetName();
388
            
389
            $pos = strrpos($setName, '\\');
390
            if($pos === false){
391
                list (, $appSetName) = explode('_', $setName);
392
            }
393
            else{
394
                list (, $appSetName) = array(
395
                    substr($setName, 0, $pos),
396
                    substr($setName, $pos + 1)
397
                );
398
            }
399
            
400
            $set = $App->$appSetName();
401
            $set->setName($field->getName());
402
            $set->setDescription($field->getDescription());
403
            
404
            if($set === null){
405
                return null;
406
            }
407
            
408
            $values = $set->select();
409
            if($values->count()>15){
410
                $widget = bab_Widgets()->select2();
0 ignored issues
show
Bug introduced by
The method select2() does not exist on Func_Widgets. ( Ignorable by Annotation )

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

410
                $widget = bab_Widgets()->/** @scrutinizer ignore-call */ select2();

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...
411
                $widget->setDataSource($set->getController()->search());
412
            }else{
413
                $widget = $W->Select();
414
                $widget->addOption('', '');
415
                foreach ($values as $record){
416
                    $widget->addOption($record->id, (string) $record->name);
417
                }
418
                
419
            }
420
            return $widget;
421
        }
422
        
423
        return parent::handleFilterInputWidget($name, $field);
424
    }
425
    
426
    public function getFilterInputWidget($name, ORMField $field = null)
427
    {
428
        return $this->handleFilterInputWidget($name, $field);
429
    }
430
    
431
    public function getFilterLabelWidget($name, ORMField $field = null)
432
    {
433
        return $this->handleFilterLabelWidget($name, $field);
434
    }
435
    
436
    public function getFilterFormItem($name, ORMField $field = null)
437
    {
438
        return $this->handleFilterLabel($this->getFilterLabelWidget($name, $field), $this->getFilterInputWidget($name, $field));
0 ignored issues
show
Bug introduced by
It seems like $this->getFilterInputWidget($name, $field) can also be of type null; however, parameter $input of Capwelton\LibApp\Ui\AppT...ew::handleFilterLabel() does only seem to accept Capwelton\Widgets\Widget...getDisplayableInterface, maybe add an additional type check? ( Ignorable by Annotation )

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

438
        return $this->handleFilterLabel($this->getFilterLabelWidget($name, $field), /** @scrutinizer ignore-type */ $this->getFilterInputWidget($name, $field));
Loading history...
439
    }
440
    
441
    /**
442
     * Handle label and input widget merge in one item before adding to the filter form
443
     * default is a vertical box layout
444
     *
445
     * @param WidgetLabel $label
446
     * @param WidgetDisplayableInterface $input
447
     * @return WidgetItem
448
     */
449
    protected function handleFilterLabel(WidgetLabel $label, WidgetDisplayableInterface $input)
450
    {
451
        $W = bab_Widgets();
452
        
453
        return $W->FlowItems($W->LabelledWidget($label->getText(), $input));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $W->FlowItems($W-...el->getText(), $input)) returns the type Widget_FlowLayout which is incompatible with the documented return type Capwelton\Widgets\Widgets\Abstracts\WidgetItem.
Loading history...
454
    }
455
    
456
    protected function getSearchItem()
457
    {
458
        $W = bab_Widgets();
459
        
460
        return $W->LineEdit()
461
            ->setName('search')
462
            ->addClass('widget-100pc');
463
    }
464
    
465
    /**
466
     * Get an advanced form filter
467
     *
468
     * @see WidgetFilter
469
     *
470
     * @param string $id
471
     * @param array $filter
472
     *
473
     * @return WidgetForm
474
     */
475
    public function getAdvancedFilterForm($id = null, $filter = null)
476
    {
477
        $App = $this->App();
478
        
479
        $W = bab_Widgets();
480
        
481
        $formItem = $this->getSearchItem();
482
        
483
        $activeFiltersFrame = $W->Frame(null, $W->FlowItems($W->VBoxItems($W->Label($App->translate('Search'))
484
            ->setAssociatedWidget($formItem), $formItem))
485
            ->setHorizontalSpacing(2, 'em')
486
            ->setVerticalSpacing(1, 'em')
487
            ->setVerticalAlign('bottom'));
488
        
489
        $addFilterButton = $W->Link($App->translate('More criteria'), $this->getRecordControllerProxy()
490
            ->displayListMoreCriteria($this->getId()))
491
            ->addClass('widget-actionbutton')
492
            ->setIcon(\Func_Icons::ACTIONS_LIST_ADD)
493
            ->setOpenMode(WidgetLink::OPEN_DIALOG)
494
            ->setDialogClass('box gradient blue app-morecriteria-dialog');
495
        
496
        $displayAdvancedForm = $this->isAdvancedFormDisplayed();
497
        $advancedFiltersFrame = $W->VBoxItems($addFilterButton)->addClass('widget-instant-container');
498
            
499
        if($displayAdvancedForm){
500
            $filterBox = $W->FlowLayout()
501
                ->addClass('widget-instant-form')
502
                ->setHorizontalSpacing(2, 'em')
503
                ->setVerticalSpacing(1, 'em')
504
                ->setVerticalAlign('bottom');
505
            $advancedFiltersFrame->addItem($filterBox);
506
        }
507
        
508
        $columns = $this->getVisibleColumns();
509
        
510
        foreach ($columns as $fieldName => $column){
511
            $field = $column->getField();
512
            if(! $column->isSearchable()){
513
                continue;
514
            }
515
            
516
            if(! ($field instanceof ORMField)){
517
                $field = null;
518
            }
519
            
520
            $label = $this->handleFilterLabelWidget($fieldName, $field);
521
            $input = $this->handleFilterInputWidget($fieldName, $field);
522
            
523
            if(isset($input) && isset($label)){
524
                
525
                $input->setName($fieldName);
526
                $label->setAssociatedWidget($input);
527
                
528
                $input->addClass('widget-100pc');
529
                
530
                $formItem = $this->handleFilterLabel($label, $input);
531
                
532
                // $formItem = $W->Section($label->getText(), $input, 7)->setFoldable(true, true);
533
                $formItem->addClass('compact', 'field_' . $fieldName);
534
                
535
                $mainSearch = (method_exists($column, 'isMainSearch') && $column->isMainSearch());
536
                
537
                if($mainSearch || $this->isFilterFieldSpecified($filter, $column->getFieldPath())){
538
                    
539
                    $removeColumnsAction = $W->Action();
540
                    $removeColumnsAction->setMethod('addon/widgets/configurationstorage', 'removeFilter', array(
541
                        'key' => $this->getId(),
542
                        'name' => $column->getFieldPath(),
543
                        'insession' => $this->isConfigurationStorageInSession()
544
                    ));
545
                    
546
                    // $formItem->setFoldable(false);
547
                    $activeFiltersFrame->addItem($W->FlexItems($formItem, $W->Link('', $removeColumnsAction)
548
                        ->setAjaxAction()
549
                        ->addClass('icon', \Func_Icons::STATUS_DIALOG_ERROR)
550
                        ->addAttribute('data-removefor', $column->getFieldPath()))
551
                        ->setAlignItems(WidgetFlexLayout::FLEX_ALIGN_ITEMS_FLEX_END));
552
                }
553
                elseif($displayAdvancedForm){
554
                    $formItem->setSizePolicy('col-lg-2 col-md-3 col-sm-6 col-xs-12');
555
                    $filterBox->addItem($formItem);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $filterBox does not seem to be defined for all execution paths leading up to this point.
Loading history...
556
                }
557
            }
558
        }
559
        
560
        if(! $this->submit){
561
            $this->submit = $W->SubmitButton();
0 ignored issues
show
Bug Best Practice introduced by
The property submit does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
562
            $this->submit->setLabel(Widget_translate('Apply filter'));
563
        }
564
        
565
        if($controller = $this->getRecordController()){
566
            $proxy = $controller->proxy();
567
            $this->reset = $W->Link($App->translate('Reset'), $proxy->resetFilters())
0 ignored issues
show
Bug introduced by
$proxy->resetFilters() of type true is incompatible with the type Widget_Action|bab_url|string expected by parameter $url of Func_Widgets::Link(). ( Ignorable by Annotation )

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

567
            $this->reset = $W->Link($App->translate('Reset'), /** @scrutinizer ignore-type */ $proxy->resetFilters())
Loading history...
568
                ->addClass('icon', \Func_Icons::ACTIONS_VIEW_REFRESH, 'widget-actionbutton')
569
                ->setTitle($App->translate('Reset filter to default values'))
570
                ->setAjaxAction();
571
            
572
            // $this->save = $W->Link(
573
            // $App->translate('Save'),
574
            // $proxy->confirmSaveCurrentFilter()
575
            // )->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_SAVE, 'widget-actionbutton')
576
            // ->setTitle($App->translate('Save current filter'))
577
            // ->setOpenMode(WidgetLink::OPEN_DIALOG_AND_RELOAD);
578
            
579
            // $this->select = null;
580
            
581
            $this->filterMenu = $W->Menu(null, $W->VBoxItems());
0 ignored issues
show
Bug Best Practice introduced by
The property filterMenu does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
582
            $this->filterMenu->setButtonClass('widget-actionbutton icon actions-list-filter');
583
            $this->filterMenu->setButtonLabel($App->translate('Saved filters'));
584
            $this->filterMenu->addClass(\Func_Icons::ICON_LEFT_16);
585
            
586
            $filterNames = $controller->getFilterNames();
587
            if(count($filterNames) > 0){
588
                // $this->select = $W->Menu(null, $W->VBoxItems());
589
                // $this->select->setButtonClass('widget-link icon actions-list-filter');
590
                // $this->select->setButtonLabel($App->translate('Saved filters'));
591
                // $this->select->addClass(\Func_Icons::ICON_LEFT_16);
592
                
593
                foreach ($filterNames as $filterName){
594
                    $filter = $W->getUserConfiguration($controller->getModelViewDefaultId() . '/filters/' . $filterName, 'widgets', false);
595
                    
596
                    // $this->select->addItem(
597
                    // $W->Link(
598
                    // $filterName,
599
                    // $proxy->setCurrentFilterName($filterName)
600
                    // )->setTitle($filter['description'])
601
                    // );
602
                    
603
                    $this->filterMenu->addItem($W->Link($filterName, $proxy->setCurrentFilterName($filterName))
604
                        ->setTitle($filter['description'])
605
                        ->setAjaxAction());
606
                }
607
                // $this->select->addSeparator();
608
                // $this->select->addItem(
609
                // $W->Link(
610
                // $App->translate('Manage filters'),
611
                // $proxy->manageFilters()
612
                // )->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_PROPERTIES)
613
                // ->setOpenMode(WidgetLink::OPEN_DIALOG_AND_RELOAD)
614
                // );
615
                
616
                $this->filterMenu->addSeparator();
617
                $this->filterMenu->addItem($W->Link($App->translate('Manage filters...'), $proxy->manageFilters())
618
                    ->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_PROPERTIES)
619
                    ->setOpenMode(WidgetLink::OPEN_DIALOG));
620
                $this->filterMenu->addSeparator();
621
            }
622
            
623
            $this->filterMenu->addItem($W->Link($App->translate('Save current filter...'), $proxy->confirmSaveCurrentFilter())
624
                ->addClass('icon', \Func_Icons::ACTIONS_DOCUMENT_SAVE)
625
                ->setOpenMode(WidgetLink::OPEN_DIALOG));
626
        }
627
        
628
        $form = $W->Form($id);
629
        $form->setReadOnly(true);
630
        $form->setName('filter');
631
        $form->colon();
632
        $form->checkUnsaved(false, null);
633
        
634
        $form->setLayout($W->FlowItems($activeFiltersFrame, $W->FlowItems($advancedFiltersFrame, $this->submit, $W->FlowItems($this->reset, $this->filterMenu) // $this->save,
635
        // $this->select,
636
        )
637
            ->setHorizontalSpacing(2, 'em')
638
            ->setVerticalSpacing(1, 'em'))
639
            ->setVerticalSpacing(1, 'em')
640
            ->setVerticalAlign('bottom')
641
            ->addClass(\Func_Icons::ICON_LEFT_16));
642
        
643
        $form->setHiddenValue('tg', $App->controllerTg);
644
        $form->setAnchor($this->getAnchor());
645
        
646
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type Widget_Form which is incompatible with the documented return type Capwelton\Widgets\Widgets\Form\WidgetForm.
Loading history...
647
    }
648
    
649
    /**
650
     * Get a advanced filter panel
651
     * Use setPageLength to define the default number of items per page
652
     *
653
     * @param array $filter
654
     *            Filter values
655
     * @param string $name
656
     *            filter form name
657
     * @param string $anchor
658
     *            anchor in destination page of filter, the can be a WidgetTab id
659
     * @return WidgetFilter
660
     */
661
    public function advancedFilterPanel($filter = null, $name = null)
662
    {
663
        $W = bab_Widgets();
664
        
665
        $filterPanel = $W->Filter();
666
        $filterPanel->setLayout($W->VBoxLayout());
667
        if(isset($name)){
668
            $filterPanel->setName($name);
669
        }
670
        
671
        $pageLength = $this->getPageLength();
672
        if(null === $pageLength){
673
            $pageLength = 15;
674
        }
675
        
676
        $pageNumber = $this->getCurrentPage();
677
        if(null === $pageNumber){
678
            $pageNumber = 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $pageNumber is dead and can be removed.
Loading history...
679
        }
680
        
681
        $this->setPageLength(isset($filter['pageSize']) ? $filter['pageSize'] : $pageLength);
682
        // $this->setCurrentPage(isset($filter['pageNumber']) ? $filter['pageNumber'] : $pageNumber);
683
        
684
        if(isset($name)){
685
            $this->sortParameterName = $name . '[filter][sort]';
0 ignored issues
show
Bug Best Practice introduced by
The property sortParameterName does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
686
        }
687
        else{
688
            $this->sortParameterName = 'filter[sort]';
689
        }
690
        
691
        if(isset($filter['sort'])){
692
            $this->setSortField($filter['sort']);
693
        }
694
        elseif(! isset($this->sortField)){
695
            
696
            if(method_exists($this, 'getDefaultSortField')){
697
                $this->setSortField($this->getDefaultSortField());
698
            }
699
            else{
700
                $columns = $this->getVisibleColumns();
701
                $sortField = key($columns);
702
                $this->setSortField($sortField);
703
            }
704
        }
705
        
706
        $form = $this->getAdvancedFilterForm(null, $filter);
707
        
708
        if(isset($filter)){
709
            if(isset($name)){
710
                $path = array(
711
                    $name,
712
                    'filter'
713
                );
714
            }
715
            else{
716
                $path = array(
717
                    'filter'
718
                );
719
            }
720
            $form->setValues($filter, $path);
721
        }
722
        
723
        $filterPanel->setFilter($form);
724
        $filterPanel->setFiltered($this);
725
        
726
        return $filterPanel;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $filterPanel returns the type Widget_Filter which is incompatible with the documented return type Capwelton\Widgets\Widgets\Item\WidgetFilter.
Loading history...
727
    }
728
    
729
    /**
730
     * @param AppCtrlRecord $recordController
731
     * @return self
732
     */
733
    public function setRecordController(AppCtrlRecord $recordController)
734
    {
735
        $this->recordController = $recordController;
736
        return $this;
737
    }
738
    
739
    /**
740
     * @return AppCtrlRecord
741
     */
742
    public function getRecordController()
743
    {
744
        return $this->recordController;
745
    }
746
    
747
    /**
748
     * @return AppCtrlRecord
749
     */
750
    public function getRecordControllerProxy()
751
    {
752
        if(! isset($this->recordControllerProxy)){
753
            $this->recordControllerProxy = $this->getRecordController()->proxy();
754
        }
755
        return $this->recordControllerProxy;
756
    }
757
}
758
759
/**
760
 * @param string|ORMField $field
761
 * @param string|null $description
762
 *
763
 * @return WidgetTableModelViewColumn
764
 */
765
function app_TableModelViewColumn($field, $description = null)
766
{
767
    if(null === $field){
0 ignored issues
show
introduced by
The condition null === $field is always false.
Loading history...
768
        return null;
769
    }
770
    
771
    if(! isset($description) && $field instanceof ORMField){
772
        $App = $field->getParentSet()->App();
773
        $description = $App->translate($field->getDescription());
774
    }
775
    
776
    return new WidgetTableModelViewColumn($field, $description);
777
}