Completed
Push — master ( 31a9ea...5d6556 )
by
unknown
03:38 queued 11s
created

src/Block/GalleryBlockService.php (8 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\MediaBundle\Block;
15
16
use Doctrine\ORM\Mapping\ClassMetadataInfo;
17
use Sonata\AdminBundle\Admin\AdminInterface;
18
use Sonata\AdminBundle\Form\FormMapper;
19
use Sonata\AdminBundle\Form\Type\ModelListType;
20
use Sonata\BlockBundle\Block\BlockContextInterface;
21
use Sonata\BlockBundle\Block\Service\AbstractBlockService;
22
use Sonata\BlockBundle\Meta\Metadata;
23
use Sonata\BlockBundle\Model\BlockInterface;
24
use Sonata\Doctrine\Model\ManagerInterface;
25
use Sonata\Form\Type\ImmutableArrayType;
26
use Sonata\Form\Validator\ErrorElement;
27
use Sonata\MediaBundle\Model\GalleryInterface;
28
use Sonata\MediaBundle\Model\MediaInterface;
29
use Sonata\MediaBundle\Provider\Pool;
30
use Symfony\Component\DependencyInjection\ContainerInterface;
31
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
32
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
33
use Symfony\Component\Form\Extension\Core\Type\NumberType;
34
use Symfony\Component\Form\Extension\Core\Type\TextType;
35
use Symfony\Component\HttpFoundation\Response;
36
use Symfony\Component\OptionsResolver\OptionsResolver;
37
use Symfony\Component\Templating\EngineInterface;
38
use Twig\Environment;
39
40
/**
41
 * @final since sonata-project/media-bundle 3.21.0
42
 *
43
 * @author Thomas Rabaix <[email protected]>
44
 */
45
class GalleryBlockService extends AbstractBlockService
46
{
47
    /**
48
     * @var ManagerInterface
49
     */
50
    protected $galleryAdmin;
51
52
    /**
53
     * @var ManagerInterface
54
     */
55
    protected $galleryManager;
56
57
    /**
58
     * @var ContainerInterface
59
     */
60
    private $container;
61
62
    /**
63
     * NEXT_MAJOR: Remove `$templating` argument.
64
     *
65
     * @param Environment|string $twigOrName
66
     */
67
    public function __construct($twigOrName, ?EngineInterface $templating, ContainerInterface $container, ManagerInterface $galleryManager)
68
    {
69
        parent::__construct($twigOrName, $templating);
70
71
        $this->galleryManager = $galleryManager;
72
        $this->container = $container;
73
    }
74
75
    /**
76
     * @return Pool
77
     */
78
    public function getMediaPool()
79
    {
80
        return $this->container->get('sonata.media.pool');
81
    }
82
83
    /**
84
     * @return AdminInterface
85
     */
86
    public function getGalleryAdmin()
87
    {
88
        if (!$this->galleryAdmin) {
89
            $this->galleryAdmin = $this->container->get('sonata.media.admin.gallery');
90
        }
91
92
        return $this->galleryAdmin;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function configureSettings(OptionsResolver $resolver): void
99
    {
100
        $resolver->setDefaults([
101
            'gallery' => false,
102
            'title' => null,
103
            'translation_domain' => null,
104
            'icon' => null,
105
            'class' => null,
106
            'context' => false,
107
            'format' => false,
108
            'pauseTime' => 3000,
109
            'startPaused' => false,
110
            'template' => '@SonataMedia/Block/block_gallery.html.twig',
111
            'galleryId' => null,
112
        ]);
113
    }
114
115
    /**
116
     * NEXT_MAJOR: Remove this method.
117
     *
118
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
119
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
120
     */
121
    public function buildEditForm(FormMapper $formMapper, BlockInterface $block): void
122
    {
123
        $contextChoices = [];
124
125
        foreach ($this->getMediaPool()->getContexts() as $name => $context) {
126
            $contextChoices[$name] = $name;
127
        }
128
129
        $gallery = $block->getSetting('galleryId');
130
131
        $formatChoices = [];
132
133
        if ($gallery instanceof GalleryInterface) {
134
            $formats = $this->getMediaPool()->getFormatNamesByContext($gallery->getContext());
135
136
            foreach ($formats as $code => $format) {
137
                $formatChoices[$code] = $code;
138
            }
139
        }
140
141
        // simulate an association ...
142
        $fieldDescription = $this->getGalleryAdmin()->getModelManager()->getNewFieldDescriptionInstance($this->getGalleryAdmin()->getClass(), 'media', [
143
            'translation_domain' => 'SonataMediaBundle',
144
        ]);
145
        $fieldDescription->setAssociationAdmin($this->getGalleryAdmin());
146
        $fieldDescription->setAdmin($formMapper->getAdmin());
147
        $fieldDescription->setOption('edit', 'list');
148
        $fieldDescription->setAssociationMapping(['fieldName' => 'gallery', 'type' => ClassMetadataInfo::MANY_TO_ONE]);
149
150
        $builder = $formMapper->create('galleryId', ModelListType::class, [
151
            'sonata_field_description' => $fieldDescription,
152
            'class' => $this->getGalleryAdmin()->getClass(),
153
            'model_manager' => $this->getGalleryAdmin()->getModelManager(),
154
            'label' => 'form.label_gallery',
155
        ]);
156
157
        $formMapper->add('settings', ImmutableArrayType::class, [
158
            'keys' => [
159
                ['title', TextType::class, [
160
                    'label' => 'form.label_title',
161
                    'required' => false,
162
                ]],
163
                ['translation_domain', TextType::class, [
164
                    'label' => 'form.label_translation_domain',
165
                    'required' => false,
166
                ]],
167
                ['icon', TextType::class, [
168
                    'label' => 'form.label_icon',
169
                    'required' => false,
170
                ]],
171
                ['class', TextType::class, [
172
                    'label' => 'form.label_class',
173
                    'required' => false,
174
                ]],
175
                ['context', ChoiceType::class, [
176
                    'required' => true,
177
                    'choices' => $contextChoices,
178
                    'label' => 'form.label_context',
179
                ]],
180
                ['format', ChoiceType::class, [
181
                    'required' => \count($formatChoices) > 0,
182
                    'choices' => $formatChoices,
183
                    'label' => 'form.label_format',
184
                ]],
185
                [$builder, null, []],
186
                ['pauseTime', NumberType::class, [
187
                    'label' => 'form.label_pause_time',
188
                ]],
189
                ['startPaused', CheckboxType::class, [
190
                    'required' => false,
191
                    'label' => 'form.label_start_paused',
192
                ]],
193
            ],
194
            'translation_domain' => 'SonataMediaBundle',
195
        ]);
196
    }
197
198
    /**
199
     * {@inheritdoc}
200
     */
201
    public function execute(BlockContextInterface $blockContext, ?Response $response = null)
202
    {
203
        $gallery = $blockContext->getBlock()->getSetting('galleryId');
204
205
        return $this->renderResponse($blockContext->getTemplate(), [
206
            'gallery' => $gallery,
207
            'block' => $blockContext->getBlock(),
208
            'settings' => $blockContext->getSettings(),
209
            'elements' => $gallery ? $this->buildElements($gallery) : [],
210
        ], $response);
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216
    public function load(BlockInterface $block): void
217
    {
218
        $gallery = $block->getSetting('galleryId');
219
220
        if ($gallery) {
221
            $gallery = $this->galleryManager->findOneBy(['id' => $gallery]);
222
        }
223
224
        $block->setSetting('galleryId', $gallery);
225
    }
226
227
    /**
228
     * NEXT_MAJOR: Remove this method.
229
     *
230
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
231
     */
232
    public function prePersist(BlockInterface $block): void
233
    {
234
        $block->setSetting('galleryId', \is_object($block->getSetting('galleryId')) ? $block->getSetting('galleryId')->getId() : null);
235
    }
236
237
    /**
238
     * NEXT_MAJOR: Remove this method.
239
     *
240
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
241
     */
242
    public function preUpdate(BlockInterface $block): void
243
    {
244
        $block->setSetting('galleryId', \is_object($block->getSetting('galleryId')) ? $block->getSetting('galleryId')->getId() : null);
245
    }
246
247
    /**
248
     * NEXT_MAJOR: Remove this method.
249
     *
250
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
251
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
252
     */
253
    public function getBlockMetadata($code = null)
254
    {
255
        return new Metadata($this->getName(), (null !== $code ? $code : $this->getName()), false, 'SonataMediaBundle', [
256
            'class' => 'fa fa-picture-o',
257
        ]);
258
    }
259
260
    /**
261
     * NEXT_MAJOR: Remove this method.
262
     *
263
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
264
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
265
     */
266
    public function buildCreateForm(FormMapper $formMapper, BlockInterface $block)
267
    {
268
        $this->buildEditForm($formMapper, $block);
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\MediaBundle\Block...ervice::buildEditForm() has been deprecated with message: since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
269
    }
270
271
    /**
272
     * NEXT_MAJOR: Remove this method.
273
     *
274
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
275
     */
276
    public function postPersist(BlockInterface $block)
0 ignored issues
show
The parameter $block is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
277
    {
278
    }
279
280
    /**
281
     * NEXT_MAJOR: Remove this method.
282
     *
283
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
284
     */
285
    public function postUpdate(BlockInterface $block)
0 ignored issues
show
The parameter $block is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
286
    {
287
    }
288
289
    /**
290
     * NEXT_MAJOR: Remove this method.
291
     *
292
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
293
     */
294
    public function preRemove(BlockInterface $block)
0 ignored issues
show
The parameter $block is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
295
    {
296
    }
297
298
    /**
299
     * NEXT_MAJOR: Remove this method.
300
     *
301
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
302
     */
303
    public function postRemove(BlockInterface $block)
0 ignored issues
show
The parameter $block is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
304
    {
305
    }
306
307
    /**
308
     * NEXT_MAJOR: Remove this method.
309
     *
310
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
311
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
312
     */
313
    public function validateBlock(ErrorElement $errorElement, BlockInterface $block)
0 ignored issues
show
The parameter $errorElement is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $block is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
314
    {
315
    }
316
317
    private function buildElements(GalleryInterface $gallery): array
318
    {
319
        $elements = [];
320
        foreach ($gallery->getGalleryItems() as $galleryItem) {
321
            if (!$galleryItem->getEnabled()) {
322
                continue;
323
            }
324
325
            $type = $this->getMediaType($galleryItem->getMedia());
0 ignored issues
show
It seems like $galleryItem->getMedia() can be null; however, getMediaType() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
326
327
            if (null === $type) {
328
                continue;
329
            }
330
331
            $elements[] = [
332
                'title' => $galleryItem->getMedia()->getName(),
333
                'caption' => $galleryItem->getMedia()->getDescription(),
334
                'type' => $type,
335
                'media' => $galleryItem->getMedia(),
336
            ];
337
        }
338
339
        return $elements;
340
    }
341
342
    private function getMediaType(MediaInterface $media): ?string
343
    {
344
        if ('video/x-flv' === $media->getContentType()) {
345
            return 'video';
346
        }
347
        if ('image' === substr($media->getContentType(), 0, 5)) {
348
            return 'image';
349
        }
350
351
        return null;
352
    }
353
}
354