Passed
Push — master ( 3ca101...8b8348 )
by Alex
02:14
created

ListBuilder::listingHeaderCells()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 15
nc 8
nop 1
dl 0
loc 26
rs 9.2222
c 0
b 0
f 0
1
<?php
2
namespace Mezon\Gui\ListBuilder;
3
4
use Mezon\Functional\Fetcher;
5
use Mezon\Gui\WidgetsRegistry\BootstrapWidgets;
6
use Mezon\TemplateEngine\TemplateEngine;
7
use Mezon\Functional\Functional;
8
9
/**
10
 * Class ListBuilder
11
 *
12
 * @package CrudService
13
 * @subpackage ListBuilder
14
 * @author Dodonov A.A.
15
 * @version v.1.0 (2019/08/12)
16
 * @copyright Copyright (c) 2019, aeon.org
17
 */
18
define('DESCRIPTION_FIELD_NAME', 'description');
19
20
/**
21
 * Class constructs grids.
22
 */
23
class ListBuilder
24
{
25
26
    /**
27
     * Fields
28
     *
29
     * @var array
30
     */
31
    protected $fields = [];
32
33
    /**
34
     * Service logic adapter
35
     *
36
     * @var \Mezon\Gui\ListBuilder\ListBuilderAdapter
37
     */
38
    protected $listBuilderAdapter = false;
39
40
    /**
41
     * List item transformation callback
42
     *
43
     * @var array
44
     */
45
    protected $recordTransformer = [];
46
47
    /**
48
     * Constructor
49
     *
50
     * @param array $fields
51
     *            List of fields
52
     * @param \Mezon\Gui\ListBuilder\ListBuilderAdapter $listBuilderAdapter
53
     *            Adapter for the data source
54
     */
55
    public function __construct(array $fields, \Mezon\Gui\ListBuilder\ListBuilderAdapter $listBuilderAdapter)
56
    {
57
        $this->fields = $fields;
58
59
        $this->listBuilderAdapter = $listBuilderAdapter;
60
    }
61
62
    /**
63
     * Setting record transformer
64
     *
65
     * @param mixed $recordTransformer
66
     *            callable record transformer
67
     * @codeCoverageIgnore
68
     */
69
    public function setRecordTransformer($recordTransformer): void
70
    {
71
        $this->recordTransformer = $recordTransformer;
72
    }
73
74
    /**
75
     * Method returns end point for the create page form
76
     *
77
     * @return string Create page endpoint
78
     */
79
    protected function getCreatePageEndpoint(): string
80
    {
81
        if (isset($_GET['create-page-endpoint'])) {
82
            return $_GET['create-page-endpoint'];
83
        }
84
85
        return '../create/';
86
    }
87
88
    /**
89
     * Method shows "no records" message instead of listing
90
     *
91
     * @return string Compiled list view
92
     */
93
    protected function listingNoItems(): string
94
    {
95
        $content = BootstrapWidgets::get('listing-no-items');
96
97
        return str_replace('{create-page-endpoint}', $this->getCreatePageEndpoint(), $content);
98
    }
99
100
    /**
101
     * Method displays list of possible buttons
102
     *
103
     * @param int $id
104
     *            Id of the record
105
     * @return string Compiled list buttons
106
     */
107
    protected function listOfButtons(int $id): string
108
    {
109
        $content = BootstrapWidgets::get('list-of-buttons');
110
111
        return str_replace('{id}', $id, $content);
112
    }
113
114
    /**
115
     * Need to display actions in list
116
     *
117
     * @return bool Do we need add actions
118
     */
119
    protected function needActions(): bool
120
    {
121
        if (@$_GET['update-button'] == 1 || @$_GET['delete-button'] == 1) {
122
            return true;
123
        } else {
124
            return false;
125
        }
126
    }
127
128
    /**
129
     * Method compiles listing items cells
130
     *
131
     * @param bool $addActions
132
     *            Do we need to add actions
133
     * @return string Compiled row
134
     */
135
    protected function listingItemsCells(bool $addActions = true): string
136
    {
137
        $content = '';
138
139
        foreach ($this->fields as $name) {
140
            if ($name == 'domain_id') {
141
                continue;
142
            }
143
            if ($name == 'id') {
144
                $content .= BootstrapWidgets::get('listing-row-centered-cell');
145
            } else {
146
                $content .= BootstrapWidgets::get('listing-row-cell');
147
            }
148
            $content = str_replace('{name}', '{' . $name . '}', $content);
149
        }
150
151
        if ($addActions && $this->needActions()) {
152
            $content .= BootstrapWidgets::get('listing-actions');
153
        }
154
155
        return $content;
156
    }
157
158
    /**
159
     * Method transforms database record
160
     *
161
     * @param array $record
162
     *            Transforming record
163
     * @return object Transformed record
164
     */
165
    protected function transformRecord(object $record): object
166
    {
167
        // here we assume that we get from service
168
        // already transformed
169
        // and here we provide only additional transformations
170
        if (is_callable($this->recordTransformer)) {
171
            $record = call_user_func($this->recordTransformer, $record);
172
        }
173
174
        return $record;
175
    }
176
177
    /**
178
     * Method compiles listing items
179
     *
180
     * @param array $records
181
     *            Listof records
182
     * @return string Compiled list items
183
     */
184
    protected function listingItems(array $records): string
185
    {
186
        $content = '';
187
188
        foreach ($records as $record) {
189
            Functional::setField($record, 'actions', $this->listOfButtons(Fetcher::getField($record, 'id')));
0 ignored issues
show
Bug introduced by
It seems like Mezon\Functional\Fetcher::getField($record, 'id') can also be of type null; however, parameter $id of Mezon\Gui\ListBuilder\ListBuilder::listOfButtons() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

189
            Functional::setField($record, 'actions', $this->listOfButtons(/** @scrutinizer ignore-type */ Fetcher::getField($record, 'id')));
Loading history...
190
191
            $content .= BootstrapWidgets::get('listing-row');
192
            $content = str_replace('{items}', $this->listingItemsCells(), $content);
193
194
            $record = $this->transformRecord($record);
195
196
            $record = $this->listBuilderAdapter->preprocessListItem($record);
197
198
            $content = TemplateEngine::printRecord($content, $record);
199
        }
200
201
        return $content;
202
    }
203
204
    /**
205
     * Method compiles header cells
206
     *
207
     * @param bool $addActions
208
     *            Do we need to add actions
209
     * @return string Compiled header
210
     */
211
    protected function listingHeaderCells(bool $addActions = true): string
212
    {
213
        $content = '';
214
215
        foreach ($this->fields as $name) {
216
            if ($name == 'domain_id') {
217
                continue;
218
            }
219
220
            $idStyle = $name == 'id' ? 'style="text-align: center;"' : '';
221
222
            $content .= BootstrapWidgets::get('listing-header-cell');
223
            $content = str_replace([
224
                '{id-style}',
225
                '{title}'
226
            ], [
227
                $idStyle,
228
                $name
229
            ], $content);
230
        }
231
232
        if ($addActions && $this->needActions()) {
233
            $content .= BootstrapWidgets::get('listing-header-actions');
234
        }
235
236
        return $content;
237
    }
238
239
    /**
240
     * Method returns listing header content
241
     *
242
     * @param
243
     *            string Compiled header
244
     */
245
    protected function listingHeaderContent(): string
246
    {
247
        if (@$_GET['create-button'] == 1) {
248
            $content = BootstrapWidgets::get('listing-header');
249
250
            $content = str_replace('{create-page-endpoint}', $this->getCreatePageEndpoint(), $content);
251
        } else {
252
            $content = BootstrapWidgets::get('simple-listing-header');
253
        }
254
255
        return $content;
256
    }
257
258
    /**
259
     * Method compiles listing header
260
     *
261
     * @return string Compiled header
262
     */
263
    protected function listingHeader(): string
264
    {
265
        $content = $this->listingHeaderContent();
266
267
        $content = str_replace(
268
            '{description}',
269
            isset($_GET[DESCRIPTION_FIELD_NAME]) ? $_GET[DESCRIPTION_FIELD_NAME] : 'Выберите необходимое действие',
270
            $content);
271
272
        return str_replace('{cells}', $this->listingHeaderCells(), $content);
273
    }
274
275
    /**
276
     * Method compiles listing header
277
     *
278
     * @return string Compiled header
279
     */
280
    protected function simpleListingHeader(): string
281
    {
282
        $content = BootstrapWidgets::get('simple-listing-header');
283
284
        $content = str_replace(
285
            '{description}',
286
            isset($_GET[DESCRIPTION_FIELD_NAME]) ? $_GET[DESCRIPTION_FIELD_NAME] : 'Выберите необходимое действие',
287
            $content);
288
289
        return str_replace('{cells}', $this->listingHeaderCells(false), $content);
290
    }
291
292
    /**
293
     * Method compiles listing items
294
     *
295
     * @param array $records
296
     *            List of records
297
     * @return string Compiled simple list
298
     */
299
    protected function simpleListingItems(array $records): string
300
    {
301
        $content = '';
302
303
        foreach ($records as $record) {
304
            $content .= str_replace(
305
                '{items}',
306
                $this->listingItemsCells(false),
307
                BootstrapWidgets::get('listing-row'));
308
309
            $record = $this->transformRecord($record);
310
311
            $content = TemplateEngine::printRecord($content, $record);
312
        }
313
314
        return $content;
315
    }
316
317
    /**
318
     * Method compiles listing form
319
     *
320
     * @return string Compiled listing form
321
     */
322
    public function listingForm(): string
323
    {
324
        // TODO split into SimpleListBuilder and ListBuilder
325
        $records = $this->listBuilderAdapter->getRecords([
326
            'field' => 'id',
327
            'order' => 'ASC'
328
        ], isset($_GET['from']) ? $_GET['from'] : 0, isset($_GET['limit']) ? $_GET['limit'] : 100);
329
330
        if (! empty($records)) {
331
            $header = $this->listingHeader();
332
333
            $items = $this->listingItems($records);
334
335
            $footer = BootstrapWidgets::get('listing-footer');
336
337
            return $header . $items . $footer;
338
        } else {
339
            return $this->listingNoItems();
340
        }
341
    }
342
343
    /**
344
     * Method compiles simple_listing form
345
     *
346
     * @return string Compiled simple listing form
347
     */
348
    public function simpleListingForm(): string
349
    {
350
        $records = $this->listBuilderAdapter->all();
351
352
        if (! empty($records)) {
353
            $header = $this->simpleListingHeader();
354
355
            $items = $this->simpleListingItems($records);
356
357
            // they are the same with full feature listing
358
            $footer = BootstrapWidgets::get('listing-footer');
359
360
            return $header . $items . $footer;
361
        } else {
362
            return BootstrapWidgets::get('listing-no-items');
363
        }
364
    }
365
366
    /**
367
     * Method returns fields of the list
368
     *
369
     * @return array fields list
370
     */
371
    public function getFields(): array
372
    {
373
        return $this->fields;
374
    }
375
}
376