Completed
Push — master ( 26278b...61e1ff )
by
unknown
04:27
created

YouTubeProvider::buildEditForm()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 0
cts 34
cp 0
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 25
nc 1
nop 1
crap 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A YouTubeProvider::buildProviderCreateForm() 0 4 1
1
<?php
2
3
namespace MediaMonks\SonataMediaBundle\Provider;
4
5
use MediaMonks\SonataMediaBundle\Entity\Media;
6
use MediaMonks\SonataMediaBundle\Model\MediaInterface;
7
use Sonata\AdminBundle\Form\FormMapper;
8
use Symfony\Component\Form\Extension\Core\Type\TextType;
9
use Symfony\Component\HttpFoundation\Response;
10
use Symfony\Component\Validator\Constraints as Constraint;
11
12
class YouTubeProvider extends ImageProvider implements ProviderInterface
13
{
14
    const URL_OEMBED = 'http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=%s&format=json';
15
    const URL_IMAGE_MAX_RES = 'https://i.ytimg.com/vi/%s/maxresdefault.jpg';
16
    const URL_IMAGE_HQ = 'https://i.ytimg.com/vi/%s/hqdefault.jpg';
17
18
    /**
19
     * @param FormMapper $formMapper
20
     */
21
    public function buildProviderEditForm(FormMapper $formMapper)
22
    {
23
        $formMapper->add('providerReference', TextType::class, ['label' => 'YouTube ID']);
24
    }
25
26
    /**
27
     * @param FormMapper $formMapper
28
     */
29
    public function buildProviderCreateForm(FormMapper $formMapper)
30
    {
31
        $formMapper->add('providerReference', TextType::class, ['label' => 'YouTube ID']);
32
    }
33
34
    /**
35
     * @param Media $media
36
     * @throws \Exception
37
     */
38
    public function update(Media $media)
39
    {
40
        $currentYoutubeId = $media->getProviderReference();
41
        $media->setProviderReference($this->parseYouTubeId($media->getProviderReference()));
42
43
        if ($currentYoutubeId !== $media->getProviderReference()) {
44
            $data = $this->getDataByYouTubeId($media->getProviderReference());
45
46
            if (empty($media->getTitle())) {
47
                $media->setTitle($data['title']);
48
            }
49
            if (empty($media->getAuthorName())) {
50
                $media->setAuthorName($data['author_name']);
51
            }
52
53
            if (empty($media->getImage())) {
54
                $this->refreshThumbnail($media);
55
            }
56
        }
57
58
        if (!is_null($media->getBinaryContent())) {
59
            $this->handleFileUpload($media);
60
        }
61
    }
62
63
    /**
64
     * @param MediaInterface $media
65
     */
66
    public function refreshThumbnail(MediaInterface $media)
67
    {
68
        $filename = sprintf('%s_%d.%s', sha1($media->getProviderReference()), time(), 'jpg');
69
        $thumbnailUrl = $this->getThumbnailUrlByYouTubeId($media->getProviderReference());
70
        $this->getFilesystem()->write(
71
            $filename,
72
            file_get_contents($thumbnailUrl)
73
        );
74
        $media->setImage($filename);
75
    }
76
77
    /**
78
     * @param string $id
79
     * @return string
80
     */
81
    public function getThumbnailUrlByYouTubeId($id)
82
    {
83
        // try to get max res image (only available for 720P videos)
84
        $urlMaxRes = sprintf(self::URL_IMAGE_MAX_RES, $id);
85
        stream_context_set_default(['http' => ['method' => 'HEAD']]);
86
        $headers = get_headers($urlMaxRes);
87
        stream_context_set_default(['http' => ['method' => 'GET']]);
88
        if ((int)substr($headers[0], 9, 3) === Response::HTTP_OK) {
89
            return $urlMaxRes;
90
        }
91
92
        return sprintf(self::URL_IMAGE_HQ, $id); // this one always exists
93
    }
94
95
    /**
96
     * @param $id
97
     * @return mixed
98
     * @throws \Exception
99
     */
100
    protected function getDataByYouTubeId($id)
101
    {
102
        set_error_handler(
103
            function () {
104
            }
105
        );
106
        $data = json_decode(file_get_contents(sprintf(self::URL_OEMBED, $id)), true);
107
        restore_error_handler();
108
109
        if (empty($data['title'])) {
110
            throw new \Exception(sprintf('Could not get data from YouTube for id "%s", is the id correct?', $id));
111
        }
112
113
        return $data;
114
    }
115
116
    /**
117
     * @param $value
118
     * @return string
119
     * @throws \Exception
120
     */
121
    protected function parseYouTubeId($value)
122
    {
123
        if (strpos($value, 'youtube.com')) {
124
            $url = parse_url($value);
125
            if (empty($url['query'])) {
126
                throw new \Exception('The supplied URL does not look like a Youtube URL');
127
            }
128
            parse_str($url['query'], $params);
129
            if (empty($params['v'])) {
130
                throw new \Exception('The supplied URL does not look like a Youtube URL');
131
            }
132
133
            return $params['v'];
134
        }
135
136
        if (strpos($value, 'youtu.be')) {
137
            $url = parse_url($value);
138
            $id = substr($url['path'], 1);
139
140
            return $id;
141
        }
142
143
        return $value;
144
    }
145
146
    /**
147
     * @param MediaInterface $media
148
     * @param array $options
149
     * @return array
150
     */
151
    public function toArray(MediaInterface $media, array $options = [])
152
    {
153
        return parent::toArray($media, $options) + [
154
                'id'   => $media->getProviderReference(),
155
            ];
156
    }
157
158
    /**
159
     * @return string
160
     */
161
    public function getIcon()
162
    {
163
        return 'youtube-play';
164
    }
165
166
    /**
167
     * @return string
168
     */
169
    public function getName()
170
    {
171
        return 'YouTube Video';
172
    }
173
174
    public function getTypeName()
175
    {
176
        return 'youtube';
177
    }
178
179
    /**
180
     * @return string
181
     */
182
    public function getMediaTemplate()
183
    {
184
        return 'MediaMonksSonataMediaBundle:Provider:youtube_media.html.twig';
185
    }
186
}
187