Completed
Pull Request — master (#94)
by
unknown
02:15
created

GridBuilder   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 296
Duplicated Lines 4.39 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

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