Completed
Pull Request — master (#591)
by Richard
16:26
created

YouTube   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Test Coverage

Coverage 78.72%

Importance

Changes 0
Metric Value
eloc 83
dl 0
loc 125
ccs 37
cts 47
cp 0.7872
rs 10
c 0
b 0
f 0
wmc 12

2 Methods

Rating   Name   Duplication   Size   Complexity  
B registerExtensionProcessing() 0 53 10
A getDhtmlEditorSupport() 0 43 2
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
namespace Xoops\Core\Text\Sanitizer\Extensions;
13
14
use Xoops\Core\Text\Sanitizer;
15
use Xoops\Core\Text\Sanitizer\ExtensionAbstract;
16
17
/**
18
 * YouTube extension
19
 *
20
 * @category  Sanitizer
21
 * @package   Xoops\Core\Text
22
 * @author    Taiwen Jiang <[email protected]>
23
 * @copyright 2000-2019 XOOPS Project (https://xoops.org)
24
 * @license   GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
25
 */
26
class YouTube extends ExtensionAbstract
27
{
28
    /**
29
     * @var array default configuration values
30
     */
31
    protected static $defaultConfiguration = [
32
        'enabled' => true,
33
        'enable_youtube_entry' => true,  // false to disable entry button in editor, existing content will still play
34
        'template' => '<div class="embed-responsive %4$s">
35
            <iframe class="embed-responsive-item" width="%2$d" height="%3$d" src="https://www.youtube.com/embed/%1$s" frameborder="0" allowfullscreen></iframe>
36
            </div>',
37
        'width'  => "640",
38
        'height' => "385",
39
    ];
40
41
    /**
42
     * Provide button and javascript code used by the DhtmlTextArea
43
     *
44
     * @param string $textAreaId dom element id
45
     *
46
     * @return string[] editor button as HTML, supporting javascript
47
     */
48 3
    public function getDhtmlEditorSupport($textAreaId)
49
    {
50 3
        if (false === $this->config['enable_youtube_entry']) {
51
            return parent::getDhtmlEditorSupport($textAreaId);
52
        }
53
54 3
        $buttonCode = $this->getEditorButtonHtml(
55 3
            $textAreaId,
56 3
            'fa fa-fw fa-youtube',
57 3
            \XoopsLocale::YOUTUBE,
58 3
            'xoopsCodeYoutube',
59 3
            \XoopsLocale::YOUTUBE_URL,
60 3
            \XoopsLocale::HEIGHT,
61 3
            \XoopsLocale::WIDTH
62
        );
63
64
        $javascript = <<<EOH
65
66
            function xoopsCodeYoutube(id, enterFlashPhrase, enterFlashHeightPhrase, enterFlashWidthPhrase)
67
            {
68
                var selection = xoopsGetSelect(id);
69
                if (selection.length > 0) {
70
                    var text = selection;
71
                } else {
72
                    var text = prompt(enterFlashPhrase, "");
73
                }
74
                var domobj = xoopsGetElementById(id);
75
                if ( text.length > 0 ) {
76
                    var text2 = prompt(enterFlashWidthPhrase, "640");
77
                    var text3 = prompt(enterFlashHeightPhrase, "385");
78
                    var result = '[youtube url="' + text + '"';
79
                    if ( text2.length > 0) {
80
                        result += ' width="' + text2 + '" height="' + text3 + '"';
81
                    }
82
                    result += " /]";
83
                    xoopsInsertText(domobj, result);
84
                }
85
                domobj.focus();
86
            }
87
88
EOH;
89
90 3
        return [$buttonCode, $javascript];
91
    }
92
93
    /**
94
     * Register extension with the supplied sanitizer instance
95
     *
96
     * @return void
97
     */
98 20
    public function registerExtensionProcessing()
99
    {
100 20
        $this->shortcodes->addShortcode(
101 20
            'youtube',
102
            function ($attributes, $content, $tagName) {
0 ignored issues
show
Unused Code introduced by
The parameter $tagName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

102
            function ($attributes, $content, /** @scrutinizer ignore-unused */ $tagName) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
103 1
                if (array_key_exists(0, $attributes) && '=' === substr($attributes[0], 0, 1)) {
104 1
                    $args = ltrim($attributes[0], '=');
105 1
                    list($width, $height) = explode(',', $args);
106 1
                    $url = $content;
107
                } else {
108
                    $defaults = [
109 1
                        'url'    => trim($content),
110 1
                        'width'  => $this->config['width'],
111 1
                        'height' => $this->config['height'],
112
                    ];
113 1
                    $cleanAttributes = $this->shortcodes->shortcodeAttributes($defaults, $attributes);
114 1
                    $url = $cleanAttributes['url'];
115 1
                    $width = (int) $cleanAttributes['width'];
116 1
                    $height = (int) $cleanAttributes['height'];
117
                }
118
119
                // from: http://stackoverflow.com/questions/2936467/parse-youtube-video-id-using-preg-match/6382259#6382259
120
                $youtubeRegex = '%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)'
121 1
                    .'([^"&?/ ]{11})%i';
122
123 1
                if (preg_match($youtubeRegex, $url, $match)) {
124
                    $videoId = $match[1];
125 1
                } elseif (preg_match('%^[^"&?/ ]{11}$%', $url)) {
126 1
                    $videoId = $url;
127
                } else {
128
                    return ''; // giveup
129
                }
130
131
                switch ($width) {
132 1
                    case 4:
133
                        $height = 3;
134
                        break;
135 1
                    case 16:
136
                        $height = 9;
137
                        break;
138
                }
139
140 1
                $aspectRatio = $width/$height; // 16x9 = 1.777777778, 4x3 = 1.333333333
141 1
                $responsiveAspect = ($aspectRatio < 1.4) ? 'embed-responsive-4by3' : 'embed-responsive-16by9';
142 1
                if ($width < 17 && $height < 10) {
143
                    $scale = (int) 640 / $width;
144
                    $width = $width * $scale;
145
                    $height = $height * $scale;
146
                }
147
148 1
                $template = $this->config['template'];
149 1
                $newContent = sprintf($template, $videoId, $width, $height, $responsiveAspect);
150 1
                return $newContent;
151 20
            }
152
        );
153 20
    }
154
}
155