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

GridBuilder::build()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 78
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 7.0003

Importance

Changes 0
Metric Value
dl 0
loc 78
rs 6.5702
c 0
b 0
f 0
ccs 49
cts 50
cp 0.98
cc 7
eloc 51
nc 20
nop 2
crap 7.0003

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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