Completed
Push — master ( 1fe58d...1d38e8 )
by
unknown
07:43
created

YouTubeProvider   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 182
Duplicated Lines 6.59 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 24
lcom 1
cbo 3
dl 12
loc 182
ccs 0
cts 105
cp 0
rs 10
c 1
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A buildProviderCreateForm() 0 4 1
A buildProviderEditForm() 0 4 1
B update() 0 22 5
A refreshThumbnail() 0 10 1
A getThumbnailUrlByYouTubeId() 0 13 2
A getDataByYouTubeId() 12 12 2
B parseYouTubeId() 0 24 5
A getIcon() 0 4 1
A getTitle() 0 4 1
A getType() 0 4 1
A getEmbedTemplate() 0 4 1
A supportsDownload() 0 4 1
A supportsEmbed() 0 4 1
A supportsImage() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
11
class YouTubeProvider extends AbstractProvider implements ProviderInterface
12
{
13
    const URL_OEMBED = 'http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=%s&format=json';
14
    const URL_IMAGE_MAX_RES = 'https://i.ytimg.com/vi/%s/maxresdefault.jpg';
15
    const URL_IMAGE_HQ = 'https://i.ytimg.com/vi/%s/hqdefault.jpg';
16
17
    /**
18
     * @param FormMapper $formMapper
19
     */
20
    public function buildProviderCreateForm(FormMapper $formMapper)
21
    {
22
        $formMapper->add('providerReference', TextType::class, ['label' => 'YouTube ID']);
23
    }
24
25
    /**
26
     * @param FormMapper $formMapper
27
     */
28
    public function buildProviderEditForm(FormMapper $formMapper)
29
    {
30
        $formMapper->add('providerReference', TextType::class, ['label' => 'YouTube ID']);
31
    }
32
33
    /**
34
     * @param Media $media
35
     * @throws \Exception
36
     */
37
    public function update(Media $media)
38
    {
39
        $currentYoutubeId = $media->getProviderReference();
40
        $media->setProviderReference($this->parseYouTubeId($media->getProviderReference()));
41
42
        if ($currentYoutubeId !== $media->getProviderReference()) {
43
            $data = $this->getDataByYouTubeId($media->getProviderReference());
44
45
            if (empty($media->getTitle())) {
46
                $media->setTitle($data['title']);
47
            }
48
            if (empty($media->getAuthorName())) {
49
                $media->setAuthorName($data['author_name']);
50
            }
51
52
            if (empty($media->getImage())) {
53
                $this->refreshThumbnail($media);
54
            }
55
        }
56
57
        parent::update($media);
58
    }
59
60
    /**
61
     * @param Media $media
62
     */
63
    public function refreshThumbnail(Media $media)
64
    {
65
        $filename = sprintf('%s_%d.%s', sha1($media->getProviderReference()), time(), 'jpg');
66
        $thumbnailUrl = $this->getThumbnailUrlByYouTubeId($media->getProviderReference());
67
        $this->getFilesystem()->write(
68
            $filename,
69
            file_get_contents($thumbnailUrl)
70
        );
71
        $media->setImage($filename);
72
    }
73
74
    /**
75
     * @param string $id
76
     * @return string
77
     */
78
    public function getThumbnailUrlByYouTubeId($id)
79
    {
80
        // try to get max res image (only available for 720P videos)
81
        $urlMaxRes = sprintf(self::URL_IMAGE_MAX_RES, $id);
82
        stream_context_set_default(['http' => ['method' => 'HEAD']]);
83
        $headers = get_headers($urlMaxRes);
84
        stream_context_set_default(['http' => ['method' => 'GET']]);
85
        if ((int)substr($headers[0], 9, 3) === Response::HTTP_OK) {
86
            return $urlMaxRes;
87
        }
88
89
        return sprintf(self::URL_IMAGE_HQ, $id); // this one always exists
90
    }
91
92
    /**
93
     * @param $id
94
     * @return mixed
95
     * @throws \Exception
96
     */
97 View Code Duplication
    protected function getDataByYouTubeId($id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98
    {
99
        $this->disableErrorHandler();
100
        $data = json_decode(file_get_contents(sprintf(self::URL_OEMBED, $id)), true);
101
        $this->restoreErrorHandler();
102
103
        if (empty($data['title'])) {
104
            throw new \Exception(sprintf('Could not get data from YouTube for id "%s", is the id correct?', $id));
105
        }
106
107
        return $data;
108
    }
109
110
    /**
111
     * @param $value
112
     * @return string
113
     * @throws \Exception
114
     */
115
    protected function parseYouTubeId($value)
116
    {
117
        if (strpos($value, 'youtube.com')) {
118
            $url = parse_url($value);
119
            if (empty($url['query'])) {
120
                throw new \Exception('The supplied URL does not look like a Youtube URL');
121
            }
122
            parse_str($url['query'], $params);
123
            if (empty($params['v'])) {
124
                throw new \Exception('The supplied URL does not look like a Youtube URL');
125
            }
126
127
            return $params['v'];
128
        }
129
130
        if (strpos($value, 'youtu.be')) {
131
            $url = parse_url($value);
132
            $id = substr($url['path'], 1);
133
134
            return $id;
135
        }
136
137
        return $value;
138
    }
139
140
    /**
141
     * @return string
142
     */
143
    public function getIcon()
144
    {
145
        return 'youtube-play';
146
    }
147
148
    /**
149
     * @return string
150
     */
151
    public function getTitle()
152
    {
153
        return 'YouTube Video';
154
    }
155
156
    public function getType()
157
    {
158
        return 'youtube';
159
    }
160
161
    /**
162
     * @return string
163
     */
164
    public function getEmbedTemplate()
165
    {
166
        return 'MediaMonksSonataMediaBundle:Provider:youtube_embed.html.twig';
167
    }
168
169
    /**
170
     * @return bool
171
     */
172
    public function supportsDownload()
173
    {
174
        return false;
175
    }
176
177
    /**
178
     * @return bool
179
     */
180
    public function supportsEmbed()
181
    {
182
        return true;
183
    }
184
185
    /**
186
     * @return bool
187
     */
188
    public function supportsImage()
189
    {
190
        return true;
191
    }
192
}
193