Completed
Push — dev ( 845ef5...8eacd8 )
by
unknown
02:50
created

GridBuilder   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 292
Duplicated Lines 4.45 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 10
dl 13
loc 292
ccs 101
cts 101
cp 1
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 13 13 1
A setDataCollection() 0 6 1
A setManialink() 0 15 1
A setManialinkFactory() 0 6 1
A addTextColumn() 0 6 1
A addActionColumn() 0 4 1
A resetColumns() 0 5 1
C build() 0 77 7
A goToFirstPage() 0 4 1
A goToPreviousPage() 0 6 2
A goToNextPage() 0 6 2
A goToLastPage() 0 4 1
A changePage() 0 5 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace eXpansion\Framework\Core\Model\Gui\Grid;
4
use eXpansion\Framework\Core\Model\Gui\Action;
5
use eXpansion\Framework\Core\Model\Gui\Factory\LineFactory;
6
use eXpansion\Framework\Core\Model\Gui\Factory\PagerFactory;
7
use eXpansion\Framework\Core\Model\Gui\Grid\Column\AbstractColumn;
8
use eXpansion\Framework\Core\Model\Gui\Grid\Column\ActionColumn;
9
use eXpansion\Framework\Core\Model\Gui\Grid\Column\TextColumn;
10
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
11
use eXpansion\Framework\Core\Plugins\Gui\ActionFactory;
12
use eXpansion\Framework\Core\Plugins\Gui\ManialinkFactory;
13
use FML\Controls\Frame;
14
15
16
/**
17
 * Class GridBuilder
18
 *
19
 * @TODO Add possibility to add actions on elements.
20
 *
21
 * @package eXpansion\Framework\Core\Model\Gui\Grid;
22
 * @author  oliver de Cramer <[email protected]>
23
 */
24
class GridBuilder
25
{
26
    /** @var  ActionFactory */
27
    protected $actionFactory;
28
29
    /** @var LineFactory */
30
    protected $titleLineFactory;
31
32
    /** @var LineFactory */
33
    protected $lineFactory;
34
35
    /** @var PagerFactory */
36
    protected $pagerFactory;
37
38
    /** @var DataCollectionInterface */
39
    protected $dataCollection;
40
41
    /** @var ManialinkInterface */
42
    protected $manialink;
43
44
    /** @var ManialinkFactory */
45
    protected $manialinkFactory;
46
47
    /** @var AbstractColumn[] */
48
    protected $columns;
49
50
    /** @var  float */
51
    protected $totalWidthCoefficency = 0;
52
53
    /** @var int */
54
    protected $currentPage = 1;
55
56
    /** @var string */
57
    protected $pageKey;
58
59
    /** @var Action */
60
    protected $actionPreviousPage;
61
    /** @var Action */
62
    protected $actionNextPage;
63
    /** @var Action */
64
    protected $actionLastPage;
65
    /** @var Action */
66
    protected $actionFirstPage;
67
68
    /** @var Action[] */
69
    protected $temporaryActions = [];
70
71
    /**
72
     * GridBuilder constructor.
73
     *
74
     * @param ActionFactory $actionFactory
75
     * @param LineFactory   $lineFactory
76
     * @param LineFactory   $titleLineFactory
77
     * @param PagerFactory  $pagerFactory
78
     */
79 5 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
80
        ActionFactory $actionFactory,
81
        LineFactory $lineFactory,
82
        LineFactory $titleLineFactory,
83
        PagerFactory $pagerFactory
84
    ) {
85 5
        $this->actionFactory = $actionFactory;
86 5
        $this->titleLineFactory = $titleLineFactory;
87 5
        $this->lineFactory = $lineFactory;
88 5
        $this->pagerFactory = $pagerFactory;
89
90 5
        $this->pageKey = spl_object_hash($this)."_key";
91 5
    }
92
93
    /**
94
     * Set the data collection.
95
     *
96
     * @param DataCollectionInterface $dataCollection
97
     *
98
     * @return $this
99
     */
100 5
    public function setDataCollection(DataCollectionInterface $dataCollection)
101
    {
102 5
        $this->dataCollection = $dataCollection;
103
104 5
        return $this;
105
    }
106
107
    /**
108
     * Set the manialink the content is generated for.
109
     *
110
     * @param ManialinkInterface $manialink
111
     *
112
     * @return $this
113
     */
114 5
    public function setManialink(ManialinkInterface $manialink)
115
    {
116 5
        $this->manialink = $manialink;
117
118 5
        $this->actionFirstPage = $this->actionFactory
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->actionFactory->cr...ToFirstPage'), array()) of type string is incompatible with the declared type object<eXpansion\Framework\Core\Model\Gui\Action> of property $actionFirstPage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
119 5
            ->createManialinkAction($manialink, array($this, 'goToFirstPage'), []);
120 5
        $this->actionPreviousPage = $this->actionFactory
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->actionFactory->cr...reviousPage'), array()) of type string is incompatible with the declared type object<eXpansion\Framework\Core\Model\Gui\Action> of property $actionPreviousPage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
121 5
            ->createManialinkAction($manialink, array($this, 'goToPreviousPage'), []);
122 5
        $this->actionNextPage = $this->actionFactory
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->actionFactory->cr...oToNextPage'), array()) of type string is incompatible with the declared type object<eXpansion\Framework\Core\Model\Gui\Action> of property $actionNextPage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
123 5
            ->createManialinkAction($manialink, array($this, 'goToNextPage'), []);
124 5
        $this->actionLastPage = $this->actionFactory
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->actionFactory->cr...oToLastPage'), array()) of type string is incompatible with the declared type object<eXpansion\Framework\Core\Model\Gui\Action> of property $actionLastPage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
125 5
            ->createManialinkAction($manialink, array($this, 'goToLastPage'), []);
126
127 5
        return $this;
128
    }
129
130
    /**
131
     * Set the manialink factory responsible with the manialink.
132
     *
133
     * @param ManialinkFactory $manialinkFactory
134
     *
135
     * @return $this
136
     */
137 5
    public function setManialinkFactory($manialinkFactory)
138
    {
139 5
        $this->manialinkFactory = $manialinkFactory;
140
141 5
        return $this;
142
    }
143
144
    /**
145
     * @param      string $key
146
     * @param      string $name
147
     * @param      integer $widthCoefficiency
148
     * @param bool $sortable
149
     * @param bool $translatable
150
     *
151
     * @return $this
152
     */
153 5
    public function addTextColumn($key, $name, $widthCoefficiency, $sortable = false, $translatable = false)
154
    {
155 5
        $this->columns[] = new TextColumn($key, $name, $widthCoefficiency, $sortable, $translatable);
156
157 5
        return $this;
158
    }
159
160
    /**
161
     * Add an action into a column.
162
     *
163
     * @param string $key
164
     * @param string $name
165
     * @param integer $widthCoefficiency
166
     * @param $action
167
     * @param Label $renderer
168
     */
169 5
    public function addActionColumn($key, $name, $widthCoefficiency, $action, $renderer)
170
    {
171 5
        $this->columns[] = new ActionColumn($key, $name, $widthCoefficiency, $action, $renderer);
172 5
    }
173
174
    /**
175
     * Remove all columns.
176
     */
177 1
    public function resetColumns()
178
    {
179 1
        $this->columns = [];
180 1
        $this->totalWidthCoefficency = 0;
0 ignored issues
show
Documentation Bug introduced by
The property $totalWidthCoefficency was declared of type double, but 0 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
181 1
    }
182
183
    /**
184
     * Build a grid.
185
     *
186
     * @param double $width
187
     * @param double $height
188
     *
189
     * @return Frame
190
     */
191 5
    public function build($width, $height)
192
    {
193 5
        foreach ($this->temporaryActions as $action) {
194 1
            $this->actionFactory->destroyAction($action);
195
        }
196
197 5
        $lineHeight = 5 + 0.5;
198
199 5
        $frame = new Frame();
200 5
        $frame->setPosition(0, 0);
201 5
        $frame->setSize($width, $height);
202
203 5
        $posY = 0;
204
        // Generating headers.
205
        // TODO if sortable create actions...
206 5
        $data = [];
207 5
        foreach ($this->columns as $columnData) {
208 5
            $data[] = [
209 5
                'text' => $columnData->getName(),
210 5
                'width' => $columnData->getWidthCoeficiency(),
211
                'translatable' => true
212
            ];
213
        }
214
215 5
        $frame->addChild($this->titleLineFactory->create($frame->getWidth(), $data));
216 5
        $posY -= $lineHeight + 1;
217
218
        /*
219
         * Display the main content.
220
         */
221 5
        $this->dataCollection->setPageSize(floor(($frame->getHeight() + $posY - $lineHeight - 2) / $lineHeight));
222
223 5
        $lines = $this->dataCollection->getData($this->currentPage);
224 5
        foreach ($lines as $i => $lineData) {
225 5
            $data = [];
226 5
            foreach ($this->columns as $columnData) {
227 5
                if ($columnData instanceof TextColumn) {
228 5
                    $data[] = [
229 5
                        'text' => $this->dataCollection->getLineData($lineData, $columnData->getKey()),
230 5
                        'width' => $columnData->getWidthCoeficiency(),
231 5
                        'translatable' => $columnData->getTranslatable()
232
                    ];
233 5
                } elseif ($columnData instanceof ActionColumn) {
234 5
                    $action = $this->actionFactory
235 5
                        ->createManialinkAction($this->manialink, $columnData->getCallable(), $lineData);
236 5
                    $this->temporaryActions[] = $action;
237 5
                    $data[] = [
238 5
                        'renderer' => clone $columnData->getRenderer(),
239 5
                        'width' => $columnData->getWidthCoeficiency(),
240 5
                        'action' => $action,
241
                    ];
242
                }
243
            }
244 5
            $line = $this->lineFactory->create($frame->getWidth(), $data, $i);
245 5
            $line->setPosition(0, $posY);
246 5
            $frame->addChild($line);
247 5
            $posY -= $lineHeight;
248
        }
249
250
        /*
251
         * Handle the pager.
252
         */
253 5
        $posY = ($frame->getHeight() - 7) * -1;
254 5
        $pager = $this->pagerFactory->create(
255 5
            $frame->getWidth(),
256 5
            $this->currentPage,
257 5
            $this->dataCollection->getLastPageNumber(),
258 5
            $this->actionFirstPage,
259 5
            $this->actionPreviousPage,
260 5
            $this->actionNextPage,
261 5
            $this->actionLastPage
262
        );
263 5
        $pager->setPosition(0, $posY);
264 5
        $frame->addChild($pager);
265
266 5
        return $frame;
267
    }
268
269
    /**
270
     * Action callback to go to the first page.
271
     */
272 1
    public function goToFirstPage()
273
    {
274 1
        $this->changePage(1);
275 1
    }
276
277
    /**
278
     * Action callback to go to the previous page.
279
     */
280 1
    public function goToPreviousPage()
281
    {
282 1
        if ($this->currentPage - 1 >= 1) {
283 1
            $this->changePage($this->currentPage - 1);
284
        }
285 1
    }
286
287
    /**
288
     * Action callback to go to the next page.
289
     */
290 3
    public function goToNextPage()
291
    {
292 3
        if ($this->currentPage + 1 <= $this->dataCollection->getLastPageNumber()) {
293 3
            $this->changePage($this->currentPage + 1);
294
        }
295 3
    }
296
297
    /**
298
     * Action callback to go to the last page.
299
     */
300 1
    public function goToLastPage()
301
    {
302 1
        $this->changePage($this->dataCollection->getLastPageNumber());
303 1
    }
304
305
    /**
306
     * Handle page change & refresh user window.
307
     *
308
     * @param integer $page
309
     */
310 4
    protected function changePage($page)
311
    {
312 4
        $this->currentPage = $page;
313 4
        $this->manialinkFactory->update($this->manialink->getUserGroup());
314
    }
315
}