Completed
Pull Request — master (#124)
by De Cramer
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 0
CRAP Score 30

Importance

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