Passed
Push — trunk ( 6d115e...2fe92c )
by Christian
11:00 queued 15s
created

LayoutBuilder::imageGallery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 23
nc 1
nop 2
dl 0
loc 35
rs 9.552
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\Content\Test\Cms;
4
5
use Shopware\Core\Framework\Test\IdsCollection;
6
use Shopware\Core\Framework\Uuid\Uuid;
7
8
/**
9
 * @internal
10
 * $builder = (new LayoutBuilder($ids, $key))
11
 *     ->productSlider('slider', $ids->getList(['product-1', 'product-2', 'product-3']));
12
 *     ->productThreeColumnBlock('boxes', [
13
 *         $builder->productBox('box-1', $ids->get('product-1')),
14
 *         $builder->productBox('box-2', $ids->get('product-2')),
15
 *         $builder->productBox('box-3', $ids->get('product-3'))
16
 *     ]);
17
 */
18
class LayoutBuilder
19
{
20
    protected string $id;
21
22
    protected ?string $name;
23
24
    /**
25
     * @var mixed[]
26
     */
27
    protected array $_dynamic = [];
28
29
    /**
30
     * @var mixed[]
31
     */
32
    protected array $blocks;
33
34
    /**
35
     * @var mixed[]
36
     */
37
    protected array $sections = [];
38
39
    public function __construct(
40
        protected IdsCollection $ids,
41
        string $key,
42
        protected string $type = 'landingpage'
43
    ) {
44
        $this->id = $this->ids->create($key);
45
        $this->name = $key;
46
    }
47
48
    /**
49
     * @return mixed[]
50
     */
51
    public function build(): array
52
    {
53
        $data = get_object_vars($this);
54
55
        unset($data['ids'], $data['_dynamic']);
56
57
        $data = array_merge($data, $this->_dynamic);
58
59
        $data['sections'] = array_values($data['sections']);
60
61
        return array_filter($data);
62
    }
63
64
    /**
65
     * @param string[] $keys
66
     */
67
    public function productThreeColumnBlock(array $keys, string $section = 'main'): LayoutBuilder
68
    {
69
        $this->section($section);
70
71
        $this->sections[$section]['blocks'][] = [
72
            'position' => $this->blockPosition($section),
73
            'type' => 'product-three-column',
74
            'slots' => [
75
                array_merge(['slot' => 'left'], $this->productBox($keys[0])),
76
                array_merge(['slot' => 'center'], $this->productBox($keys[1])),
77
                array_merge(['slot' => 'right'], $this->productBox($keys[2])),
78
            ],
79
        ];
80
81
        return $this;
82
    }
83
84
    public function listing(string $section = 'main'): LayoutBuilder
85
    {
86
        $this->section($section);
87
88
        $this->sections[$section]['blocks'][] = array_merge([
89
            'position' => $this->blockPosition($section),
90
            'type' => 'product-listing',
91
            'sectionPosition' => 'main',
92
            'slots' => [
93
                ['type' => 'product-listing', 'slot' => 'content', 'config' => []],
94
            ],
95
        ], self::margin(20, 20, 20, 20));
96
97
        return $this;
98
    }
99
100
    public function image(string $key, string $section = 'main'): self
101
    {
102
        $this->section($section);
103
104
        $this->sections[$section]['blocks'][] = array_merge(
105
            [
106
                'type' => 'image',
107
                'position' => $this->blockPosition($section),
108
                'sectionPosition' => 'main',
109
                'backgroundMediaMode' => 'cover',
110
                'slots' => [
111
                    [
112
                        'type' => 'image',
113
                        'slot' => 'image',
114
                        'config' => [
115
                            'url' => ['source' => 'static', 'value' => 300],
116
                            'media' => ['source' => 'static', 'value' => $this->ids->get($key)],
117
                            'newTab' => ['source' => 'static', 'value' => false],
118
                            'minHeight' => ['source' => 'static', 'value' => '340px'],
119
                            'displayMode' => ['source' => 'static', 'value' => 'standard'],
120
                            'verticalAlign' => ['source' => 'static', 'value' => null],
121
                        ],
122
                    ],
123
                ],
124
            ],
125
            self::margin(20, 20, 20, 20)
126
        );
127
128
        return $this;
129
    }
130
131
    /**
132
     * @param string[] $keys
133
     */
134
    public function imageSlider(array $keys, string $section = 'main'): self
135
    {
136
        $this->section($section);
137
138
        $this->sections[$section]['blocks'][] = array_merge(
139
            [
140
                'type' => 'image-slider',
141
                'position' => $this->blockPosition($section),
142
                'sectionPosition' => 'main',
143
                'backgroundMediaMode' => 'cover',
144
                'slots' => [
145
                    [
146
                        'type' => 'image-slider',
147
                        'slot' => 'imageSlider',
148
                        'config' => [
149
                            'sliderItems' => [
150
                                'source' => 'static',
151
                                'value' => array_map(fn (string $id) => ['mediaId' => $id], array_values($this->ids->getList($keys))),
152
                            ],
153
                            'speed' => ['source' => 'static', 'value' => 300],
154
                            'autoSlide' => ['source' => 'static', 'value' => false],
155
                            'minHeight' => ['source' => 'static', 'value' => '300px'],
156
                            'displayMode' => ['source' => 'static', 'value' => 'standard'],
157
                            'verticalAlign' => ['source' => 'static', 'value' => null],
158
                            'navigationDots' => ['source' => 'static', 'value' => true],
159
                            'autoplayTimeout' => ['source' => 'static', 'value' => 5000],
160
                            'navigationArrows' => ['source' => 'static', 'value' => 'outside'],
161
                        ],
162
                    ],
163
                ],
164
            ],
165
            self::margin(20, 20, 20, 20)
166
        );
167
168
        return $this;
169
    }
170
171
    /**
172
     * @param string[] $keys
173
     */
174
    public function imageGallery(array $keys, string $section = 'main'): self
175
    {
176
        $this->section($section);
177
178
        $this->sections[$section]['blocks'][] = array_merge(
179
            [
180
                'type' => 'image-gallery',
181
                'position' => $this->blockPosition($section),
182
                'sectionPosition' => 'main',
183
                'backgroundMediaMode' => 'cover',
184
                'slots' => [
185
                    [
186
                        'type' => 'image-gallery',
187
                        'slot' => 'imageGallery',
188
                        'config' => [
189
                            'sliderItems' => [
190
                                'source' => 'static',
191
                                'value' => array_map(fn (string $id) => ['mediaId' => $id], array_values($this->ids->getList($keys))),
192
                            ],
193
                            'speed' => ['source' => 'static', 'value' => 300],
194
                            'autoSlide' => ['source' => 'static', 'value' => false],
195
                            'minHeight' => ['source' => 'static', 'value' => '300px'],
196
                            'displayMode' => ['source' => 'static', 'value' => 'standard'],
197
                            'verticalAlign' => ['source' => 'static', 'value' => null],
198
                            'navigationDots' => ['source' => 'static', 'value' => true],
199
                            'autoplayTimeout' => ['source' => 'static', 'value' => 5000],
200
                            'navigationArrows' => ['source' => 'static', 'value' => 'outside'],
201
                        ],
202
                    ],
203
                ],
204
            ],
205
            self::margin(20, 20, 20, 20)
206
        );
207
208
        return $this;
209
    }
210
211
    /**
212
     * @param string[] $keys
213
     */
214
    public function productSlider(array $keys, string $section = 'main'): self
215
    {
216
        $this->section($section);
217
218
        $this->sections[$section]['blocks'][] = array_merge(
219
            [
220
                'type' => 'product-slider',
221
                'position' => $this->blockPosition($section),
222
                'sectionPosition' => 'main',
223
                'backgroundMediaMode' => 'cover',
224
                'slots' => [
225
                    [
226
                        'type' => 'product-slider',
227
                        'slot' => 'productSlider',
228
                        'config' => [
229
                            'products' => [
230
                                'source' => 'static',
231
                                'value' => array_values($this->ids->getList($keys)),
232
                            ],
233
                            'title' => ['source' => 'static', 'value' => ''],
234
                            'displayMode' => ['source' => 'static', 'value' => 'standard'],
235
                            'boxLayout' => ['source' => 'static', 'value' => 'standard'],
236
                            'navigation' => ['source' => 'static', 'value' => true],
237
                            'rotate' => ['source' => 'static', 'value' => false],
238
                            'border' => ['source' => 'static', 'value' => false],
239
                            'elMinWidth' => ['source' => 'static', 'value' => '300px'],
240
                            'verticalAlign' => ['source' => 'static', 'value' => null],
241
                            'productStreamSorting' => ['source' => 'static', 'value' => 'name:ASC'],
242
                            'productStreamLimit' => ['source' => 'static', 'value' => 10],
243
                        ],
244
                    ],
245
                ],
246
            ],
247
            self::margin(20, 20, 20, 20)
248
        );
249
250
        return $this;
251
    }
252
253
    public function productStreamSlider(string $stream, string $section = 'main'): self
254
    {
255
        $this->section($section);
256
257
        $this->sections[$section]['blocks'][] = array_merge(
258
            [
259
                'type' => 'product-slider',
260
                'position' => $this->blockPosition($section),
261
                'sectionPosition' => 'main',
262
                'backgroundMediaMode' => 'cover',
263
                'slots' => [
264
                    [
265
                        'type' => 'product-slider',
266
                        'slot' => 'productSlider',
267
                        'config' => [
268
                            'products' => [
269
                                'source' => 'product_stream',
270
                                'value' => $this->ids->get($stream),
271
                            ],
272
                            'title' => ['source' => 'static', 'value' => ''],
273
                            'displayMode' => ['source' => 'static', 'value' => 'standard'],
274
                            'boxLayout' => ['source' => 'static', 'value' => 'standard'],
275
                            'navigation' => ['source' => 'static', 'value' => true],
276
                            'rotate' => ['source' => 'static', 'value' => false],
277
                            'border' => ['source' => 'static', 'value' => false],
278
                            'elMinWidth' => ['source' => 'static', 'value' => '300px'],
279
                            'verticalAlign' => ['source' => 'static', 'value' => null],
280
                            'productStreamSorting' => ['source' => 'static', 'value' => 'name:ASC'],
281
                            'productStreamLimit' => ['source' => 'static', 'value' => 10],
282
                        ],
283
                    ],
284
                ],
285
            ],
286
            self::margin(20, 20, 20, 20)
287
        );
288
289
        return $this;
290
    }
291
292
    /**
293
     * @return mixed[]
294
     */
295
    public function productBox(string $key, string $boxLayout = 'standard', string $displayMode = 'standard'): array
296
    {
297
        return [
298
            'type' => 'product-box',
299
            'config' => [
300
                'product' => ['source' => 'static', 'value' => $this->ids->get($key)],
301
                'boxLayout' => ['source' => 'static', 'value' => $boxLayout],
302
                'displayMode' => ['source' => 'static', 'value' => $displayMode],
303
                'verticalAlign' => ['source' => 'static', 'value' => null],
304
            ],
305
        ];
306
    }
307
308
    public function section(string $key): void
309
    {
310
        if (isset($this->sections[$key])) {
311
            return;
312
        }
313
314
        $this->sections[$key] = [
315
            'type' => 'default',
316
            'position' => \count($this->sections),
317
            'blocks' => [],
318
        ];
319
    }
320
321
    public function productHeading(?string $key = null, string $section = 'main'): self
322
    {
323
        $this->section($section);
324
        $key ??= Uuid::randomHex();
325
326
        $this->sections[$section]['blocks'][$key] = array_merge(
327
            [
328
                'type' => 'product-heading',
329
                'position' => $this->blockPosition($section),
330
                'slots' => [
331
                    ['type' => 'product-name', 'slot' => 'left'],
332
                    ['type' => 'manufacturer-logo', 'slot' => 'right'],
333
                ],
334
            ],
335
            self::margin(0, 0, 20, 0)
336
        );
337
338
        return $this;
339
    }
340
341
    public function galleryBuybox(?string $key = null, string $section = 'main'): self
342
    {
343
        $this->section($section);
344
        $key ??= Uuid::randomHex();
345
        $this->sections[$section]['blocks'][$key] = array_merge(
346
            [
347
                'type' => 'gallery-buybox',
348
                'position' => $this->blockPosition($section),
349
                'slots' => [
350
                    ['type' => 'image-gallery', 'slot' => 'left'],
351
                    ['type' => 'buy-box', 'slot' => 'right'],
352
                ],
353
            ],
354
            self::margin(20, 0, 0, 0)
355
        );
356
357
        return $this;
358
    }
359
360
    public function descriptionReviews(?string $key = null, string $section = 'main'): self
361
    {
362
        $this->section($section);
363
        $key ??= Uuid::randomHex();
364
        $this->sections[$section]['blocks'][$key] = array_merge(
365
            [
366
                'type' => 'product-description-reviews',
367
                'position' => $this->blockPosition($section),
368
                'slots' => [
369
                    ['type' => 'product-description-reviews', 'slot' => 'content'],
370
                ],
371
            ],
372
            self::margin(20, 0, 20, 0)
373
        );
374
375
        return $this;
376
    }
377
378
    public function crossSelling(?string $key = null, string $section = 'main'): self
379
    {
380
        $this->section($section);
381
        $key ??= Uuid::randomHex();
382
        $this->sections[$section]['blocks'][$key] = array_merge(
383
            [
384
                'type' => 'cross-selling',
385
                'position' => $this->blockPosition($section),
386
                'slots' => [
387
                    ['type' => 'cross-selling', 'slot' => 'content'],
388
                ],
389
            ],
390
            self::margin(20, 0, 20, 0)
391
        );
392
393
        return $this;
394
    }
395
396
    private function blockPosition(string $section): int
397
    {
398
        return is_countable($this->sections[$section]['blocks']) ? \count($this->sections[$section]['blocks']) : 0;
399
    }
400
401
    /**
402
     * @return string[]
403
     */
404
    private static function margin(int $top, int $right, int $bottom, int $left): array
405
    {
406
        return [
407
            'marginTop' => $top > 0 ? $top . 'px' : '0',
408
            'marginRight' => $right > 0 ? $right . 'px' : '0',
409
            'marginBottom' => $bottom > 0 ? $bottom . 'px' : '0',
410
            'marginLeft' => $left > 0 ? $top . '$left' : '0',
411
        ];
412
    }
413
}
414