Completed
Push — master ( f6198e...300d99 )
by Paweł
53:20
created

MediaFactory::findImage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 1
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Content Bundle.
7
 *
8
 * Copyright 2016 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2016 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\ContentBundle\Factory\ORM;
18
19
use SWP\Bundle\ContentBundle\Doctrine\ImageRepositoryInterface;
20
use SWP\Bundle\ContentBundle\Model\ArticleMedia;
21
use SWP\Bundle\ContentBundle\Model\File;
22
use SWP\Bundle\ContentBundle\Model\Image;
23
use SWP\Bundle\ContentBundle\Model\ImageRendition;
24
use SWP\Bundle\ContentBundle\Factory\MediaFactoryInterface;
25
use SWP\Bundle\ContentBundle\Model\ArticleInterface;
26
use SWP\Bundle\ContentBundle\Model\ArticleMediaInterface;
27
use SWP\Bundle\ContentBundle\Model\FileInterface;
28
use SWP\Bundle\ContentBundle\Model\ImageInterface;
29
use SWP\Bundle\ContentBundle\Model\ImageRenditionInterface;
30
use SWP\Component\Bridge\Model\ItemInterface;
31
use SWP\Component\Bridge\Model\Rendition;
32
use SWP\Component\Storage\Factory\FactoryInterface;
33
use Symfony\Component\HttpFoundation\File\UploadedFile;
34
35
class MediaFactory implements MediaFactoryInterface
36
{
37
    /**
38
     * @var ImageRepositoryInterface
39
     */
40
    protected $imageRepository;
41
42
    /**
43
     * @var FactoryInterface
44
     */
45
    protected $factory;
46
47
    /**
48
     * @var FactoryInterface
49
     */
50
    protected $imageFactory;
51
52
    /**
53 11
     * @var FactoryInterface
54
     */
55
    protected $fileFactory;
56
57 11
    /**
58 11
     * MediaFactory constructor.
59 11
     *
60
     * @param ImageRepositoryInterface $imageRepository
61
     * @param FactoryInterface         $factory
62
     * @param FactoryInterface         $imageFactory
63
     * @param FactoryInterface         $fileFactory
64
     */
65
    public function __construct(
66
        ImageRepositoryInterface $imageRepository,
67
        FactoryInterface $factory,
68
        FactoryInterface $imageFactory,
69
        FactoryInterface $fileFactory
70
    ) {
71
        $this->imageRepository = $imageRepository;
72
        $this->factory = $factory;
73
        $this->imageFactory = $imageFactory;
74
        $this->fileFactory = $fileFactory;
75
    }
76
77
    public function create(ArticleInterface $article, string $key, ItemInterface $item): ArticleMediaInterface
78
    {
79
        $articleMedia = $this->factory->create();
80
        $articleMedia->setArticle($article);
81
        $articleMedia->setFromItem($item);
82
        $articleMedia = $this->createImageMedia($articleMedia, $key, $item);
83
84
        return $articleMedia;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function createMediaAsset(UploadedFile $uploadedFile, string $assetId): FileInterface
91
    {
92
        $asset = $this->getProperObject($uploadedFile);
93
        $asset->setAssetId($assetId);
94
        $asset->setFileExtension($uploadedFile->guessClientExtension());
95
96
        return $asset;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function createImageRendition(
103
        ImageInterface $image,
104
        ArticleMediaInterface $articleMedia,
105
        string $key, Rendition $rendition
106
    ): ImageRenditionInterface {
107
        $imageRendition = new ImageRendition();
108
        $imageRendition->setImage($image);
109
        $imageRendition->setMedia($articleMedia);
110
        $imageRendition->setHeight($rendition->getHeight());
111
        $imageRendition->setWidth($rendition->getWidth());
112
        $imageRendition->setName($key);
113
114
        return $imageRendition;
115
    }
116
117
    /**
118
     * Handle Article Media with Image (add renditions, set mimetype etc.).
119
     *
120
     * @param ArticleMedia  $articleMedia
121
     * @param string        $key          unique key shared between media and image rendition
122
     * @param ItemInterface $item
123
     *
124
     * @return ArticleMedia
125
     */
126
    protected function createImageMedia(ArticleMedia $articleMedia, string $key, ItemInterface $item)
127
    {
128
        if (0 === $item->getRenditions()->count()) {
129
            return $articleMedia;
130
        }
131
132
        $originalRendition = $item->getRenditions()['original'];
133
        $articleMedia->setMimetype($originalRendition->getMimetype());
134
        $articleMedia->setKey($key);
135
        $image = $this->findImage($originalRendition->getMedia());
136
        $articleMedia->setImage($image);
0 ignored issues
show
Bug introduced by
It seems like $image defined by $this->findImage($originalRendition->getMedia()) on line 135 can be null; however, SWP\Bundle\ContentBundle...rticleMedia::setImage() 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...
137
        foreach ($item->getRenditions() as $key => $rendition) {
138
            $image = $this->findImage($rendition->getMedia());
139
            if (null === $image) {
140
                continue;
141
            }
142
143
            $imageRendition = $this->createImageRendition($image, $articleMedia, $key, $rendition);
144
            $this->imageRepository->persist($imageRendition);
0 ignored issues
show
Documentation introduced by
$imageRendition is of type object<SWP\Bundle\Conten...mageRenditionInterface>, but the function expects a object<SWP\Component\Sto...l\PersistableInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
145
146
            $articleMedia->addRendition($imageRendition);
0 ignored issues
show
Compatibility introduced by
$imageRendition of type object<SWP\Bundle\Conten...mageRenditionInterface> is not a sub-type of object<SWP\Bundle\Conten...e\Model\ImageRendition>. It seems like you assume a concrete implementation of the interface SWP\Bundle\ContentBundle...ImageRenditionInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
147
        }
148
149
        return $articleMedia;
150
    }
151
152
    private function findImage(string $mediaId)
153
    {
154
        return $this->imageRepository
155
            ->findImageByAssetId(ArticleMedia::handleMediaId($mediaId));
156
    }
157
158
    protected function getProperObject(UploadedFile $uploadedFile)
159
    {
160
        if (in_array(exif_imagetype($uploadedFile->getRealPath()), [
161
            IMAGETYPE_GIF,
162
            IMAGETYPE_JPEG,
163
            IMAGETYPE_PNG,
164
            IMAGETYPE_BMP,
165
        ])) {
166
            return $this->imageFactory->create();
167
        }
168
169
        return $this->fileFactory->create();
170
    }
171
}
172