Completed
Push — master ( 392108...56fa54 )
by Petr
11:09
created

Operation   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 87.88%

Importance

Changes 9
Bugs 1 Features 3
Metric Value
wmc 17
c 9
b 1
f 3
lcom 1
cbo 9
dl 0
loc 145
ccs 58
cts 66
cp 0.8788
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 18 1
A setConfirm() 0 9 1
A setPrimaryKey() 0 5 1
A getPrimaryKey() 0 8 2
C handleOperations() 0 37 8
A addCheckers() 0 20 4
1
<?php
2
3
/**
4
 * This file is part of the Grido (http://grido.bugyik.cz)
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\Exception;
17
18
/**
19
 * Operation with one or more rows.
20
 *
21
 * @package     Grido
22
 * @subpackage  Components
23
 * @author      Petr Bugyík
24
 *
25
 * @property-read string $primaryKey
26
 * @method void onSubmit(string $operation, array $ids) Description
27
 */
28
class Operation extends Component
29 1
{
30
    const ID = 'operations';
31
32
    /** @var array callback on operation submit */
33
    public $onSubmit;
34
35
    /** @var string */
36
    protected $primaryKey;
37
38
    /**
39
     * @param \Grido\Grid $grid
40
     * @param array $operations
41
     * @param callback $onSubmit - callback after operation submit
42
     */
43
    public function __construct($grid, array $operations, $onSubmit)
44
    {
45 1
        $this->grid = $grid;
46 1
        $grid->addComponent($this, self::ID);
47
48 1
        $grid['form'][$grid::BUTTONS]->addSubmit(self::ID, 'OK')
49 1
            ->onClick[] = [$this, 'handleOperations'];
50
51 1
        $grid['form']->addContainer(self::ID)
52 1
            ->addSelect(self::ID, 'Selected', $operations)
53 1
            ->setPrompt('Grido.Selected');
54
55 1
        $grid->onRender[] = function(Grid $grid) {
56 1
            $this->addCheckers($grid['form'][Operation::ID]);
57 1
        };
58
59 1
        $this->onSubmit[] = $onSubmit;
60 1
    }
61
62
    /**
63
     * Sets client side confirm for operation.
64
     * @param string $operation
65
     * @param string $message
66
     * @return Operation
67
     */
68
    public function setConfirm($operation, $message)
69
    {
70 1
        $message = $this->translate($message);
71 1
        $this->grid->onRender[] = function(Grid $grid) use ($operation, $message) {
72 1
            $grid['form'][Operation::ID][Operation::ID]->controlPrototype->data["grido-confirm-$operation"] = $message;
73 1
        };
74
75 1
        return $this;
76
    }
77
78
    /**
79
     * Sets primary key.
80
     * @param string $primaryKey
81
     * @return Operation
82
     */
83
    public function setPrimaryKey($primaryKey)
84
    {
85 1
        $this->primaryKey = $primaryKey;
86 1
        return $this;
87
    }
88
89
    /**********************************************************************************************/
90
91
    /**
92
     * @return string
93
     */
94
    public function getPrimaryKey()
95
    {
96 1
        if ($this->primaryKey === NULL) {
97 1
            $this->primaryKey = $this->grid->primaryKey;
98 1
        }
99
100 1
        return $this->primaryKey;
101
    }
102
103
    /**********************************************************************************************/
104
105
    /**
106
     * @param \Nette\Forms\Controls\SubmitButton $button
107
     * @internal
108
     */
109
    public function handleOperations(\Nette\Forms\Controls\SubmitButton $button)
110
    {
111 1
        $grid = $this->getGrid();
112 1
        !empty($grid->onRegistered) && $grid->onRegistered($grid);
113 1
        $form = $button->getForm();
114 1
        $this->addCheckers($form[self::ID]);
115
116 1
        $values = $form[self::ID]->values;
117 1
        if (empty($values[self::ID])) {
118 1
            $httpData = $form->getHttpData();
119 1
            if (!empty($httpData[self::ID][self::ID]) && $operation = $httpData[self::ID][self::ID]) {
120 1
                $grid->__triggerUserNotice("Operation with name '$operation' does not exist.");
121 1
            }
122
123 1
            $grid->reload();
124
        }
125
126 1
        $ids = [];
127 1
        $operation = $values[self::ID];
128 1
        unset($values[self::ID]);
129
130 1
        foreach ($values as $key => $val) {
131 1
            if ($val) {
132 1
                $ids[] = $key;
133 1
            }
134 1
        }
135
136 1
        $this->onSubmit($operation, $ids);
137 1
        $grid->page = 1;
138
139 1
        if ($this->presenter->isAjax()) {
140
            $grid['form'][self::ID][self::ID]->setValue(NULL);
141
            $grid->getData(TRUE, FALSE);
142
        }
143
144 1
        $grid->reload();
145
    }
146
147
    /**
148
     * @param \Nette\Forms\Container $container
149
     * @throws Exception
150
     * @internal
151
     */
152
    public function addCheckers(\Nette\Forms\Container $container)
153
    {
154 1
        $items = $this->grid->getData();
155 1
        $primaryKey = $this->getPrimaryKey();
156
157 1
        foreach ($items as $item) {
0 ignored issues
show
Bug introduced by
The expression $items of type array|object<Grido\DataS...tabase\Table\Selection> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
158
            try {
159 1
                $primaryValue = $this->grid->getProperty($item, $primaryKey);
160 1
                if (!isset($container[$primaryValue])) {
161 1
                    $container->addCheckbox(Helpers::formatColumnName($primaryValue))
162 1
                        ->controlPrototype->title = $primaryValue;
163 1
                }
164 1
            } catch (\Exception $e) {
165
                throw new Exception(
166
                    'You should define some else primary key via $grid->setPrimaryKey() '.
167
                    "because currently defined '$primaryKey' key is not suitable for operation feature."
168
                );
169
            }
170 1
        }
171 1
    }
172
}
173