xref: /plugin/vshare/syntax/video.php (revision b82f24af674525b493dac939915358a71279a32e)
1*b82f24afSAndreas Gohr<?php
2*b82f24afSAndreas Gohr
3*b82f24afSAndreas Gohr/**
4*b82f24afSAndreas Gohr * Easily embed videos from various Video Sharing sites
5*b82f24afSAndreas Gohr *
6*b82f24afSAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7*b82f24afSAndreas Gohr * @author     Andreas Gohr <andi@splitbrain.org>
8*b82f24afSAndreas Gohr */
9*b82f24afSAndreas Gohrclass syntax_plugin_vshare_video extends DokuWiki_Syntax_Plugin
10*b82f24afSAndreas Gohr{
11*b82f24afSAndreas Gohr    protected $sites;
12*b82f24afSAndreas Gohr
13*b82f24afSAndreas Gohr    protected $sizes = [
14*b82f24afSAndreas Gohr        'small' => [255, 143],
15*b82f24afSAndreas Gohr        'medium' => [425, 239],
16*b82f24afSAndreas Gohr        'large' => [520, 293],
17*b82f24afSAndreas Gohr        'full' => ['100%', ''],
18*b82f24afSAndreas Gohr        'half' => ['50%', ''],
19*b82f24afSAndreas Gohr    ];
20*b82f24afSAndreas Gohr
21*b82f24afSAndreas Gohr    protected $alignments = [
22*b82f24afSAndreas Gohr        0 => 'none',
23*b82f24afSAndreas Gohr        1 => 'right',
24*b82f24afSAndreas Gohr        2 => 'left',
25*b82f24afSAndreas Gohr        3 => 'center',
26*b82f24afSAndreas Gohr    ];
27*b82f24afSAndreas Gohr
28*b82f24afSAndreas Gohr    /**
29*b82f24afSAndreas Gohr     * Constructor.
30*b82f24afSAndreas Gohr     * Intitalizes the supported video sites
31*b82f24afSAndreas Gohr     */
32*b82f24afSAndreas Gohr    public function __construct()
33*b82f24afSAndreas Gohr    {
34*b82f24afSAndreas Gohr        $this->sites = helper_plugin_vshare::loadSites();
35*b82f24afSAndreas Gohr    }
36*b82f24afSAndreas Gohr
37*b82f24afSAndreas Gohr    /** @inheritdoc */
38*b82f24afSAndreas Gohr    public function getType()
39*b82f24afSAndreas Gohr    {
40*b82f24afSAndreas Gohr        return 'substition';
41*b82f24afSAndreas Gohr    }
42*b82f24afSAndreas Gohr
43*b82f24afSAndreas Gohr    /** @inheritdoc */
44*b82f24afSAndreas Gohr    public function getPType()
45*b82f24afSAndreas Gohr    {
46*b82f24afSAndreas Gohr        return 'block';
47*b82f24afSAndreas Gohr    }
48*b82f24afSAndreas Gohr
49*b82f24afSAndreas Gohr    /** @inheritdoc */
50*b82f24afSAndreas Gohr    public function getSort()
51*b82f24afSAndreas Gohr    {
52*b82f24afSAndreas Gohr        return 159;
53*b82f24afSAndreas Gohr    }
54*b82f24afSAndreas Gohr
55*b82f24afSAndreas Gohr    /** @inheritdoc */
56*b82f24afSAndreas Gohr    public function connectTo($mode)
57*b82f24afSAndreas Gohr    {
58*b82f24afSAndreas Gohr        $pattern = join('|', array_keys($this->sites));
59*b82f24afSAndreas Gohr        $this->Lexer->addSpecialPattern('\{\{\s?(?:' . $pattern . ')>[^}]*\}\}', $mode, 'plugin_vshare_video');
60*b82f24afSAndreas Gohr    }
61*b82f24afSAndreas Gohr
62*b82f24afSAndreas Gohr    /** @inheritdoc */
63*b82f24afSAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
64*b82f24afSAndreas Gohr    {
65*b82f24afSAndreas Gohr        $command = substr($match, 2, -2);
66*b82f24afSAndreas Gohr
67*b82f24afSAndreas Gohr        // title
68*b82f24afSAndreas Gohr        list($command, $title) = array_pad(explode('|', $command), 2, '');
69*b82f24afSAndreas Gohr        $title = trim($title);
70*b82f24afSAndreas Gohr
71*b82f24afSAndreas Gohr        // alignment
72*b82f24afSAndreas Gohr        $align = 0;
73*b82f24afSAndreas Gohr        if (substr($command, 0, 1) == ' ') $align += 1;
74*b82f24afSAndreas Gohr        if (substr($command, -1) == ' ') $align += 2;
75*b82f24afSAndreas Gohr        $command = trim($command);
76*b82f24afSAndreas Gohr
77*b82f24afSAndreas Gohr        // get site and video
78*b82f24afSAndreas Gohr        list($site, $vid) = explode('>', $command);
79*b82f24afSAndreas Gohr        if (!$this->sites[$site]) return null; // unknown site
80*b82f24afSAndreas Gohr        if (!$vid) return null; // no video!?
81*b82f24afSAndreas Gohr
82*b82f24afSAndreas Gohr        // what size?
83*b82f24afSAndreas Gohr        list($vid, $pstr) = array_pad(explode('?', $vid, 2), 2, '');
84*b82f24afSAndreas Gohr        parse_str($pstr, $userparams);
85*b82f24afSAndreas Gohr        list($width, $height) = $this->parseSize($userparams);
86*b82f24afSAndreas Gohr
87*b82f24afSAndreas Gohr        // get URL
88*b82f24afSAndreas Gohr        $url = $this->insertPlaceholders($this->sites[$site]['url'], $vid, $width, $height);
89*b82f24afSAndreas Gohr        list($url, $urlpstr) = array_pad(explode('?', $url, 2), 2, '');
90*b82f24afSAndreas Gohr        parse_str($urlpstr, $urlparams);
91*b82f24afSAndreas Gohr
92*b82f24afSAndreas Gohr        // merge parameters
93*b82f24afSAndreas Gohr        $params = array_merge($urlparams, $userparams);
94*b82f24afSAndreas Gohr        $url = $url . '?' . buildURLparams($params, '&');
95*b82f24afSAndreas Gohr
96*b82f24afSAndreas Gohr        return array(
97*b82f24afSAndreas Gohr            'site' => $site,
98*b82f24afSAndreas Gohr            'domain' => parse_url($url, PHP_URL_HOST),
99*b82f24afSAndreas Gohr            'video' => $vid,
100*b82f24afSAndreas Gohr            'url' => $url,
101*b82f24afSAndreas Gohr            'align' => $this->alignments[$align],
102*b82f24afSAndreas Gohr            'width' => $width,
103*b82f24afSAndreas Gohr            'height' => $height,
104*b82f24afSAndreas Gohr            'title' => $title,
105*b82f24afSAndreas Gohr        );
106*b82f24afSAndreas Gohr    }
107*b82f24afSAndreas Gohr
108*b82f24afSAndreas Gohr    /** @inheritdoc */
109*b82f24afSAndreas Gohr    public function render($mode, Doku_Renderer $R, $data)
110*b82f24afSAndreas Gohr    {
111*b82f24afSAndreas Gohr        if ($mode != 'xhtml') return false;
112*b82f24afSAndreas Gohr        if (is_null($data)) return false;
113*b82f24afSAndreas Gohr
114*b82f24afSAndreas Gohr        if (is_a($R, 'renderer_plugin_dw2pdf')) {
115*b82f24afSAndreas Gohr            $R->doc .= $this->pdf($data);
116*b82f24afSAndreas Gohr        } else {
117*b82f24afSAndreas Gohr            $R->doc .= $this->iframe($data, $this->getConf('gdpr') ? 'div' : 'iframe');
118*b82f24afSAndreas Gohr        }
119*b82f24afSAndreas Gohr        return true;
120*b82f24afSAndreas Gohr    }
121*b82f24afSAndreas Gohr
122*b82f24afSAndreas Gohr    /**
123*b82f24afSAndreas Gohr     * Prepare the HTML for output of the embed iframe
124*b82f24afSAndreas Gohr     * @param array $data
125*b82f24afSAndreas Gohr     * @param string $element Can be used to not directly embed the iframe
126*b82f24afSAndreas Gohr     * @return string
127*b82f24afSAndreas Gohr     */
128*b82f24afSAndreas Gohr    public function iframe($data, $element = 'iframe')
129*b82f24afSAndreas Gohr    {
130*b82f24afSAndreas Gohr        return "<$element "
131*b82f24afSAndreas Gohr            . buildAttributes(array(
132*b82f24afSAndreas Gohr                'src' => $data['url'],
133*b82f24afSAndreas Gohr                'width' => $data['width'],
134*b82f24afSAndreas Gohr                'height' => $data['height'],
135*b82f24afSAndreas Gohr                'style' => $this->sizeToStyle($data['width'], $data['height']),
136*b82f24afSAndreas Gohr                'class' => 'vshare vshare__' . $data['align'],
137*b82f24afSAndreas Gohr                'allowfullscreen' => '',
138*b82f24afSAndreas Gohr                'frameborder' => 0,
139*b82f24afSAndreas Gohr                'scrolling' => 'no',
140*b82f24afSAndreas Gohr                'data-domain' => $data['domain'],
141*b82f24afSAndreas Gohr            ))
142*b82f24afSAndreas Gohr            . '><h3>' . hsc($data['title']) . "</h3></$element>";
143*b82f24afSAndreas Gohr    }
144*b82f24afSAndreas Gohr
145*b82f24afSAndreas Gohr    /**
146*b82f24afSAndreas Gohr     * Create a style attribute for the given size
147*b82f24afSAndreas Gohr     *
148*b82f24afSAndreas Gohr     * @param int|string $width
149*b82f24afSAndreas Gohr     * @param int|string $height
150*b82f24afSAndreas Gohr     * @return string
151*b82f24afSAndreas Gohr     */
152*b82f24afSAndreas Gohr    public function sizeToStyle($width, $height)
153*b82f24afSAndreas Gohr    {
154*b82f24afSAndreas Gohr        // no unit? use px
155*b82f24afSAndreas Gohr        if ($width && $width == (int)$width) {
156*b82f24afSAndreas Gohr            $width = $width . 'px';
157*b82f24afSAndreas Gohr        }
158*b82f24afSAndreas Gohr        // no unit? use px
159*b82f24afSAndreas Gohr        if ($height && $height == (int)$height) {
160*b82f24afSAndreas Gohr            $height = $height . 'px';
161*b82f24afSAndreas Gohr        }
162*b82f24afSAndreas Gohr
163*b82f24afSAndreas Gohr        $style = '';
164*b82f24afSAndreas Gohr        if ($width) $style .= 'width:' . $width . ';';
165*b82f24afSAndreas Gohr        if ($height) $style .= 'height:' . $height . ';';
166*b82f24afSAndreas Gohr        return $style;
167*b82f24afSAndreas Gohr    }
168*b82f24afSAndreas Gohr
169*b82f24afSAndreas Gohr    /**
170*b82f24afSAndreas Gohr     * Prepare the HTML for output in PDF exports
171*b82f24afSAndreas Gohr     *
172*b82f24afSAndreas Gohr     * @param array $data
173*b82f24afSAndreas Gohr     * @return string
174*b82f24afSAndreas Gohr     */
175*b82f24afSAndreas Gohr    public function pdf($data)
176*b82f24afSAndreas Gohr    {
177*b82f24afSAndreas Gohr        $html = '<div class="vshare vshare__' . $data['align'] . '"
178*b82f24afSAndreas Gohr                      width="' . $data['width'] . '"
179*b82f24afSAndreas Gohr                      height="' . $data['height'] . '">';
180*b82f24afSAndreas Gohr
181*b82f24afSAndreas Gohr        $html .= '<a href="' . $data['url'] . '" class="vshare">';
182*b82f24afSAndreas Gohr        $html .= '<img src="' . DOKU_BASE . 'lib/plugins/vshare/video.png" />';
183*b82f24afSAndreas Gohr        $html .= '</a>';
184*b82f24afSAndreas Gohr
185*b82f24afSAndreas Gohr        $html .= '<br />';
186*b82f24afSAndreas Gohr
187*b82f24afSAndreas Gohr        $html .= '<a href="' . $data['url'] . '" class="vshare">';
188*b82f24afSAndreas Gohr        $html .= ($data['title'] ? hsc($data['title']) : 'Video');
189*b82f24afSAndreas Gohr        $html .= '</a>';
190*b82f24afSAndreas Gohr
191*b82f24afSAndreas Gohr        $html .= '</div>';
192*b82f24afSAndreas Gohr
193*b82f24afSAndreas Gohr        return $html;
194*b82f24afSAndreas Gohr    }
195*b82f24afSAndreas Gohr
196*b82f24afSAndreas Gohr    /**
197*b82f24afSAndreas Gohr     * Fill the placeholders in the given URL
198*b82f24afSAndreas Gohr     *
199*b82f24afSAndreas Gohr     * @param string $url
200*b82f24afSAndreas Gohr     * @param string $vid
201*b82f24afSAndreas Gohr     * @param int|string $width
202*b82f24afSAndreas Gohr     * @param int|string $height
203*b82f24afSAndreas Gohr     * @return string
204*b82f24afSAndreas Gohr     */
205*b82f24afSAndreas Gohr    public function insertPlaceholders($url, $vid, $width, $height)
206*b82f24afSAndreas Gohr    {
207*b82f24afSAndreas Gohr        global $INPUT;
208*b82f24afSAndreas Gohr        $url = str_replace('@VIDEO@', rawurlencode($vid), $url);
209*b82f24afSAndreas Gohr        $url = str_replace('@DOMAIN@', rawurlencode($INPUT->server->str('HTTP_HOST')), $url);
210*b82f24afSAndreas Gohr        $url = str_replace('@WIDTH@', $width, $url);
211*b82f24afSAndreas Gohr        $url = str_replace('@HEIGHT@', $height, $url);
212*b82f24afSAndreas Gohr
213*b82f24afSAndreas Gohr        return $url;
214*b82f24afSAndreas Gohr    }
215*b82f24afSAndreas Gohr
216*b82f24afSAndreas Gohr    /**
217*b82f24afSAndreas Gohr     * Extract the wanted size from the parameter list
218*b82f24afSAndreas Gohr     *
219*b82f24afSAndreas Gohr     * @param array $params
220*b82f24afSAndreas Gohr     * @return int[]
221*b82f24afSAndreas Gohr     */
222*b82f24afSAndreas Gohr    public function parseSize(&$params)
223*b82f24afSAndreas Gohr    {
224*b82f24afSAndreas Gohr        $known = join('|', array_keys($this->sizes));
225*b82f24afSAndreas Gohr
226*b82f24afSAndreas Gohr        foreach ($params as $key => $value) {
227*b82f24afSAndreas Gohr            if (preg_match("/^((\d+)x(\d+))|($known)\$/i", $key, $m)) {
228*b82f24afSAndreas Gohr                unset($params[$key]);
229*b82f24afSAndreas Gohr                if (isset($m[4])) {
230*b82f24afSAndreas Gohr                    return $this->sizes[strtolower($m[4])];
231*b82f24afSAndreas Gohr                } else {
232*b82f24afSAndreas Gohr                    return [$m[2], $m[3]];
233*b82f24afSAndreas Gohr                }
234*b82f24afSAndreas Gohr            }
235*b82f24afSAndreas Gohr        }
236*b82f24afSAndreas Gohr
237*b82f24afSAndreas Gohr        // default
238*b82f24afSAndreas Gohr        return $this->sizes['medium'];
239*b82f24afSAndreas Gohr    }
240*b82f24afSAndreas Gohr}
241