YouTubeProvider::getHelperProperties()   B
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 141

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 141
rs 8
c 0
b 0
f 0
cc 3
nc 4
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 Buzz\Browser;
17
use Gaufrette\Filesystem;
18
use Sonata\MediaBundle\CDN\CDNInterface;
19
use Sonata\MediaBundle\Generator\GeneratorInterface;
20
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
21
use Sonata\MediaBundle\Model\MediaInterface;
22
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
23
use Symfony\Component\HttpFoundation\RedirectResponse;
24
25
/**
26
 * @final since sonata-project/media-bundle 3.21.0
27
 */
28
class YouTubeProvider extends BaseVideoProvider
29
{
30
    /**
31
     * @var bool
32
     */
33
    protected $html5;
34
35
    /**
36
     * @param string                   $name
37
     * @param MetadataBuilderInterface $metadata
38
     * @param bool                     $html5
39
     */
40
    public function __construct($name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, Browser $browser, ?MetadataBuilderInterface $metadata = null, $html5 = false)
41
    {
42
        parent::__construct($name, $filesystem, $cdn, $pathGenerator, $thumbnail, $browser, $metadata);
43
        $this->html5 = $html5;
44
    }
45
46
    public function getProviderMetadata()
47
    {
48
        return new Metadata(
49
            $this->getName(),
50
            $this->getName().'.description',
51
            null,
52
            'SonataMediaBundle',
53
            ['class' => 'fa fa-youtube']
54
        );
55
    }
56
57
    public function getHelperProperties(MediaInterface $media, $format, $options = [])
58
    {
59
        // Override html5 value if $options['html5'] is a boolean
60
        if (!isset($options['html5'])) {
61
            $options['html5'] = $this->html5;
62
        }
63
64
        // documentation : http://code.google.com/apis/youtube/player_parameters.html
65
66
        $default_player_url_parameters = [
67
            //Values: 0 or 1. Default is 1. Sets whether the player should load related
68
            // videos once playback of the initial video starts. Related videos are
69
            // displayed in the "genie menu" when the menu button is pressed. The player
70
            // search functionality will be disabled if rel is set to 0.
71
            'rel' => 0,
72
73
            // Values: 0 or 1. Default is 0. Sets whether or not the initial video will autoplay
74
            // when the player loads.
75
            'autoplay' => 0,
76
77
            // Values: 0 or 1. Default is 0. In the case of a single video player, a setting of 1
78
            // will cause the player to play the initial video again and again. In the case of a
79
            // playlist player (or custom player), the player will play the entire playlist and
80
            // then start again at the first video.
81
            'loop' => 0,
82
83
            // Values: 0 or 1. Default is 0. Setting this to 1 will enable the Javascript API.
84
            // For more information on the Javascript API and how to use it, see the JavaScript
85
            // API documentation.
86
            'enablejsapi' => 0,
87
88
            // Value can be any alphanumeric string. This setting is used in conjunction with the
89
            // JavaScript API. See the JavaScript API documentation for details.
90
            'playerapiid' => null,
91
92
            // Values: 0 or 1. Default is 0. Setting to 1 will disable the player keyboard controls.
93
            // Keyboard controls are as follows:
94
            //      Spacebar: Play / Pause
95
            //      Arrow Left: Jump back 10% in the current video
96
            //      Arrow Right: Jump ahead 10% in the current video
97
            //      Arrow Up: Volume up
98
            //      Arrow Down: Volume Down
99
            'disablekb' => 0,
100
101
            // Values: 0 or 1. Default is 0. Setting to 1 enables the "Enhanced Genie Menu". This
102
            // behavior causes the genie menu (if present) to appear when the user's mouse enters
103
            // the video display area, as opposed to only appearing when the menu button is pressed.
104
            'egm' => 0,
105
106
            // Values: 0 or 1. Default is 0. Setting to 1 enables a border around the entire video
107
            // player. The border's primary color can be set via the color1 parameter, and a
108
            // secondary color can be set by the color2 parameter.
109
            'border' => 0,
110
111
            // Values: Any RGB value in hexadecimal format. color1 is the primary border color, and
112
            // color2 is the video control bar background color and secondary border color.
113
            'color1' => null,
114
            'color2' => null,
115
116
            // Values: 0 or 1. Default is 0. Setting to 1 enables the fullscreen button. This has no
117
            // effect on the Chromeless Player. Note that you must include some extra arguments to
118
           // your embed code for this to work.
119
            'fs' => 1,
120
121
            // Values: A positive integer. This parameter causes the player to begin playing the video
122
            // at the given number of seconds from the start of the video. Note that similar to the
123
            // seekTo function, the player will look for the closest keyframe to the time you specify.
124
            // This means sometimes the play head may seek to just before the requested time, usually
125
            // no more than ~2 seconds
126
            'start' => 0,
127
128
            // Values: 0 or 1. Default is 0. Setting to 1 enables HD playback by default. This has no
129
            // effect on the Chromeless Player. This also has no effect if an HD version of the video
130
            // is not available. If you enable this option, keep in mind that users with a slower
131
            // connection may have an sub-optimal experience unless they turn off HD. You should ensure
132
            // your player is large enough to display the video in its native resolution.
133
            'hd' => 1,
134
135
            // Values: 0 or 1. Default is 1. Setting to 0 disables the search box from displaying when
136
            // the video is minimized. Note that if the rel parameter is set to 0 then the search box
137
            // will also be disabled, regardless of the value of showsearch.
138
            'showsearch' => 0,
139
140
            // Values: 0 or 1. Default is 1. Setting to 0 causes the player to not display information
141
            // like the video title and rating before the video starts playing.
142
            'showinfo' => 0,
143
144
            // Values: 1 or 3. Default is 1. Setting to 1 will cause video annotations to be shown by
145
            // default, whereas setting to 3 will cause video annotation to not be shown by default.
146
            'iv_load_policy' => 1,
147
148
            // Values: 1. Default is based on user preference. Setting to 1 will cause closed captions
149
            // to be shown by default, even if the user has turned captions off.
150
            'cc_load_policy' => 1,
151
152
            // Values: 'window' or 'opaque' or 'transparent'.
153
            // When wmode=window, the Flash movie is not rendered in the page.
154
            // When wmode=opaque, the Flash movie is rendered as part of the page.
155
            // When wmode=transparent, the Flash movie is rendered as part of the page.
156
            'wmode' => 'window',
157
        ];
158
159
        $default_player_parameters = [
160
            // Values: 0 or 1. Default is 0. Setting to 1 enables a border around the entire video
161
            // player. The border's primary color can be set via the color1 parameter, and a
162
            // secondary color can be set by the color2 parameter.
163
            'border' => $default_player_url_parameters['border'],
164
165
            // Values: 'allowfullscreen' or empty. Default is 'allowfullscreen'. Setting to empty value disables
166
            //  the fullscreen button.
167
            'allowFullScreen' => '1' === $default_player_url_parameters['fs'] ? true : false,
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of '1' (string) and $default_player_url_parameters['fs'] (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
168
169
            // The allowScriptAccess parameter in the code is needed to allow the player SWF to call
170
            // functions on the containing HTML page, since the player is hosted on a different domain
171
            // from the HTML page.
172
            'allowScriptAccess' => $options['allowScriptAccess'] ?? 'always',
173
174
            // Values: 'window' or 'opaque' or 'transparent'.
175
            // When wmode=window, the Flash movie is not rendered in the page.
176
            // When wmode=opaque, the Flash movie is rendered as part of the page.
177
            // When wmode=transparent, the Flash movie is rendered as part of the page.
178
            'wmode' => $default_player_url_parameters['wmode'],
179
        ];
180
181
        $player_url_parameters = array_merge($default_player_url_parameters, $options['player_url_parameters'] ?? []);
182
183
        $box = $this->getBoxHelperProperties($media, $format, $options);
184
185
        $player_parameters = array_merge($default_player_parameters, $options['player_parameters'] ?? [], [
186
            'width' => $box->getWidth(),
187
            'height' => $box->getHeight(),
188
        ]);
189
190
        $params = [
191
            'html5' => $options['html5'],
192
            'player_url_parameters' => http_build_query($player_url_parameters),
193
            'player_parameters' => $player_parameters,
194
        ];
195
196
        return $params;
197
    }
198
199
    public function updateMetadata(MediaInterface $media, $force = false): void
200
    {
201
        $url = sprintf('https://www.youtube.com/oembed?url=%s&format=json', $this->getReferenceUrl($media));
202
203
        try {
204
            $metadata = $this->getMetadata($media, $url);
205
        } catch (\RuntimeException $e) {
206
            $media->setEnabled(false);
207
            $media->setProviderStatus(MediaInterface::STATUS_ERROR);
208
209
            return;
210
        }
211
212
        $media->setProviderMetadata($metadata);
213
214
        if ($force) {
215
            $media->setName($metadata['title']);
216
            $media->setAuthorName($metadata['author_name']);
217
        }
218
219
        $media->setHeight($metadata['height']);
220
        $media->setWidth($metadata['width']);
221
        $media->setContentType('video/x-flv');
222
    }
223
224
    public function getDownloadResponse(MediaInterface $media, $format, $mode, array $headers = [])
225
    {
226
        return new RedirectResponse($this->getReferenceUrl($media), 302, $headers);
227
    }
228
229
    /**
230
     * Get provider reference url.
231
     *
232
     * @return string
233
     */
234
    public function getReferenceUrl(MediaInterface $media)
235
    {
236
        return sprintf('https://www.youtube.com/watch?v=%s', $media->getProviderReference());
237
    }
238
239
    protected function fixBinaryContent(MediaInterface $media): void
240
    {
241
        if (!$media->getBinaryContent()) {
242
            return;
243
        }
244
245
        if (11 === \strlen($media->getBinaryContent())) {
246
            return;
247
        }
248
249
        if (preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\#\?&\"'>]+)/", $media->getBinaryContent(), $matches)) {
250
            $media->setBinaryContent($matches[1]);
251
        }
252
    }
253
254
    protected function doTransform(MediaInterface $media): void
255
    {
256
        $this->fixBinaryContent($media);
257
258
        if (!$media->getBinaryContent()) {
259
            return;
260
        }
261
262
        $media->setProviderName($this->name);
263
        $media->setProviderStatus(MediaInterface::STATUS_OK);
264
        $media->setProviderReference($media->getBinaryContent());
265
266
        $this->updateMetadata($media, true);
267
    }
268
}
269