Completed
Push — master ( 7c81ae...22b0b3 )
by
unknown
02:49 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
    public function configureSettings(OptionsResolver $resolver): void
96
    {
97
        $resolver->setDefaults([
98
            'gallery' => false,
99
            'title' => null,
100
            'translation_domain' => null,
101
            'icon' => null,
102
            'class' => null,
103
            'context' => false,
104
            'format' => false,
105
            'pauseTime' => 3000,
106
            'startPaused' => false,
107
            'template' => '@SonataMedia/Block/block_gallery.html.twig',
108
            'galleryId' => null,
109
        ]);
110
    }
111
112
    /**
113
     * NEXT_MAJOR: Remove this method.
114
     *
115
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
116
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
117
     */
118
    public function buildEditForm(FormMapper $formMapper, BlockInterface $block): void
119
    {
120
        $contextChoices = [];
121
122
        foreach ($this->getMediaPool()->getContexts() as $name => $context) {
123
            $contextChoices[$name] = $name;
124
        }
125
126
        $gallery = $block->getSetting('galleryId');
127
128
        $formatChoices = [];
129
130
        if ($gallery instanceof GalleryInterface) {
131
            $formats = $this->getMediaPool()->getFormatNamesByContext($gallery->getContext());
132
133
            foreach ($formats as $code => $format) {
134
                $formatChoices[$code] = $code;
135
            }
136
        }
137
138
        // simulate an association ...
139
        $fieldDescription = $this->getGalleryAdmin()->getModelManager()->getNewFieldDescriptionInstance($this->getGalleryAdmin()->getClass(), 'media', [
140
            'translation_domain' => 'SonataMediaBundle',
141
        ]);
142
        $fieldDescription->setAssociationAdmin($this->getGalleryAdmin());
143
        $fieldDescription->setAdmin($formMapper->getAdmin());
144
        $fieldDescription->setOption('edit', 'list');
145
        $fieldDescription->setAssociationMapping(['fieldName' => 'gallery', 'type' => ClassMetadataInfo::MANY_TO_ONE]);
146
147
        $builder = $formMapper->create('galleryId', ModelListType::class, [
148
            'sonata_field_description' => $fieldDescription,
149
            'class' => $this->getGalleryAdmin()->getClass(),
150
            'model_manager' => $this->getGalleryAdmin()->getModelManager(),
151
            'label' => 'form.label_gallery',
152
        ]);
153
154
        $formMapper->add('settings', ImmutableArrayType::class, [
155
            'keys' => [
156
                ['title', TextType::class, [
157
                    'label' => 'form.label_title',
158
                    'required' => false,
159
                ]],
160
                ['translation_domain', TextType::class, [
161
                    'label' => 'form.label_translation_domain',
162
                    'required' => false,
163
                ]],
164
                ['icon', TextType::class, [
165
                    'label' => 'form.label_icon',
166
                    'required' => false,
167
                ]],
168
                ['class', TextType::class, [
169
                    'label' => 'form.label_class',
170
                    'required' => false,
171
                ]],
172
                ['context', ChoiceType::class, [
173
                    'required' => true,
174
                    'choices' => $contextChoices,
175
                    'label' => 'form.label_context',
176
                ]],
177
                ['format', ChoiceType::class, [
178
                    'required' => \count($formatChoices) > 0,
179
                    'choices' => $formatChoices,
180
                    'label' => 'form.label_format',
181
                ]],
182
                [$builder, null, []],
183
                ['pauseTime', NumberType::class, [
184
                    'label' => 'form.label_pause_time',
185
                ]],
186
                ['startPaused', CheckboxType::class, [
187
                    'required' => false,
188
                    'label' => 'form.label_start_paused',
189
                ]],
190
            ],
191
            'translation_domain' => 'SonataMediaBundle',
192
        ]);
193
    }
194
195
    public function execute(BlockContextInterface $blockContext, ?Response $response = null)
196
    {
197
        $gallery = $blockContext->getBlock()->getSetting('galleryId');
198
199
        return $this->renderResponse($blockContext->getTemplate(), [
200
            'gallery' => $gallery,
201
            'block' => $blockContext->getBlock(),
202
            'settings' => $blockContext->getSettings(),
203
            'elements' => $gallery ? $this->buildElements($gallery) : [],
204
        ], $response);
205
    }
206
207
    public function load(BlockInterface $block): void
208
    {
209
        $gallery = $block->getSetting('galleryId');
210
211
        if ($gallery) {
212
            $gallery = $this->galleryManager->findOneBy(['id' => $gallery]);
213
        }
214
215
        $block->setSetting('galleryId', $gallery);
216
    }
217
218
    /**
219
     * NEXT_MAJOR: Remove this method.
220
     *
221
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
222
     */
223
    public function prePersist(BlockInterface $block): void
224
    {
225
        $block->setSetting('galleryId', \is_object($block->getSetting('galleryId')) ? $block->getSetting('galleryId')->getId() : null);
226
    }
227
228
    /**
229
     * NEXT_MAJOR: Remove this method.
230
     *
231
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
232
     */
233
    public function preUpdate(BlockInterface $block): void
234
    {
235
        $block->setSetting('galleryId', \is_object($block->getSetting('galleryId')) ? $block->getSetting('galleryId')->getId() : null);
236
    }
237
238
    /**
239
     * NEXT_MAJOR: Remove this method.
240
     *
241
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
242
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
243
     */
244
    public function getBlockMetadata($code = null)
245
    {
246
        return new Metadata($this->getName(), (null !== $code ? $code : $this->getName()), false, 'SonataMediaBundle', [
247
            'class' => 'fa fa-picture-o',
248
        ]);
249
    }
250
251
    /**
252
     * NEXT_MAJOR: Remove this method.
253
     *
254
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0. You should use
255
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
256
     */
257
    public function buildCreateForm(FormMapper $formMapper, BlockInterface $block)
258
    {
259
        $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...
260
    }
261
262
    /**
263
     * NEXT_MAJOR: Remove this method.
264
     *
265
     * @deprecated since sonata-project/media-bundle 3.25, to be removed in 4.0.
266
     */
267
    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...
268
    {
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 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...
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 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...
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 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...
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. You should use
302
     *             `Sonata\BlockBundle\Block\Service\EditableBlockService` interface instead.
303
     */
304
    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...
305
    {
306
    }
307
308
    private function buildElements(GalleryInterface $gallery): array
309
    {
310
        $elements = [];
311
        foreach ($gallery->getGalleryItems() as $galleryItem) {
312
            if (!$galleryItem->getEnabled()) {
313
                continue;
314
            }
315
316
            $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...
317
318
            if (null === $type) {
319
                continue;
320
            }
321
322
            $elements[] = [
323
                'title' => $galleryItem->getMedia()->getName(),
324
                'caption' => $galleryItem->getMedia()->getDescription(),
325
                'type' => $type,
326
                'media' => $galleryItem->getMedia(),
327
            ];
328
        }
329
330
        return $elements;
331
    }
332
333
    private function getMediaType(MediaInterface $media): ?string
334
    {
335
        if ('video/x-flv' === $media->getContentType()) {
336
            return 'video';
337
        }
338
        if ('image' === substr($media->getContentType(), 0, 5)) {
339
            return 'image';
340
        }
341
342
        return null;
343
    }
344
}
345