Completed
Pull Request — master (#124)
by De Cramer
02:52
created

GridBuilder::resetColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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