Completed
Pull Request — master (#95)
by
unknown
05:41
created

GridBuilder::build()   C

Complexity

Conditions 7
Paths 20

Size

Total Lines 78
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 7

Importance

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

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
use eXpansion\Framework\Core\Model\Gui\Action;
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
15
16
/**
17
 * Class GridBuilder
18
 *
19
 * @TODO Add possibility to add actions on elements.
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 DataCollectionInterface */
39
    protected $dataCollection;
40
41
    /** @var ManialinkInterface */
42
    protected $manialink;
43
44
    /** @var ManialinkFactory */
45
    protected $manialinkFactory;
46
47
    /** @var AbstractColumn[] */
48
    protected $columns;
49
50
    /** @var  float */
51
    protected $totalWidthCoefficency = 0.;
52
53
    /** @var int */
54
    protected $currentPage = 1;
55
56
    /** @var string */
57
    protected $pageKey;
58
59
    /** @var string */
60
    protected $actionPreviousPage;
61
    /** @var string */
62
    protected $actionNextPage;
63
    /** @var string */
64
    protected $actionLastPage;
65
    /** @var string */
66
    protected $actionFirstPage;
67
68
    /** @var string[] */
69
    protected $temporaryActions = [];
70
71
    /**
72
     * GridBuilder constructor.
73
     *
74
     * @param ActionFactory $actionFactory
75
     * @param LineFactory   $lineFactory
76
     * @param LineFactory   $titleLineFactory
77
     * @param PagerFactory  $pagerFactory
78
     */
79 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...
80
        ActionFactory $actionFactory,
81
        LineFactory $lineFactory,
82
        LineFactory $titleLineFactory,
83
        PagerFactory $pagerFactory
84
    ) {
85 5
        $this->actionFactory = $actionFactory;
86 5
        $this->titleLineFactory = $titleLineFactory;
87 5
        $this->lineFactory = $lineFactory;
88 5
        $this->pagerFactory = $pagerFactory;
89
90 5
        $this->pageKey = spl_object_hash($this)."_key";
91 5
    }
92
93
    /**
94
     * Set the data collection.
95
     *
96
     * @param DataCollectionInterface $dataCollection
97
     *
98
     * @return $this
99
     */
100 5
    public function setDataCollection(DataCollectionInterface $dataCollection)
101
    {
102 5
        $this->dataCollection = $dataCollection;
103
104 5
        return $this;
105
    }
106
107
    /**
108
     * Set the manialink the content is generated for.
109
     *
110
     * @param ManialinkInterface $manialink
111
     *
112
     * @return $this
113
     */
114 5
    public function setManialink(ManialinkInterface $manialink)
115
    {
116 5
        $this->manialink = $manialink;
117
118 5
        $this->actionFirstPage = $this->actionFactory
119 5
            ->createManialinkAction($manialink, array($this, 'goToFirstPage'), []);
120 5
        $this->actionPreviousPage = $this->actionFactory
121 5
            ->createManialinkAction($manialink, array($this, 'goToPreviousPage'), []);
122 5
        $this->actionNextPage = $this->actionFactory
123 5
            ->createManialinkAction($manialink, array($this, 'goToNextPage'), []);
124 5
        $this->actionLastPage = $this->actionFactory
125 5
            ->createManialinkAction($manialink, array($this, 'goToLastPage'), []);
126
127 5
        return $this;
128
    }
129
130
    /**
131
     * Set the manialink factory responsible with the manialink.
132
     *
133
     * @param ManialinkFactory $manialinkFactory
134
     *
135
     * @return $this
136
     */
137 5
    public function setManialinkFactory($manialinkFactory)
138
    {
139 5
        $this->manialinkFactory = $manialinkFactory;
140
141 5
        return $this;
142
    }
143
144
    /**
145
     * @param      string $key
146
     * @param      string $name
147
     * @param      integer $widthCoefficiency
148
     * @param bool $sortable
149
     * @param bool $translatable
150
     *
151
     * @return $this
152
     */
153 5
    public function addTextColumn($key, $name, $widthCoefficiency, $sortable = false, $translatable = false)
154
    {
155 5
        $this->columns[] = new TextColumn($key, $name, $widthCoefficiency, $sortable, $translatable);
156
157 5
        return $this;
158
    }
159
160
    /**
161
     * Add an action into a column.
162
     *
163
     * @param string $key
164
     * @param string $name
165
     * @param integer $widthCoefficiency
166
     * @param $action
167
     * @param Label $renderer
168
     *
169
     * @return $this
170
     */
171 5
    public function addActionColumn($key, $name, $widthCoefficiency, $action, $renderer)
172
    {
173 5
        $this->columns[] = new ActionColumn($key, $name, $widthCoefficiency, $action, $renderer);
174
175 5
        return $this;
176
    }
177
178
    /**
179
     * Remove all columns.
180
     */
181 1
    public function resetColumns()
182
    {
183 1
        $this->columns = [];
184 1
        $this->totalWidthCoefficency = 0.;
185 1
    }
186
187
    /**
188
     * Build a grid.
189
     *
190
     * @param double $width
191
     * @param double $height
192
     *
193
     * @return Frame
194
     */
195 5
    public function build($width, $height)
196
    {
197 5
        foreach ($this->temporaryActions as $action) {
198 1
            $this->actionFactory->destroyAction($action);
199
        }
200
201 5
        $lineHeight = 5 + 0.5;
202
203 5
        $frame = new Frame();
204 5
        $frame->setPosition(0, 0);
205 5
        $frame->setSize($width, $height);
206
207 5
        $posY = 0.;
208
        // Generating headers.
209
        // TODO if sortable create actions...
210 5
        $data = [];
211 5
        foreach ($this->columns as $columnData) {
212 5
            $data[] = [
213 5
                'text' => $columnData->getName(),
214 5
                'width' => $columnData->getWidthCoeficiency(),
215
                'translatable' => true
216
            ];
217
        }
218
219 5
        $frame->addChild($this->titleLineFactory->create($frame->getWidth(), $data));
220 5
        $posY -= $lineHeight + 1;
221
222
        /*
223
         * Display the main content.
224
         */
225 5
        $this->dataCollection->setPageSize(floor(($frame->getHeight() + $posY - $lineHeight - 2) / $lineHeight));
226
227 5
        $lines = $this->dataCollection->getData($this->currentPage);
228 5
        $idx = 0;
229 5
        foreach ($lines as $i => $lineData) {
230 5
            $data = [];
231 5
            foreach ($this->columns as $columnData) {
232 5
                if ($columnData instanceof TextColumn) {
233 5
                    $data[] = [
234 5
                        'text' => $this->dataCollection->getLineData($lineData, $columnData->getKey()),
235 5
                        'width' => $columnData->getWidthCoeficiency(),
236 5
                        'translatable' => $columnData->getTranslatable()
237
                    ];
238 5
                } elseif ($columnData instanceof ActionColumn) {
239 5
                    $action = $this->actionFactory
240 5
                        ->createManialinkAction($this->manialink, $columnData->getCallable(), $lineData);
241 5
                    $this->temporaryActions[] = $action;
242 5
                    $data[] = [
243 5
                        'renderer' => clone $columnData->getRenderer(),
244 5
                        'width' => $columnData->getWidthCoeficiency(),
245 5
                        'action' => $action,
246
                    ];
247
                }
248
            }
249 5
            $line = $this->lineFactory->create($frame->getWidth(), $data, $idx++);
250 5
            $line->setPosition(0, $posY);
251 5
            $frame->addChild($line);
252 5
            $posY -= $lineHeight;
253
        }
254
255
        /*
256
         * Handle the pager.
257
         */
258 5
        $posY = ($frame->getHeight() - 7) * -1;
259 5
        $pager = $this->pagerFactory->create(
260 5
            $frame->getWidth(),
261 5
            $this->currentPage,
262 5
            $this->dataCollection->getLastPageNumber(),
263 5
            $this->actionFirstPage,
264 5
            $this->actionPreviousPage,
265 5
            $this->actionNextPage,
266 5
            $this->actionLastPage
267
        );
268 5
        $pager->setPosition(0, $posY);
269 5
        $frame->addChild($pager);
270
271 5
        return $frame;
272
    }
273
274
    /**
275
     * Action callback to go to the first page.
276
     */
277 1
    public function goToFirstPage()
278
    {
279 1
        $this->changePage(1);
280 1
    }
281
282
    /**
283
     * Action callback to go to the previous page.
284
     */
285 1
    public function goToPreviousPage()
286
    {
287 1
        if ($this->currentPage - 1 >= 1) {
288 1
            $this->changePage($this->currentPage - 1);
289
        }
290 1
    }
291
292
    /**
293
     * Action callback to go to the next page.
294
     */
295 3
    public function goToNextPage()
296
    {
297 3
        if ($this->currentPage + 1 <= $this->dataCollection->getLastPageNumber()) {
298 3
            $this->changePage($this->currentPage + 1);
299
        }
300 3
    }
301
302
    /**
303
     * Action callback to go to the last page.
304
     */
305 1
    public function goToLastPage()
306
    {
307 1
        $this->changePage($this->dataCollection->getLastPageNumber());
308 1
    }
309
310
    /**
311
     * Handle page change & refresh user window.
312
     *
313
     * @param integer $page
314
     */
315 4
    protected function changePage($page)
316
    {
317 4
        $this->currentPage = $page;
318 4
        $this->manialinkFactory->update($this->manialink->getUserGroup());
319 4
    }
320
}
321