Container   F
last analyzed

Complexity

Total Complexity 60

Size/Duplication

Total Lines 409
Duplicated Lines 0 %

Coupling/Cohesion

Components 7
Dependencies 20

Test Coverage

Coverage 98.82%

Importance

Changes 0
Metric Value
wmc 60
lcom 7
cbo 20
dl 0
loc 409
ccs 84
cts 85
cp 0.9882
rs 3.6
c 0
b 0
f 0

30 Methods

Rating   Name   Duplication   Size   Complexity  
A getColumn() 0 6 2
A getFilter() 0 6 2
A getAction() 0 6 2
A getOperation() 0 4 1
A getExport() 0 4 1
A getButton() 0 6 2
A hasColumns() 0 12 5
A hasFilters() 0 12 5
A hasActions() 0 12 5
A hasOperation() 0 11 4
A hasExport() 0 11 4
A hasButtons() 0 11 4
A addColumnText() 0 4 1
A addColumnEmail() 0 4 1
A addColumnLink() 0 4 1
A addColumnDate() 0 4 1
A addColumnNumber() 0 4 1
A addFilterText() 0 4 1
A addFilterDate() 0 4 1
A addFilterDateRange() 0 4 1
A addFilterCheck() 0 4 1
A addFilterSelect() 0 4 1
A addFilterNumber() 0 4 1
A addFilterCustom() 0 4 1
A addActionHref() 0 4 1
A addActionEvent() 0 4 1
A setOperation() 0 4 1
A setExport() 0 4 1
A addButton() 0 4 1
A setEditableColumns() 0 16 6

How to fix   Complexity   

Complex Class

Complex classes like Container often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Container, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * This file is part of the Grido (https://github.com/o5/grido)
5
 *
6
 * Copyright (c) 2011 Petr Bugyík (http://petr.bugyik.cz)
7
 *
8
 * For the full copyright and license information, please view
9
 * the file license.md that was distributed with this source code.
10
 */
11
12
namespace Grido\Components;
13
14
use Grido\Grid;
15
use Grido\Helpers;
16
use Grido\Components\Actions\Action;
17
use Grido\Components\Columns\Column;
18
use Grido\Components\Filters\Filter;
19
use Grido\Components\Columns\Editable;
20
21
/**
22
 * Container of grid components.
23
 *
24
 * @package     Grido
25
 * @subpackage  Components
26
 * @author      Petr Bugyík
27
 *
28
 */
29
abstract class Container extends \Nette\Application\UI\Control
30 1
{
31
    /** @var bool */
32
    protected $hasColumns;
33
34
    /** @var bool */
35
    protected $hasFilters;
36
37
    /** @var bool */
38
    protected $hasActions;
39
40
    /** @var bool */
41
    protected $hasOperation;
42
43
    /** @var bool */
44
    protected $hasExport;
45
46
    /** @var bool */
47
    protected $hasButtons;
48 1
49
    /**
50
     * Returns column component.
51 1
     * @param string $name
52
     * @param bool $need
53
     * @return Editable
54
     */
55
    public function getColumn($name, $need = TRUE)
56
    {
57 1
        return $this->hasColumns()
58 1
            ? $this->getComponent(Column::ID)->getComponent(Helpers::formatColumnName($name), $need)
59 1
            : NULL;
60
    }
61
62
    /**
63
     * Returns filter component.
64
     * @param string $name
65
     * @param bool $need
66
     * @return Filter
67
     */
68
    public function getFilter($name, $need = TRUE)
69 1
    {
70 1
        return $this->hasFilters()
71 1
            ? $this->getComponent(Filter::ID)->getComponent(Helpers::formatColumnName($name), $need)
72 1
            : NULL;
73
    }
74
75
    /**
76
     * Returns action component.
77
     * @param string $name
78
     * @param bool $need
79
     * @return Action
80
     */
81
    public function getAction($name, $need = TRUE)
82 1
    {
83 1
        return $this->hasActions()
84 1
            ? $this->getComponent(Action::ID)->getComponent($name, $need)
85 1
            : NULL;
86
    }
87
88
    /**
89
     * Returns operations component.
90
     * @param bool $need
91
     * @return Operation
92
     */
93
    public function getOperation($need = TRUE)
94
    {
95 1
        return $this->getComponent(Operation::ID, $need);
96
    }
97
98
    /**
99
     * Returns export component.
100
     * @param bool $need
101
     * @return Export
102
     */
103
    public function getExport($need = TRUE)
104
    {
105 1
        return $this->getComponent(Export::ID, $need);
106
    }
107
108
    /**
109
     * Returns toolbar button component.
110
     * @param bool $need
111
     * @return Button
112
     */
113
    public function getButton($name, $need = TRUE)
114
    {
115 1
        return $this->hasButtons()
116 1
            ? $this->getComponent(Button::ID)->getComponent($name, $need)
117 1
            : NULL;
118
    }
119
120
    /**********************************************************************************************/
121
122
    /**
123
     * @param bool $useCache
124
     * @return bool
125
     * @internal
126
     */
127
    public function hasColumns($useCache = TRUE)
128
    {
129 1
        $hasColumns = $this->hasColumns;
130
131 1
        if ($hasColumns === NULL || $useCache === FALSE) {
132 1
            $container = $this->getComponent(Column::ID, FALSE);
133 1
            $hasColumns = $container && count($container->getComponents()) > 0;
134 1
            $this->hasColumns = $useCache ? $hasColumns : NULL;
135 1
        }
136
137 1
        return $hasColumns;
138
    }
139
140
    /**
141
     * @param bool $useCache
142
     * @return bool
143
     * @internal
144
     */
145
    public function hasFilters($useCache = TRUE)
146
    {
147 1
        $hasFilters = $this->hasFilters;
148
149 1
        if ($hasFilters === NULL || $useCache === FALSE) {
150 1
            $container = $this->getComponent(Filter::ID, FALSE);
151 1
            $hasFilters = $container && count($container->getComponents()) > 0;
152 1
            $this->hasFilters = $useCache ? $hasFilters : NULL;
153 1
        }
154
155 1
        return $hasFilters;
156
    }
157
158
    /**
159
     * @param bool $useCache
160
     * @return bool
161
     * @internal
162
     */
163
    public function hasActions($useCache = TRUE)
164
    {
165 1
        $hasActions = $this->hasActions;
166
167 1
        if ($hasActions === NULL || $useCache === FALSE) {
168 1
            $container = $this->getComponent(Action::ID, FALSE);
169 1
            $hasActions = $container && count($container->getComponents()) > 0;
170 1
            $this->hasActions = $useCache ? $hasActions : NULL;
171 1
        }
172
173 1
        return $hasActions;
174
    }
175
176
    /**
177
     * @param bool $useCache
178
     * @return bool
179
     * @internal
180
     */
181
    public function hasOperation($useCache = TRUE)
182
    {
183 1
        $hasOperation = $this->hasOperation;
184
185 1
        if ($hasOperation === NULL || $useCache === FALSE) {
186 1
            $hasOperation = (bool) $this->getComponent(Operation::ID, FALSE);
187 1
            $this->hasOperation = $useCache ? $hasOperation : NULL;
188 1
        }
189
190 1
        return $hasOperation;
191
    }
192
193
    /**
194
     * @param bool $useCache
195
     * @return bool
196
     * @internal
197
     */
198
    public function hasExport($useCache = TRUE)
199
    {
200 1
        $hasExport = $this->hasExport;
201
202 1
        if ($hasExport === NULL || $useCache === FALSE) {
203 1
            $hasExport = (bool) $this->getComponent(Export::ID, FALSE);
204 1
            $this->hasExport = $useCache ? $hasExport : NULL;
205 1
        }
206
207 1
        return $hasExport;
208
    }
209
210
    /**
211
     * @param bool $useCache
212
     * @return bool
213
     * @internal
214
     */
215
    public function hasButtons($useCache = TRUE)
216
    {
217 1
        $hasButtons = $this->hasButtons;
218
219 1
        if ($hasButtons === NULL || $useCache === FALSE) {
220 1
            $hasButtons = (bool) $this->getComponent(Button::ID, FALSE);
221 1
            $this->hasButtons = $useCache ? $hasButtons : NULL;
222 1
        }
223
224 1
        return $hasButtons;
225
    }
226
227
    /**********************************************************************************************/
228
229
    /**
230
     * @param string $name
231
     * @param string $label
232
     * @return Columns\Text
233
     */
234
    public function addColumnText($name, $label)
235
    {
236 1
        return new Columns\Text($this, $name, $label);
237
    }
238
239
    /**
240
     * @param string $name
241
     * @param string $label
242
     * @return Columns\Email
243
     */
244
    public function addColumnEmail($name, $label)
245
    {
246 1
        return new Columns\Email($this, $name, $label);
247
    }
248
249
    /**
250
     * @param string $name
251
     * @param string $label
252
     * @return Columns\Link
253
     */
254
    public function addColumnLink($name, $label)
255
    {
256 1
        return new Columns\Link($this, $name, $label);
257
    }
258
259
    /**
260
     * @param string $name
261
     * @param string $label
262
     * @param string $dateFormat
263
     * @return Columns\Date
264
     */
265
    public function addColumnDate($name, $label, $dateFormat = NULL)
266
    {
267 1
        return new Columns\Date($this, $name, $label, $dateFormat);
268
    }
269
270
    /**
271
     * @param string $name
272
     * @param string $label
273
     * @param int $decimals number of decimal points
274
     * @param string $decPoint separator for the decimal point
275
     * @param string $thousandsSep thousands separator
276
     * @return Columns\Number
277
     */
278
    public function addColumnNumber($name, $label, $decimals = NULL, $decPoint = NULL, $thousandsSep = NULL)
279
    {
280 1
        return new Columns\Number($this, $name, $label, $decimals, $decPoint, $thousandsSep);
281
    }
282
283
    /**********************************************************************************************/
284
285
    /**
286
     * @param string $name
287
     * @param string $label
288
     * @return Filters\Text
289
     */
290
    public function addFilterText($name, $label)
291
    {
292 1
        return new Filters\Text($this, $name, $label);
293
    }
294
295
    /**
296
     * @param string $name
297
     * @param string $label
298
     * @return Filters\Date
299
     */
300
    public function addFilterDate($name, $label)
301
    {
302 1
        return new Filters\Date($this, $name, $label);
303
    }
304
305
    /**
306
     * @param string $name
307
     * @param string $label
308
     * @return Filters\DateRange
309
     */
310
    public function addFilterDateRange($name, $label)
311
    {
312 1
        return new Filters\DateRange($this, $name, $label);
313
    }
314
315
    /**
316
     * @param string $name
317
     * @param string $label
318
     * @return Filters\Check
319
     */
320
    public function addFilterCheck($name, $label)
321
    {
322 1
        return new Filters\Check($this, $name, $label);
323
    }
324
325
    /**
326
     * @param string $name
327
     * @param string $label
328
     * @param array $items
329
     * @return Filters\Select
330
     */
331
    public function addFilterSelect($name, $label, array $items = NULL)
332
    {
333 1
        return new Filters\Select($this, $name, $label, $items);
334
    }
335
336
    /**
337
     * @param string $name
338
     * @param string $label
339
     * @return Filters\Number
340
     */
341
    public function addFilterNumber($name, $label)
342
    {
343 1
        return new Filters\Number($this, $name, $label);
344
    }
345
346
    /**
347
     * @param string $name
348
     * @param \Nette\Forms\IControl $formControl
349
     * @return Filters\Custom
350
     */
351
    public function addFilterCustom($name, \Nette\Forms\IControl $formControl)
352
    {
353 1
        return new Filters\Custom($this, $name, NULL, $formControl);
354
    }
355
356
    /**********************************************************************************************/
357
358
    /**
359
     * @param string $name
360
     * @param string $label
361
     * @param string $destination
362
     * @param array $arguments
363
     * @return Actions\Href
364
     */
365
    public function addActionHref($name, $label, $destination = NULL, array $arguments = [])
366
    {
367 1
        return new Actions\Href($this, $name, $label, $destination, $arguments);
368
    }
369
370
    /**
371
     * @param string $name
372
     * @param string $label
373
     * @param callback $onClick
374
     * @return Actions\Event
375
     */
376
    public function addActionEvent($name, $label, $onClick = NULL)
377
    {
378 1
        return new Actions\Event($this, $name, $label, $onClick);
379
    }
380
381
    /**********************************************************************************************/
382
383
    /**
384
     * @param array $operations
385
     * @param callback $onSubmit - callback after operation submit
386
     * @return Operation
387
     */
388
    public function setOperation(array $operations, $onSubmit)
389
    {
390 1
        return new Operation($this, $operations, $onSubmit);
391
    }
392
393
    /**
394
     * @param string $label of exporting file
395
     * @return Export
396
     */
397
    public function setExport($label = NULL)
398
    {
399 1
        return new Export($this, $label);
400
    }
401
402
403
    /**
404
     * @param string $name
405
     * @param string $label
406
     * @param string $destination - first param for method $presenter->link()
407
     * @param array $arguments - second param for method $presenter->link()
408
     * @return Button
409
     */
410
    public function addButton($name, $label = NULL, $destination = NULL, array $arguments = [])
411
    {
412 1
        return new Button($this, $name, $label, $destination, $arguments);
413
    }
414
415
    /**
416
     * Sets all columns as editable.
417
     * First parameter is optional and is for implementation of method for saving modified data.
418
     * @param callback $callback function($id, $newValue, $oldValue, Editable $column) {}
419
     * @return Grid
420
     */
421
    public function setEditableColumns($callback = NULL)
422
    {
423 1
        $this->onRender[] = function(Grid $grid) use ($callback) {
424 1
            if (!$grid->hasColumns()) {
425
                return;
426
            }
427
428 1
            foreach ($grid->getComponent(Column::ID)->getComponents() as $column) {
429 1
                if ($column instanceof Editable && !$column->isEditableDisabled() && !$column->editableCallback) {
430 1
                    $column->setEditable($callback);
431 1
                }
432 1
            }
433 1
        };
434
435 1
        return $this;
436
    }
437
}
438