Completed
Pull Request — master (#124)
by
unknown
02:38
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\Components\uiTooltip;
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 DataCollectionInterface */
40
    protected $dataCollection;
41
42
    /** @var ManialinkInterface */
43
    protected $manialink;
44
45
    /** @var ManialinkFactory */
46
    protected $manialinkFactory;
47
48
    /** @var AbstractColumn[] */
49
    protected $columns;
50
51
    /** @var  float */
52
    protected $totalWidthCoefficency = 0.;
53
54
    /** @var int */
55
    protected $currentPage = 1;
56
57
    /** @var string */
58
    protected $pageKey;
59
60
    /** @var string */
61
    protected $actionPreviousPage;
62
    /** @var string */
63
    protected $actionNextPage;
64
    /** @var string */
65
    protected $actionLastPage;
66
    /** @var string */
67
    protected $actionFirstPage;
68
69
    /** @var string[] */
70
    protected $temporaryActions = [];
71
72
    /** @var array */
73
    protected $temporaryEntries = [];
74
75
76
    /**
77
     * GridBuilder constructor.
78
     *
79
     * @param ActionFactory $actionFactory
80
     * @param LineFactory $lineFactory
81
     * @param LineFactory $titleLineFactory
82
     * @param PagerFactory $pagerFactory
83
     */
84 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...
85
        ActionFactory $actionFactory,
86
        LineFactory $lineFactory,
87
        LineFactory $titleLineFactory,
88
        PagerFactory $pagerFactory
89
    ) {
90 5
        $this->actionFactory = $actionFactory;
91 5
        $this->titleLineFactory = $titleLineFactory;
92 5
        $this->lineFactory = $lineFactory;
93 5
        $this->pagerFactory = $pagerFactory;
94
95 5
        $this->pageKey = "key_".spl_object_hash($this);
96 5
    }
97
98
    /**
99
     * Set the data collection.
100
     *
101
     * @param DataCollectionInterface $dataCollection
102
     *
103
     * @return $this
104
     */
105 5
    public function setDataCollection(DataCollectionInterface $dataCollection)
106
    {
107 5
        $this->dataCollection = $dataCollection;
108
109 5
        return $this;
110
    }
111
112
    /**
113
     * Set the manialink the content is generated for.
114
     *
115
     * @param ManialinkInterface $manialink
116
     *
117
     * @return $this
118
     */
119 5
    public function setManialink(ManialinkInterface $manialink)
120
    {
121 5
        $this->manialink = $manialink;
122
123 5
        $this->actionFirstPage = $this->actionFactory
124 5
            ->createManialinkAction($manialink, array($this, 'goToFirstPage'), []);
125 5
        $this->actionPreviousPage = $this->actionFactory
126 5
            ->createManialinkAction($manialink, array($this, 'goToPreviousPage'), []);
127 5
        $this->actionNextPage = $this->actionFactory
128 5
            ->createManialinkAction($manialink, array($this, 'goToNextPage'), []);
129 5
        $this->actionLastPage = $this->actionFactory
130 5
            ->createManialinkAction($manialink, array($this, 'goToLastPage'), []);
131
132 5
        return $this;
133
    }
134
135
    /**
136
     * Set the manialink factory responsible with the manialink.
137
     *
138
     * @param ManialinkFactory $manialinkFactory
139
     *
140
     * @return $this
141
     */
142 5
    public function setManialinkFactory($manialinkFactory)
143
    {
144 5
        $this->manialinkFactory = $manialinkFactory;
145
146 5
        return $this;
147
    }
148
149
    /**
150
     * @param      string $key
151
     * @param      string $name
152
     * @param      integer $widthCoefficiency
153
     * @param bool $sortable
154
     * @param bool $translatable
155
     *
156
     * @return $this
157
     */
158 5
    public function addTextColumn($key, $name, $widthCoefficiency, $sortable = false, $translatable = false)
159
    {
160 5
        $this->columns[] = new TextColumn($key, $name, $widthCoefficiency, $sortable, $translatable);
161
162 5
        return $this;
163
    }
164
165
    /**
166
     * @param      string $key
167
     * @param      string $name
168
     * @param      integer $widthCoefficiency
169
     * @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...
170
     * @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...
171
     *
172
     * @return $this
173
     */
174
    public function addInputColumn($key, $name, $widthCoefficiency)
175
    {
176
        $this->columns[] = new InputColumn($key, $name, $widthCoefficiency);
177
178
        return $this;
179
    }
180
181
182
    /**
183
     * Add an action into a column.
184
     *
185
     * @param string $key
186
     * @param string $name
187
     * @param integer $widthCoefficiency
188
     * @param $action
189
     * @param Renderable $renderer
190
     *
191
     * @return $this
192
     */
193 5
    public function addActionColumn($key, $name, $widthCoefficiency, $action, $renderer)
194
    {
195 5
        $this->columns[] = new ActionColumn($key, $name, $widthCoefficiency, $action, $renderer);
196
197 5
        return $this;
198
    }
199
200
    /**
201
     * Remove all columns.
202
     */
203 1
    public function resetColumns()
204
    {
205 1
        $this->columns = [];
206 1
        $this->totalWidthCoefficency = 0.;
207 1
    }
208
209
    /**
210
     * Build a grid.
211
     *
212
     * @param double $width
213
     * @param double $height
214
     *
215
     * @return Frame
216
     */
217 5
    public function build($width, $height)
218
    {
219 5
        foreach ($this->temporaryActions as $action) {
220 1
            $this->actionFactory->destroyAction($action);
221
        }
222
223 5
        $lineHeight = 5 + 0.5;
224
225
226 5
        $frame = new Frame();
227 5
        $frame->setPosition(0, 0);
228 5
        $frame->setSize($width, $height);
229
230 5
        $posY = 0.;
231 5
        $tooltip = new uiTooltip();
232 5
        $frame->addChild($tooltip);
233
234
        // Generating headers.
235
        // TODO if sortable create actions...
236 5
        $data = [];
237 5
        foreach ($this->columns as $columnData) {
238 5
            $data[] = [
239 5
                'text' => $columnData->getName(),
240 5
                'width' => $columnData->getWidthCoeficiency(),
241
                'translatable' => true,
242
            ];
243
        }
244
245 5
        $frame->addChild($this->titleLineFactory->create($frame->getWidth(), $data));
246 5
        $posY -= $lineHeight + 1;
247
248
        /*
249
         * Display the main content.
250
         */
251 5
        $this->dataCollection->setPageSize(floor(($frame->getHeight() + $posY - $lineHeight - 2) / $lineHeight));
252
253 5
        $lines = $this->dataCollection->getData($this->currentPage);
254 5
        $idx = 0;
255 5
        foreach ($lines as $i => $lineData) {
256 5
            $data = [];
257 5
            foreach ($this->columns as $columnData) {
258 5
                if ($columnData instanceof TextColumn) {
259
260 5
                    $data[] = [
261 5
                        'text' => $this->dataCollection->getLineData($lineData, $columnData->getKey()),
262 5
                        'width' => $columnData->getWidthCoeficiency(),
263 5
                        'translatable' => $columnData->getTranslatable(),
264
                    ];
265 5
                } elseif ($columnData instanceof ActionColumn) {
266 5
                    $action = $this->actionFactory
267 5
                        ->createManialinkAction($this->manialink, $columnData->getCallable(), $lineData);
268 5
                    $this->temporaryActions[] = $action;
269 5
                    $data[] = [
270 5
                        'renderer' => clone $columnData->getRenderer(),
271 5
                        'width' => $columnData->getWidthCoeficiency(),
272 5
                        'action' => $action,
273
                    ];
274
                } elseif ($columnData instanceof InputColumn) {
275
                    $value = $this->dataCollection->getLineData($lineData, $columnData->getKey());
276
277
                    $data[] = [
278
                        'input' => $value,
279
                        'index' => $i,
280
                        'tooltip' => $tooltip,
281 5
                        'width' => $columnData->getWidthCoeficiency(),
282
                    ];
283
                }
284
            }
285 5
            $line = $this->lineFactory->create($frame->getWidth(), $data, $idx++);
286 5
            $line->setPosition(0, $posY);
287 5
            $frame->addChild($line);
288 5
            $posY -= $lineHeight;
289
        }
290
291
        /*
292
         * Handle the pager.
293
         */
294 5
        $posY = ($frame->getHeight() - 7) * -1;
295 5
        $pager = $this->pagerFactory->create(
296 5
            $frame->getWidth(),
297 5
            $this->currentPage,
298 5
            $this->dataCollection->getLastPageNumber(),
299 5
            $this->actionFirstPage,
300 5
            $this->actionPreviousPage,
301 5
            $this->actionNextPage,
302 5
            $this->actionLastPage
303
        );
304 5
        $pager->setPosition(0, $posY);
305 5
        $frame->addChild($pager);
306
307 5
        return $frame;
308
    }
309
310
    /**
311
     * Action callback to go to the first page.
312
     */
313 1
    public function goToFirstPage($login = null, $entries = [])
314
    {
315 1
        $this->updateDataCollection($entries);
316 1
        $this->changePage(1);
317 1
    }
318
319
    /**
320
     * Action callback to go to the previous page.
321
     */
322 1
    public function goToPreviousPage($login = null, $entries = [])
323
    {
324 1
        $this->updateDataCollection($entries);
325 1
        if ($this->currentPage - 1 >= 1) {
326 1
            $this->changePage($this->currentPage - 1);
327
        }
328 1
    }
329
330
    /**
331
     * Action callback to go to the next page.
332
     */
333 3
    public function goToNextPage($login = null, $entries = [])
334
    {
335 3
        $this->updateDataCollection($entries);
336 3
        if ($this->currentPage + 1 <= $this->dataCollection->getLastPageNumber()) {
337 3
            $this->changePage($this->currentPage + 1);
338
        }
339 3
    }
340
341
    /**
342
     * Action callback to go to the last page.
343
     */
344 1
    public function goToLastPage($login = null, $entries = [])
345
    {
346 1
        $this->updateDataCollection($entries);
347 1
        $this->changePage($this->dataCollection->getLastPageNumber());
348 1
    }
349
350
    /**
351
     * Updates dataCollection from entries.
352
     */
353 4
    public function updateDataCollection($entries)
354
    {
355
356 4
        $data = [];
357 4
        $start = ($this->currentPage - 1) * $this->dataCollection->getPageSize();
358 4
        foreach ($entries as $key => $value) {
359
            $array = explode("_", str_replace("entry_", "", $key));
360
            setType($value, $array[1]);
361
            $data[$array[0]] = $value;
362
        }
363
364 4
        $lines = $this->dataCollection->getData($this->currentPage);
365 4
        foreach ($lines as $i => $lineData) {
366 4
            $newData = $lineData;
367 4
            foreach ($this->columns as $columnData) {
368 4
                if ($columnData instanceof InputColumn) {
369 4
                    $newData[$columnData->getKey()] = $data[$i];
370
                }
371
            }
372 4
            $this->dataCollection->setDataByIndex($start + $i, $newData);
373
        }
374 4
    }
375
376
    /** get dataCollection
377
     *
378
     * @return DataCollectionInterface
379
     */
380
    public function getDataCollection()
381
    {
382
        return $this->dataCollection;
383
    }
384
385
    /**
386
     * Handle page change & refresh user window.
387
     *
388
     * @param integer $page
389
     */
390 4
    protected function changePage($page)
391
    {
392 4
        $this->currentPage = $page;
393 4
        $this->manialinkFactory->update($this->manialink->getUserGroup());
394 4
    }
395
}
396