Completed
Push — master ( cf3a9d...627ec6 )
by Marko
10s
created

ImageProvider::getReferenceImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
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\Provider;
15
16
use Gaufrette\Filesystem;
17
use Imagine\Image\ImagineInterface;
18
use Sonata\CoreBundle\Model\Metadata;
19
use Sonata\MediaBundle\CDN\CDNInterface;
20
use Sonata\MediaBundle\Generator\GeneratorInterface;
21
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
22
use Sonata\MediaBundle\Model\MediaInterface;
23
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
24
use Symfony\Component\HttpFoundation\File\File;
25
use Symfony\Component\HttpFoundation\File\UploadedFile;
26
27
class ImageProvider extends FileProvider
28
{
29
    /**
30
     * @var ImagineInterface
31
     */
32
    protected $imagineAdapter;
33
34
    /**
35
     * @param string                   $name
36
     * @param Filesystem               $filesystem
37
     * @param CDNInterface             $cdn
38
     * @param GeneratorInterface       $pathGenerator
39
     * @param ThumbnailInterface       $thumbnail
40
     * @param array                    $allowedExtensions
41
     * @param array                    $allowedMimeTypes
42
     * @param ImagineInterface         $adapter
43
     * @param MetadataBuilderInterface $metadata
44
     */
45
    public function __construct($name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, array $allowedExtensions, array $allowedMimeTypes, ImagineInterface $adapter, MetadataBuilderInterface $metadata = null)
46
    {
47
        parent::__construct($name, $filesystem, $cdn, $pathGenerator, $thumbnail, $allowedExtensions, $allowedMimeTypes, $metadata);
48
49
        $this->imagineAdapter = $adapter;
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function getProviderMetadata()
56
    {
57
        return new Metadata($this->getName(), $this->getName().'.description', false, 'SonataMediaBundle', ['class' => 'fa fa-picture-o']);
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getHelperProperties(MediaInterface $media, $format, $options = [])
64
    {
65
        if (MediaProviderInterface::FORMAT_REFERENCE === $format) {
66
            $box = $media->getBox();
67
        } else {
68
            $resizerFormat = $this->getFormat($format);
69
            if (false === $resizerFormat) {
70
                throw new \RuntimeException(sprintf('The image format "%s" is not defined.
71
                        Is the format registered in your ``sonata_media`` configuration?', $format));
72
            }
73
74
            $box = $this->resizer->getBox($media, $resizerFormat);
75
        }
76
77
        $mediaWidth = $box->getWidth();
78
79
        $params = [
80
            'alt' => $media->getName(),
81
            'title' => $media->getName(),
82
            'src' => $this->generatePublicUrl($media, $format),
83
            'width' => $mediaWidth,
84
            'height' => $box->getHeight(),
85
        ];
86
87
        if (MediaProviderInterface::FORMAT_ADMIN !== $format) {
88
            $srcSetFormats = $this->getFormats();
89
90
            if (isset($options['srcset']) && is_array($options['srcset'])) {
91
                $srcSetFormats = [];
92
                foreach ($options['srcset'] as $srcSetFormat) {
93
                    $formatName = $this->getFormatName($media, $srcSetFormat);
94
                    $srcSetFormats[$formatName] = $this->getFormat($formatName);
95
                }
96
                unset($options['srcset']);
97
98
                // Make sure the requested format is also in the srcSetFormats
99
                if (!isset($srcSetFormats[$format])) {
100
                    $srcSetFormats[$format] = $this->getFormat($format);
101
                }
102
            }
103
104
            if (!isset($options['srcset'])) {
105
                $srcSet = [];
106
107
                foreach ($srcSetFormats as $providerFormat => $settings) {
108
                    // Check if format belongs to the current media's context
109
                    if (0 === strpos($providerFormat, $media->getContext())) {
110
                        $width = $this->resizer->getBox($media, $settings)->getWidth();
111
112
                        $srcSet[] = sprintf('%s %dw', $this->generatePublicUrl($media, $providerFormat), $width);
113
                    }
114
                }
115
116
                // The reference format is not in the formats list
117
                $srcSet[] = sprintf(
118
                    '%s %dw',
119
                    $this->generatePublicUrl($media, MediaProviderInterface::FORMAT_REFERENCE),
120
                    $media->getBox()->getWidth()
121
                );
122
123
                $params['srcset'] = implode(', ', $srcSet);
124
            }
125
126
            $params['sizes'] = sprintf('(max-width: %1$dpx) 100vw, %1$dpx', $mediaWidth);
127
        }
128
129
        return array_merge($params, $options);
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function updateMetadata(MediaInterface $media, $force = true): void
136
    {
137
        try {
138
            if (!$media->getBinaryContent() instanceof \SplFileInfo) {
139
                // this is now optimized at all!!!
140
                $path = tempnam(sys_get_temp_dir(), 'sonata_update_metadata');
141
                $fileObject = new \SplFileObject($path, 'w');
142
                $fileObject->fwrite($this->getReferenceFile($media)->getContent());
143
            } else {
144
                $fileObject = $media->getBinaryContent();
145
            }
146
147
            $image = $this->imagineAdapter->open($fileObject->getPathname());
148
            $size = $image->getSize();
149
150
            $media->setSize($fileObject->getSize());
151
            $media->setWidth($size->getWidth());
152
            $media->setHeight($size->getHeight());
153
        } catch (\LogicException $e) {
154
            $media->setProviderStatus(MediaInterface::STATUS_ERROR);
155
156
            $media->setSize(0);
157
            $media->setWidth(0);
158
            $media->setHeight(0);
159
        }
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function generatePublicUrl(MediaInterface $media, $format)
166
    {
167
        if (MediaProviderInterface::FORMAT_REFERENCE === $format) {
168
            $path = $this->getReferenceImage($media);
169
        } else {
170
            $path = $this->thumbnail->generatePublicUrl($this, $media, $format);
171
        }
172
173
        // if $path is already an url, no further action is required
174
        if (null !== parse_url($path, PHP_URL_SCHEME)) {
175
            return $path;
176
        }
177
178
        return $this->getCdn()->getPath($path, $media->getCdnIsFlushable());
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184
    public function generatePrivateUrl(MediaInterface $media, $format)
185
    {
186
        return $this->thumbnail->generatePrivateUrl($this, $media, $format);
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192
    protected function doTransform(MediaInterface $media): void
193
    {
194
        parent::doTransform($media);
195
196
        if ($media->getBinaryContent() instanceof UploadedFile) {
197
            $fileName = $media->getBinaryContent()->getClientOriginalName();
198
        } elseif ($media->getBinaryContent() instanceof File) {
199
            $fileName = $media->getBinaryContent()->getFilename();
200
        } else {
201
            // Should not happen, FileProvider should throw an exception in that case
202
            return;
203
        }
204
205
        if (!in_array(strtolower(pathinfo($fileName, PATHINFO_EXTENSION)), $this->allowedExtensions)
206
            || !in_array($media->getBinaryContent()->getMimeType(), $this->allowedMimeTypes)) {
207
            return;
208
        }
209
210
        try {
211
            $image = $this->imagineAdapter->open($media->getBinaryContent()->getPathname());
212
        } catch (\RuntimeException $e) {
213
            $media->setProviderStatus(MediaInterface::STATUS_ERROR);
214
215
            return;
216
        }
217
218
        $size = $image->getSize();
219
220
        $media->setWidth($size->getWidth());
221
        $media->setHeight($size->getHeight());
222
223
        $media->setProviderStatus(MediaInterface::STATUS_OK);
224
    }
225
}
226