Completed
Pull Request — master (#124)
by
unknown
02:35
created

GridBuilder::updateDataCollection()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.2

Importance

Changes 0
Metric Value
dl 0
loc 22
c 0
b 0
f 0
ccs 12
cts 15
cp 0.8
rs 8.6737
cc 5
eloc 14
nc 8
nop 1
crap 5.2
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\InputColumn;
10
use eXpansion\Framework\Core\Model\Gui\Grid\Column\TextColumn;
11
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
12
use eXpansion\Framework\Core\Plugins\Gui\ActionFactory;
13
use eXpansion\Framework\Core\Plugins\Gui\ManialinkFactory;
14
use eXpansion\Framework\Gui\Ui\Factory;
15
use FML\Controls\Frame;
16
use FML\Types\Renderable;
17
18
19
/**
20
 * Class GridBuilder
21
 *
22
 * @package eXpansion\Framework\Core\Model\Gui\Grid;
23
 * @author  oliver de Cramer <[email protected]>
24
 */
25
class GridBuilder
26
{
27
    /** @var  ActionFactory */
28
    protected $actionFactory;
29
30
    /** @var LineFactory */
31
    protected $titleLineFactory;
32
33
    /** @var LineFactory */
34
    protected $lineFactory;
35
36
    /** @var PagerFactory */
37
    protected $pagerFactory;
38
39
    /** @var Factory */
40
    protected $uiFactory;
41
42
    /** @var DataCollectionInterface */
43
    protected $dataCollection;
44
45
    /** @var ManialinkInterface */
46
    protected $manialink;
47
48
    /** @var ManialinkFactory */
49
    protected $manialinkFactory;
50
51
    /** @var AbstractColumn[] */
52
    protected $columns;
53
54
    /** @var  float */
55
    protected $totalWidthCoefficency = 0.;
56
57
    /** @var int */
58
    protected $currentPage = 1;
59
60
    /** @var string */
61
    protected $pageKey;
62
63
    /** @var string */
64
    protected $actionPreviousPage;
65
    /** @var string */
66
    protected $actionNextPage;
67
    /** @var string */
68
    protected $actionLastPage;
69
    /** @var string */
70
    protected $actionFirstPage;
71
72
    /** @var string[] */
73
    protected $temporaryActions = [];
74
75
    /** @var array */
76
    protected $temporaryEntries = [];
77
78
79
    /**
80
     * GridBuilder constructor.
81
     *
82
     * @param ActionFactory $actionFactory
83
     * @param LineFactory $lineFactory
84
     * @param LineFactory $titleLineFactory
85
     * @param PagerFactory $pagerFactory
86
     */
87 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...
88
        ActionFactory $actionFactory,
89
        LineFactory $lineFactory,
90
        LineFactory $titleLineFactory,
91
        PagerFactory $pagerFactory,
92
        Factory $uiFactory
93
    ) {
94 5
        $this->actionFactory = $actionFactory;
95 5
        $this->titleLineFactory = $titleLineFactory;
96 5
        $this->lineFactory = $lineFactory;
97 5
        $this->pagerFactory = $pagerFactory;
98 5
        $this->uiFactory = $uiFactory;
99
100 5
        $this->pageKey = "key_".spl_object_hash($this);
101 5
    }
102
103
    /**
104
     * Set the data collection.
105
     *
106
     * @param DataCollectionInterface $dataCollection
107
     *
108
     * @return $this
109
     */
110 5
    public function setDataCollection(DataCollectionInterface $dataCollection)
111
    {
112 5
        $this->dataCollection = $dataCollection;
113
114 5
        return $this;
115
    }
116
117
    /**
118
     * Set the manialink the content is generated for.
119
     *
120
     * @param ManialinkInterface $manialink
121
     *
122
     * @return $this
123
     */
124 5
    public function setManialink(ManialinkInterface $manialink)
125
    {
126 5
        $this->manialink = $manialink;
127
128 5
        $this->actionFirstPage = $this->actionFactory
129 5
            ->createManialinkAction($manialink, array($this, 'goToFirstPage'), []);
130 5
        $this->actionPreviousPage = $this->actionFactory
131 5
            ->createManialinkAction($manialink, array($this, 'goToPreviousPage'), []);
132 5
        $this->actionNextPage = $this->actionFactory
133 5
            ->createManialinkAction($manialink, array($this, 'goToNextPage'), []);
134 5
        $this->actionLastPage = $this->actionFactory
135 5
            ->createManialinkAction($manialink, array($this, 'goToLastPage'), []);
136
137 5
        return $this;
138
    }
139
140
    /**
141
     * Set the manialink factory responsible with the manialink.
142
     *
143
     * @param ManialinkFactory $manialinkFactory
144
     *
145
     * @return $this
146
     */
147 5
    public function setManialinkFactory($manialinkFactory)
148
    {
149 5
        $this->manialinkFactory = $manialinkFactory;
150
151 5
        return $this;
152
    }
153
154
    /**
155
     * @param      string $key
156
     * @param      string $name
157
     * @param      integer $widthCoefficiency
158
     * @param bool $sortable
159
     * @param bool $translatable
160
     *
161
     * @return $this
162
     */
163 5
    public function addTextColumn($key, $name, $widthCoefficiency, $sortable = false, $translatable = false)
164
    {
165 5
        $this->columns[] = new TextColumn($key, $name, $widthCoefficiency, $sortable, $translatable);
166
167 5
        return $this;
168
    }
169
170
    /**
171
     * @param      string $key
172
     * @param      string $name
173
     * @param      integer $widthCoefficiency
174
     * @param bool $sortable
0 ignored issues
show
Bug introduced by
There is no parameter named $sortable. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
175
     * @param bool $translatable
0 ignored issues
show
Bug introduced by
There is no parameter named $translatable. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
176
     *
177
     * @return $this
178
     */
179
    public function addInputColumn($key, $name, $widthCoefficiency)
180
    {
181
        $this->columns[] = new InputColumn($key, $name, $widthCoefficiency);
182
183
        return $this;
184
    }
185
186
187
    /**
188
     * Add an action into a column.
189
     *
190
     * @param string $key
191
     * @param string $name
192
     * @param integer $widthCoefficiency
193
     * @param $action
194
     * @param Renderable $renderer
195
     *
196
     * @return $this
197
     */
198 5
    public function addActionColumn($key, $name, $widthCoefficiency, $action, $renderer)
199
    {
200 5
        $this->columns[] = new ActionColumn($key, $name, $widthCoefficiency, $action, $renderer);
201
202 5
        return $this;
203
    }
204
205
    /**
206
     * Remove all columns.
207
     */
208 1
    public function resetColumns()
209
    {
210 1
        $this->columns = [];
211 1
        $this->totalWidthCoefficency = 0.;
212 1
    }
213
214
    /**
215
     * Build a grid.
216
     *
217
     * @param double $width
218
     * @param double $height
219
     *
220
     * @return Frame
221
     */
222 5
    public function build($width, $height)
223
    {
224 5
        foreach ($this->temporaryActions as $action) {
225 1
            $this->actionFactory->destroyAction($action);
226
        }
227
228 5
        $lineHeight = 5 + 0.5;
229
230
231 5
        $frame = new Frame();
232 5
        $frame->setPosition(0, 0);
233 5
        $frame->setSize($width, $height);
234
235 5
        $posY = 0.;
236 5
        $tooltip = $this->uiFactory->createTooltip();
237 5
        $frame->addChild($tooltip);
238
239
        // Generating headers.
240
        // TODO if sortable create actions...
241 5
        $data = [];
242 5
        foreach ($this->columns as $columnData) {
243 5
            $data[] = [
244 5
                'text' => $columnData->getName(),
245 5
                'width' => $columnData->getWidthCoeficiency(),
246
                'translatable' => true,
247
            ];
248
        }
249
250 5
        $frame->addChild($this->titleLineFactory->create($frame->getWidth(), $data));
251 5
        $posY -= $lineHeight + 1;
252
253
        /*
254
         * Display the main content.
255
         */
256 5
        $this->dataCollection->setPageSize(floor(($frame->getHeight() + $posY - $lineHeight - 2) / $lineHeight));
257
258 5
        $lines = $this->dataCollection->getData($this->currentPage);
259 5
        $idx = 0;
260 5
        foreach ($lines as $i => $lineData) {
261 5
            $data = [];
262 5
            foreach ($this->columns as $columnData) {
263 5
                if ($columnData instanceof TextColumn) {
264
265 5
                    $data[] = [
266 5
                        'text' => $this->dataCollection->getLineData($lineData, $columnData->getKey()),
267 5
                        'width' => $columnData->getWidthCoeficiency(),
268 5
                        'translatable' => $columnData->getTranslatable(),
269
                    ];
270 5
                } elseif ($columnData instanceof ActionColumn) {
271 5
                    $action = $this->actionFactory
272 5
                        ->createManialinkAction($this->manialink, $columnData->getCallable(), $lineData);
273 5
                    $this->temporaryActions[] = $action;
274 5
                    $data[] = [
275 5
                        'renderer' => clone $columnData->getRenderer(),
276 5
                        'width' => $columnData->getWidthCoeficiency(),
277 5
                        'action' => $action,
278
                    ];
279
                } elseif ($columnData instanceof InputColumn) {
280
                    $value = $this->dataCollection->getLineData($lineData, $columnData->getKey());
281
282
                    $data[] = [
283
                        'input' => $value,
284
                        'index' => $i,
285
                        'tooltip' => $tooltip,
286 5
                        'width' => $columnData->getWidthCoeficiency(),
287
                    ];
288
                }
289
            }
290 5
            $line = $this->lineFactory->create($frame->getWidth(), $data, $idx++);
291 5
            $line->setPosition(0, $posY);
292 5
            $frame->addChild($line);
293 5
            $posY -= $lineHeight;
294
        }
295
296
        /*
297
         * Handle the pager.
298
         */
299 5
        $posY = ($frame->getHeight() - 7) * -1;
300 5
        $pager = $this->pagerFactory->create(
301 5
            $frame->getWidth(),
302 5
            $this->currentPage,
303 5
            $this->dataCollection->getLastPageNumber(),
304 5
            $this->actionFirstPage,
305 5
            $this->actionPreviousPage,
306 5
            $this->actionNextPage,
307 5
            $this->actionLastPage
308
        );
309 5
        $pager->setPosition(0, $posY);
310 5
        $frame->addChild($pager);
311
312 5
        return $frame;
313
    }
314
315
    /**
316
     * Action callback to go to the first page.
317
     */
318 1
    public function goToFirstPage($login = null, $entries = [])
319
    {
320 1
        $this->updateDataCollection($entries);
321 1
        $this->changePage(1);
322 1
    }
323
324
    /**
325
     * Action callback to go to the previous page.
326
     */
327 1
    public function goToPreviousPage($login = null, $entries = [])
328
    {
329 1
        $this->updateDataCollection($entries);
330 1
        if ($this->currentPage - 1 >= 1) {
331 1
            $this->changePage($this->currentPage - 1);
332
        }
333 1
    }
334
335
    /**
336
     * Action callback to go to the next page.
337
     */
338 3
    public function goToNextPage($login = null, $entries = [])
339
    {
340 3
        $this->updateDataCollection($entries);
341 3
        if ($this->currentPage + 1 <= $this->dataCollection->getLastPageNumber()) {
342 3
            $this->changePage($this->currentPage + 1);
343
        }
344 3
    }
345
346
    /**
347
     * Action callback to go to the last page.
348
     */
349 1
    public function goToLastPage($login = null, $entries = [])
350
    {
351 1
        $this->updateDataCollection($entries);
352 1
        $this->changePage($this->dataCollection->getLastPageNumber());
353 1
    }
354
355
    /**
356
     * Updates dataCollection from entries.
357
     */
358 4
    public function updateDataCollection($entries)
359
    {
360
361 4
        $data = [];
362 4
        $start = ($this->currentPage - 1) * $this->dataCollection->getPageSize();
363 4
        foreach ($entries as $key => $value) {
364
            $array = explode("_", str_replace("entry_", "", $key));
365
            setType($value, $array[1]);
366
            $data[$array[0]] = $value;
367
        }
368
369 4
        $lines = $this->dataCollection->getData($this->currentPage);
370 4
        foreach ($lines as $i => $lineData) {
371 4
            $newData = $lineData;
372 4
            foreach ($this->columns as $columnData) {
373 4
                if ($columnData instanceof InputColumn) {
374 4
                    $newData[$columnData->getKey()] = $data[$i];
375
                }
376
            }
377 4
            $this->dataCollection->setDataByIndex($start + $i, $newData);
378
        }
379 4
    }
380
381
    /** get dataCollection
382
     *
383
     * @return DataCollectionInterface
384
     */
385
    public function getDataCollection()
386
    {
387
        return $this->dataCollection;
388
    }
389
390
    /**
391
     * Handle page change & refresh user window.
392
     *
393
     * @param integer $page
394
     */
395 4
    protected function changePage($page)
396
    {
397 4
        $this->currentPage = $page;
398 4
        $this->manialinkFactory->update($this->manialink->getUserGroup());
399 4
    }
400
}
401