Completed
Pull Request — 1.5 (#767)
by Paweł
10:46
created

MediaFactory::getFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 3
nc 3
nop 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 Psr\Log\LoggerInterface;
20
use SWP\Bundle\ContentBundle\Manager\MediaManagerInterface;
21
use SWP\Bundle\ContentBundle\Model\ArticleMedia;
22
use SWP\Bundle\ContentBundle\Factory\MediaFactoryInterface;
23
use SWP\Bundle\ContentBundle\Model\ArticleInterface;
24
use SWP\Bundle\ContentBundle\Model\ArticleMediaInterface;
25
use SWP\Bundle\ContentBundle\Model\FileInterface;
26
use SWP\Bundle\ContentBundle\Model\ImageInterface;
27
use SWP\Bundle\ContentBundle\Provider\ORM\ArticleMediaAssetProviderInterface;
28
use SWP\Component\Bridge\Model\ItemInterface;
29
use SWP\Component\Bridge\Model\RenditionInterface;
30
use SWP\Component\Storage\Factory\FactoryInterface;
31
32
class MediaFactory implements MediaFactoryInterface
33
{
34
    /**
35
     * @var ArticleMediaAssetProviderInterface
36
     */
37
    protected $articleMediaAssetProvider;
38
39
    /**
40
     * @var FactoryInterface
41
     */
42
    protected $factory;
43
44
    /**
45
     * @var ImageRenditionFactoryInterface
46
     */
47
    protected $imageRenditionFactory;
48
49
    /**
50
     * @var MediaManagerInterface
51
     */
52
    protected $mediaManager;
53
54
    /**
55
     * @var LoggerInterface
56
     */
57
    private $logger;
58
59
    public function __construct(
60
        ArticleMediaAssetProviderInterface $articleMediaAssetProvider,
61
        FactoryInterface $factory,
62
        ImageRenditionFactoryInterface $imageRenditionFactory,
63
        MediaManagerInterface $mediaManager,
64
        LoggerInterface $logger
65
    ) {
66
        $this->articleMediaAssetProvider = $articleMediaAssetProvider;
67
        $this->factory = $factory;
68
        $this->imageRenditionFactory = $imageRenditionFactory;
69
        $this->mediaManager = $mediaManager;
70
        $this->logger = $logger;
71
    }
72
73
    public function create(ArticleInterface $article, string $key, ItemInterface $item): ArticleMediaInterface
74
    {
75
        $articleMedia = $this->factory->create();
76
        $articleMedia->setArticle($article);
77
        $articleMedia->setFromItem($item);
78
79
        if (ItemInterface::TYPE_PICTURE === $item->getType()) {
80
            return $this->createImageMedia($articleMedia, $key, $item);
81
        }
82
83
        return $this->createFileMedia($articleMedia, $key, $item);
84
    }
85
86
    public function createEmpty(): ArticleMediaInterface
87
    {
88
        return $this->factory->create();
89
    }
90
91
    protected function createFileMedia(ArticleMedia $articleMedia, string $key, ItemInterface $item): ArticleMediaInterface
92
    {
93
        if (0 === $item->getRenditions()->count()) {
94
            return $articleMedia;
95
        }
96
97
        $originalRendition = $this->findOriginalRendition($item);
98
        $articleMedia->setMimetype($originalRendition->getMimetype());
99
        $articleMedia->setKey($key);
100
        $file = $this->articleMediaAssetProvider->getFile($originalRendition);
101
        $articleMedia->setFile($this->getFile($originalRendition, $file));
102
103
        return $articleMedia;
104
    }
105
106
    protected function createImageMedia(ArticleMedia $articleMedia, string $key, ItemInterface $item): ArticleMediaInterface
107
    {
108
        if (0 === $item->getRenditions()->count()) {
109
            return $articleMedia;
110
        }
111
112
        $originalRendition = $this->findOriginalRendition($item);
113
        $articleMedia->setMimetype($originalRendition->getMimetype());
114
        $articleMedia->setKey($key);
115
116
        /** @var ImageInterface $image */
117
        $image = $this->getFile($originalRendition, $this->articleMediaAssetProvider->getImage($originalRendition));
118
        $articleMedia->setImage($image);
119
120
        foreach ($item->getRenditions() as $rendition) {
121
            $image = $this->getFile($rendition, $this->articleMediaAssetProvider->getImage($rendition));
122
            if (null === $image) {
123
                continue;
124
            }
125
126
            $articleMedia->addRendition($this->imageRenditionFactory->createWith($articleMedia, $image, $rendition));
127
        }
128
129
        return $articleMedia;
130
    }
131
132
    private function getFile(RenditionInterface $rendition, ?FileInterface $file): ?FileInterface
133
    {
134
        if (null !== $file) {
135
            return $file;
136
        }
137
138
        try {
139
            return $this->downloadAsset($rendition->getHref(), $rendition->getMedia(), $rendition->getMimetype());
140
        } catch (\Exception $e) {
141
            $this->logger->error(\sprintf('%s: %s', $rendition->getHref(), $e->getMessage()));
142
143
            return null;
144
        }
145
    }
146
147
    private function downloadAsset(string $url, string $media, string $mimetype): FileInterface
148
    {
149
        $this->logger->info(\sprintf('Downloading %s for media %s', $url, $media));
150
        $uploadedFile = $this->mediaManager->downloadFile($url, $media, $mimetype);
151
        $file = $this->mediaManager->handleUploadedFile($uploadedFile, $media);
152
153
        if ($file instanceof ImageInterface) {
154
            list($width, $height) = \getimagesize($uploadedFile->getRealPath());
155
            $file->setWidth($width);
156
            $file->setHeight($height);
157
        }
158
159
        return $file;
160
    }
161
162
    private function findOriginalRendition(ItemInterface $item): RenditionInterface
163
    {
164
        return $item->getRenditions()->filter(
165
            function (RenditionInterface $rendition) {
166
                return 'original' === $rendition->getName();
167
            }
168
        )->first();
169
    }
170
}
171