Completed
Pull Request — master (#104)
by
unknown
03:28
created

GridBuilder   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 297
Duplicated Lines 4.38 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 99.02%

Importance

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

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 6 1
A resetColumns() 0 5 1
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
C build() 0 78 7

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
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
use FML\Controls\Label;
15
use FML\Types\Renderable;
16
17
18
/**
19
 * Class GridBuilder
20
 *
21
 * @TODO Add possibility to add actions on elements.
22
 *
23
 * @package eXpansion\Framework\Core\Model\Gui\Grid;
24
 * @author  oliver de Cramer <[email protected]>
25
 */
26
class GridBuilder
27
{
28
    /** @var  ActionFactory */
29
    protected $actionFactory;
30
31
    /** @var LineFactory */
32
    protected $titleLineFactory;
33
34
    /** @var LineFactory */
35
    protected $lineFactory;
36
37
    /** @var PagerFactory */
38
    protected $pagerFactory;
39
40
    /** @var DataCollectionInterface */
41
    protected $dataCollection;
42
43
    /** @var ManialinkInterface */
44
    protected $manialink;
45
46
    /** @var ManialinkFactory */
47
    protected $manialinkFactory;
48
49
    /** @var AbstractColumn[] */
50
    protected $columns;
51
52
    /** @var  float */
53
    protected $totalWidthCoefficency = 0.;
54
55
    /** @var int */
56
    protected $currentPage = 1;
57
58
    /** @var string */
59
    protected $pageKey;
60
61
    /** @var string */
62
    protected $actionPreviousPage;
63
    /** @var string */
64
    protected $actionNextPage;
65
    /** @var string */
66
    protected $actionLastPage;
67
    /** @var string */
68
    protected $actionFirstPage;
69
70
    /** @var string[] */
71
    protected $temporaryActions = [];
72
73
    /**
74
     * GridBuilder constructor.
75
     *
76
     * @param ActionFactory $actionFactory
77
     * @param LineFactory $lineFactory
78
     * @param LineFactory $titleLineFactory
79
     * @param PagerFactory $pagerFactory
80
     */
81 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...
82
        ActionFactory $actionFactory,
83
        LineFactory $lineFactory,
84
        LineFactory $titleLineFactory,
85
        PagerFactory $pagerFactory
86
    ) {
87 5
        $this->actionFactory = $actionFactory;
88 5
        $this->titleLineFactory = $titleLineFactory;
89 5
        $this->lineFactory = $lineFactory;
90 5
        $this->pagerFactory = $pagerFactory;
91
92 5
        $this->pageKey = "key_".spl_object_hash($this);
93 5
    }
94
95
    /**
96
     * Set the data collection.
97
     *
98
     * @param DataCollectionInterface $dataCollection
99
     *
100
     * @return $this
101
     */
102 5
    public function setDataCollection(DataCollectionInterface $dataCollection)
103
    {
104 5
        $this->dataCollection = $dataCollection;
105
106 5
        return $this;
107
    }
108
109
    /**
110
     * Set the manialink the content is generated for.
111
     *
112
     * @param ManialinkInterface $manialink
113
     *
114
     * @return $this
115
     */
116 5
    public function setManialink(ManialinkInterface $manialink)
117
    {
118 5
        $this->manialink = $manialink;
119
120 5
        $this->actionFirstPage = $this->actionFactory
121 5
            ->createManialinkAction($manialink, array($this, 'goToFirstPage'), []);
122 5
        $this->actionPreviousPage = $this->actionFactory
123 5
            ->createManialinkAction($manialink, array($this, 'goToPreviousPage'), []);
124 5
        $this->actionNextPage = $this->actionFactory
125 5
            ->createManialinkAction($manialink, array($this, 'goToNextPage'), []);
126 5
        $this->actionLastPage = $this->actionFactory
127 5
            ->createManialinkAction($manialink, array($this, 'goToLastPage'), []);
128
129 5
        return $this;
130
    }
131
132
    /**
133
     * Set the manialink factory responsible with the manialink.
134
     *
135
     * @param ManialinkFactory $manialinkFactory
136
     *
137
     * @return $this
138
     */
139 5
    public function setManialinkFactory($manialinkFactory)
140
    {
141 5
        $this->manialinkFactory = $manialinkFactory;
142
143 5
        return $this;
144
    }
145
146
    /**
147
     * @param      string $key
148
     * @param      string $name
149
     * @param      integer $widthCoefficiency
150
     * @param bool $sortable
151
     * @param bool $translatable
152
     *
153
     * @return $this
154
     */
155 5
    public function addTextColumn($key, $name, $widthCoefficiency, $sortable = false, $translatable = false)
156
    {
157 5
        $this->columns[] = new TextColumn($key, $name, $widthCoefficiency, $sortable, $translatable);
158
159 5
        return $this;
160
    }
161
162
    /**
163
     * Add an action into a column.
164
     *
165
     * @param string $key
166
     * @param string $name
167
     * @param integer $widthCoefficiency
168
     * @param $action
169
     * @param Renderable $renderer
170
     *
171
     * @return $this
172
     */
173 5
    public function addActionColumn($key, $name, $widthCoefficiency, $action, $renderer)
174
    {
175 5
        $this->columns[] = new ActionColumn($key, $name, $widthCoefficiency, $action, $renderer);
176
177 5
        return $this;
178
    }
179
180
    /**
181
     * Remove all columns.
182
     */
183 1
    public function resetColumns()
184
    {
185 1
        $this->columns = [];
186 1
        $this->totalWidthCoefficency = 0.;
187 1
    }
188
189
    /**
190
     * Build a grid.
191
     *
192
     * @param double $width
193
     * @param double $height
194
     *
195
     * @return Frame
196
     */
197 5
    public function build($width, $height)
198
    {
199 5
        foreach ($this->temporaryActions as $action) {
200 1
            $this->actionFactory->destroyAction($action);
201
        }
202
203 5
        $lineHeight = 5 + 0.5;
204
205 5
        $frame = new Frame();
206 5
        $frame->setPosition(0, 0);
207 5
        $frame->setSize($width, $height);
208
209 5
        $posY = 0.;
210
        // Generating headers.
211
        // TODO if sortable create actions...
212 5
        $data = [];
213 5
        foreach ($this->columns as $columnData) {
214 5
            $data[] = [
215 5
                'text' => $columnData->getName(),
216 5
                'width' => $columnData->getWidthCoeficiency(),
217
                'translatable' => true
218
            ];
219
        }
220
221 5
        $frame->addChild($this->titleLineFactory->create($frame->getWidth(), $data));
222 5
        $posY -= $lineHeight + 1;
223
224
        /*
225
         * Display the main content.
226
         */
227 5
        $this->dataCollection->setPageSize(floor(($frame->getHeight() + $posY - $lineHeight - 2) / $lineHeight));
228
229 5
        $lines = $this->dataCollection->getData($this->currentPage);
230 5
        $idx = 0;
231 5
        foreach ($lines as $i => $lineData) {
232 5
            $data = [];
233 5
            foreach ($this->columns as $columnData) {
234 5
                if ($columnData instanceof TextColumn) {
235 5
                    $data[] = [
236 5
                        'text' => $this->dataCollection->getLineData($lineData, $columnData->getKey()),
237 5
                        'width' => $columnData->getWidthCoeficiency(),
238 5
                        'translatable' => $columnData->getTranslatable(),
239
                    ];
240
                } elseif ($columnData instanceof ActionColumn) {
241 5
                    $action = $this->actionFactory
242 5
                        ->createManialinkAction($this->manialink, $columnData->getCallable(), $lineData);
243 5
                    $this->temporaryActions[] = $action;
244 5
                    $data[] = [
245 5
                        'renderer' => clone $columnData->getRenderer(),
246 5
                        'width' => $columnData->getWidthCoeficiency(),
247 5
                        'action' => $action,
248
                    ];
249
                }
250
            }
251 5
            $line = $this->lineFactory->create($frame->getWidth(), $data, $idx++);
252 5
            $line->setPosition(0, $posY);
253 5
            $frame->addChild($line);
254 5
            $posY -= $lineHeight;
255
        }
256
257
        /*
258
         * Handle the pager.
259
         */
260 5
        $posY = ($frame->getHeight() - 7) * -1;
261 5
        $pager = $this->pagerFactory->create(
262 5
            $frame->getWidth(),
263 5
            $this->currentPage,
264 5
            $this->dataCollection->getLastPageNumber(),
265 5
            $this->actionFirstPage,
266 5
            $this->actionPreviousPage,
267 5
            $this->actionNextPage,
268 5
            $this->actionLastPage
269
        );
270 5
        $pager->setPosition(0, $posY);
271 5
        $frame->addChild($pager);
272
273 5
        return $frame;
274
    }
275
276
    /**
277
     * Action callback to go to the first page.
278
     */
279 1
    public function goToFirstPage()
280
    {
281 1
        $this->changePage(1);
282 1
    }
283
284
    /**
285
     * Action callback to go to the previous page.
286
     */
287 1
    public function goToPreviousPage()
288
    {
289 1
        if ($this->currentPage - 1 >= 1) {
290 1
            $this->changePage($this->currentPage - 1);
291
        }
292 1
    }
293
294
    /**
295
     * Action callback to go to the next page.
296
     */
297 3
    public function goToNextPage()
298
    {
299 3
        if ($this->currentPage + 1 <= $this->dataCollection->getLastPageNumber()) {
300 3
            $this->changePage($this->currentPage + 1);
301
        }
302 3
    }
303
304
    /**
305
     * Action callback to go to the last page.
306
     */
307 1
    public function goToLastPage()
308
    {
309 1
        $this->changePage($this->dataCollection->getLastPageNumber());
310 1
    }
311
312
    /**
313
     * Handle page change & refresh user window.
314
     *
315
     * @param integer $page
316
     */
317 4
    protected function changePage($page)
318
    {
319 4
        $this->currentPage = $page;
320 4
        $this->manialinkFactory->update($this->manialink->getUserGroup());
321 4
    }
322
}
323