Passed
Push — master ( c477ed...0b5fa5 )
by Alex
02:17
created

Common::transformRecord()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 10
rs 10
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
8
/**
9
 * Class ListBuilder
10
 *
11
 * @package CrudService
12
 * @subpackage ListBuilder
13
 * @author Dodonov A.A.
14
 * @version v.1.0 (2019/08/12)
15
 * @copyright Copyright (c) 2019, aeon.org
16
 */
17
18
/**
19
 * Class constructs grids
20
 */
21
class Common
22
{
23
24
    /**
25
     * Fields
26
     *
27
     * @var array
28
     */
29
    private $fields = [];
30
31
    /**
32
     * Service logic adapter
33
     *
34
     * @var \Mezon\Gui\ListBuilder\ListBuilderAdapter
35
     */
36
    private $listBuilderAdapter = false;
37
38
    /**
39
     * List item transformation callback
40
     *
41
     * @var array
42
     */
43
    private $recordTransformer = [];
44
45
    /**
46
     * Custom actions for each record
47
     *
48
     * @var string
49
     */
50
    private $customActions = null;
51
52
    /**
53
     * Constructor
54
     *
55
     * @param array $fields
56
     *            List of fields
57
     * @param \Mezon\Gui\ListBuilder\ListBuilderAdapter $listBuilderAdapter
58
     *            Adapter for the data source
59
     */
60
    public function __construct(array $fields, ListBuilderAdapter $listBuilderAdapter)
61
    {
62
        $transformedFields = [];
63
64
        foreach ($fields as $i => $field) {
65
            $key = is_array($field) ? $i : $field;
66
            $transformedFields[$key] = is_array($field) ? $field : [
67
                'title' => $field
68
            ];
69
        }
70
71
        $this->fields = $transformedFields;
72
73
        $this->listBuilderAdapter = $listBuilderAdapter;
74
    }
75
76
    /**
77
     * Method sets custom actions
78
     *
79
     * @param string $actions
80
     */
81
    public function setCustomActions(string $actions): void
82
    {
83
        $this->customActions = $actions;
84
    }
85
86
    /**
87
     * Setting record transformer
88
     *
89
     * @param mixed $recordTransformer
90
     *            callable record transformer
91
     * @codeCoverageIgnore
92
     */
93
    public function setRecordTransformer($recordTransformer): void
94
    {
95
        $this->recordTransformer = $recordTransformer;
96
    }
97
98
    /**
99
     * Method returns end point for the create page form
100
     *
101
     * @return string Create page endpoint
102
     */
103
    private function getCreatePageEndpoint(): string
104
    {
105
        if (isset($_GET['create-page-endpoint'])) {
106
            return $_GET['create-page-endpoint'];
107
        }
108
109
        return '../create/';
110
    }
111
112
    /**
113
     * Method shows "no records" message instead of listing
114
     *
115
     * @return string Compiled list view
116
     */
117
    private function listingNoItems(): string
118
    {
119
        $content = BootstrapWidgets::get('listing-no-items');
120
121
        return str_replace('{create-page-endpoint}', $this->getCreatePageEndpoint(), $content);
122
    }
123
124
    /**
125
     * Method displays list of possible buttons
126
     *
127
     * @param int $id
128
     *            Id of the record
129
     * @return string Compiled list buttons
130
     */
131
    private function listOfButtons(int $id): string
132
    {
133
        $content = BootstrapWidgets::get('list-of-buttons');
134
135
        return str_replace('{id}', $id, $content);
136
    }
137
138
    /**
139
     * Need to display actions in list
140
     *
141
     * @return bool Do we need add actions
142
     */
143
    private function needActions(): bool
144
    {
145
        if (@$_GET['update-button'] == 1 || @$_GET['delete-button'] == 1 || $this->customActions !== null) {
146
            return true;
147
        }
148
149
        return false;
150
    }
151
152
    /**
153
     * Method compiles listing items cells
154
     *
155
     * @param array|object $record
156
     *            record data
157
     * @return string Compiled row
158
     */
159
    private function listingItemsCells($record): string
160
    {
161
        $content = '';
162
163
        foreach (array_keys($this->fields) as $name) {
164
            if ($name == 'domain_id') {
165
                continue;
166
            }
167
            if ($name == 'id') {
168
                $content .= BootstrapWidgets::get('listing-row-centered-cell');
169
            } else {
170
                $content .= BootstrapWidgets::get('listing-row-cell');
171
            }
172
            $content = str_replace('{name}', '{' . $name . '}', $content);
173
        }
174
175
        if ($this->needActions()) {
176
            $content .= BootstrapWidgets::get('listing-actions');
177
178
            $content = str_replace(
179
                '{actions}',
180
                $this->customActions === null ? $this->listOfButtons(Fetcher::getField($record, 'id')) : $this->customActions,
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\Common::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

180
                $this->customActions === null ? $this->listOfButtons(/** @scrutinizer ignore-type */ Fetcher::getField($record, 'id')) : $this->customActions,
Loading history...
181
                $content);
182
        }
183
184
        return $content;
185
    }
186
187
    /**
188
     * Method transforms database record
189
     *
190
     * @param array $record
191
     *            Transforming record
192
     * @return object Transformed record
193
     */
194
    private function transformRecord(object $record): object
195
    {
196
        // here we assume that we get from service
197
        // already transformed
198
        // and here we provide only additional transformations
199
        if (is_callable($this->recordTransformer)) {
200
            $record = call_user_func($this->recordTransformer, $record);
201
        }
202
203
        return $record;
204
    }
205
206
    /**
207
     * Method compiles listing items
208
     *
209
     * @param array $records
210
     *            Listof records
211
     * @return string Compiled list items
212
     */
213
    private function listingItems(array $records): string
214
    {
215
        $content = '';
216
217
        foreach ($records as $record) {
218
            $content .= BootstrapWidgets::get('listing-row');
219
            $content = str_replace('{items}', $this->listingItemsCells($record), $content);
220
221
            $record = $this->transformRecord($record);
222
223
            $record = $this->listBuilderAdapter->preprocessListItem($record);
224
225
            $content = TemplateEngine::printRecord($content, $record);
226
        }
227
228
        return $content;
229
    }
230
231
    /**
232
     * Method compiles header cells
233
     *
234
     * @return string Compiled header
235
     */
236
    private function listingHeaderCells(): string
237
    {
238
        $content = '';
239
240
        foreach ($this->fields as $name => $data) {
241
            if ($name == 'domain_id') {
242
                continue;
243
            }
244
245
            $idStyle = $name == 'id' ? 'style="text-align: center; width:5%;"' : '';
246
247
            $content .= BootstrapWidgets::get('listing-header-cell');
248
            $content = str_replace([
249
                '{id-style}',
250
                '{title}'
251
            ], [
252
                $idStyle,
253
                $data['title']
254
            ], $content);
255
        }
256
257
        if ($this->needActions()) {
258
            $content .= BootstrapWidgets::get('listing-header-actions');
259
        }
260
261
        return $content;
262
    }
263
264
    /**
265
     * Method returns listing header content
266
     *
267
     * @param
268
     *            string Compiled header
269
     */
270
    private function listingHeaderContent(): string
271
    {
272
        if (@$_GET['create-button'] == 1) {
273
            $content = BootstrapWidgets::get('listing-header');
274
275
            $content = str_replace('{create-page-endpoint}', $this->getCreatePageEndpoint(), $content);
276
        } else {
277
            $content = BootstrapWidgets::get('simple-listing-header');
278
        }
279
280
        return $content;
281
    }
282
283
    /**
284
     * Method compiles listing header
285
     *
286
     * @return string Compiled header
287
     */
288
    private function listingHeader(): string
289
    {
290
        $content = $this->listingHeaderContent();
291
292
        $content = str_replace(
293
            '{description}',
294
            isset($_GET['description']) ? $_GET['description'] : 'Выберите необходимое действие',
295
            $content);
296
297
        return str_replace('{cells}', $this->listingHeaderCells(), $content);
298
    }
299
300
    /**
301
     * Method compiles listing form
302
     *
303
     * @return string Compiled listing form
304
     */
305
    public function listingForm(): string
306
    {
307
        $records = $this->listBuilderAdapter->getRecords([
308
            'field' => 'id',
309
            'order' => 'ASC'
310
        ], isset($_GET['from']) ? $_GET['from'] : 0, isset($_GET['limit']) ? $_GET['limit'] : 100);
311
312
        if (! empty($records)) {
313
            $header = $this->listingHeader();
314
315
            $items = $this->listingItems($records);
316
317
            $footer = BootstrapWidgets::get('listing-footer');
318
319
            return $header . $items . $footer;
320
        } else {
321
            return $this->listingNoItems();
322
        }
323
    }
324
325
    /**
326
     * Method returns fields of the list
327
     *
328
     * @return array fields list
329
     */
330
    public function getFields(): array
331
    {
332
        return $this->fields;
333
    }
334
}
335