1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Class Video |
4
|
|
|
* |
5
|
|
|
* @filesource Video.php |
6
|
|
|
* @created 12.10.2015 |
7
|
|
|
* @package chillerlan\bbcode\Modules\Html5 |
8
|
|
|
* @author Smiley <[email protected]> |
9
|
|
|
* @copyright 2015 Smiley |
10
|
|
|
* @license MIT |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace chillerlan\bbcode\Modules\Html5; |
14
|
|
|
|
15
|
|
|
use chillerlan\bbcode\Modules\ModuleInterface; |
16
|
|
|
use chillerlan\TinyCurl\Traits\RequestTrait; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Transforms several video tags into HTML5 |
20
|
|
|
* |
21
|
|
|
* @todo |
22
|
|
|
*/ |
23
|
|
|
class Video extends Html5BaseModule implements ModuleInterface{ |
24
|
|
|
use RequestTrait; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* An array of tags the module is able to process |
28
|
|
|
* |
29
|
|
|
* @var array |
30
|
|
|
* @see \chillerlan\bbcode\Modules\Tagmap::$tags |
31
|
|
|
*/ |
32
|
|
|
protected $tags = ['video', 'dmotion', 'vimeo', 'youtube', 'moddb']; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* temp flash |
36
|
|
|
* |
37
|
|
|
* @var string |
38
|
|
|
*/ |
39
|
|
|
protected $flash; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var array |
43
|
|
|
*/ |
44
|
|
|
protected $cssclass = ['bb-video']; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Transforms the bbcode, called from BaseModuleInterface |
48
|
|
|
* |
49
|
|
|
* @return string a transformed snippet |
50
|
|
|
* @see \chillerlan\bbcode\Modules\BaseModuleInterface::transform() |
51
|
|
|
* @internal |
52
|
|
|
*/ |
53
|
|
|
public function __transform():string{ |
54
|
|
|
$this->setRequestCA($this->parserOptions->ca_info); |
55
|
|
|
|
56
|
|
|
if(empty($this->content)){ |
57
|
|
|
return ''; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
$this->flash = $this->getAttribute('flash'); |
61
|
|
|
|
62
|
|
|
if($this->getAttribute('wide')){ |
63
|
|
|
$this->cssclass[] = 'wide'; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
return $this->getPlayer(); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Gets the video provider |
71
|
|
|
* |
72
|
|
|
* @return string |
73
|
|
|
*/ |
74
|
|
|
protected function getPlayer():string{ |
75
|
|
|
$bbtag = $this->bbtag(); |
76
|
|
|
$url = parse_url($this->content); |
77
|
|
|
$host = isset($url['host']) ? str_replace('www.', '', $url['host']) : false; |
78
|
|
|
|
79
|
|
|
switch(true){ |
80
|
|
|
case $this->tag === 'vimeo' || $bbtag === 'vimeo' || $host === 'vimeo.com': |
81
|
|
|
return $this->vimeo(); |
82
|
|
|
case $this->tag === 'youtube' || $bbtag === 'youtube' || in_array($host, ['youtube.com', 'youtu.be']): |
83
|
|
|
return $this->youtube($host, $url); |
|
|
|
|
84
|
|
|
case $this->tag === 'moddb' || $bbtag === 'moddb' || $host === 'moddb.com': |
85
|
|
|
return $this->moddb($host, $url); |
|
|
|
|
86
|
|
|
case $this->tag === 'dmotion' || $bbtag === 'dmotion' || in_array($host, ['dailymotion.com', 'dai.ly']): |
87
|
|
|
return $this->dailymotion($host, $url); |
|
|
|
|
88
|
|
|
default: |
89
|
|
|
return $this->html5Player(); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @param string $video_url |
96
|
|
|
* |
97
|
|
|
* @return string |
98
|
|
|
*/ |
99
|
|
|
protected function flashPlayer(string $video_url):string{ |
100
|
|
|
|
101
|
|
|
return '<div'.$this->getCssClass($this->cssclass).'>' |
102
|
|
|
.'<object type="application/x-shockwave-flash" data="'.$video_url.'">' |
103
|
|
|
.'<param name="allowfullscreen" value="true">' |
104
|
|
|
.'<param name="wmode" value="opaque" />' |
105
|
|
|
.'<param name="movie" value="'.$video_url.'" />' |
106
|
|
|
.'</object></div>'; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param string $video_url |
111
|
|
|
* |
112
|
|
|
* @return string |
113
|
|
|
*/ |
114
|
|
|
protected function embedPlayer(string $video_url):string{ |
115
|
|
|
|
116
|
|
|
return '<div'.$this->getCssClass($this->cssclass).'>' |
117
|
|
|
.'<iframe src="'.$video_url.'" allowfullscreen></iframe></div>'; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @return string |
122
|
|
|
*/ |
123
|
|
|
protected function html5Player():string{ |
124
|
|
|
|
125
|
|
|
return '<video src="'.$this->checkUrl($this->content).'"' |
126
|
|
|
.$this->getCssClass($this->cssclass).' preload="auto" controls="true"></video>'; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @param string $host |
131
|
|
|
* @param array $url |
132
|
|
|
* |
133
|
|
|
* @return string |
134
|
|
|
*/ |
135
|
|
|
protected function dailymotion(string $host, array $url):string{ |
136
|
|
|
|
137
|
|
|
if($host === 'dailymotion.com'){ |
138
|
|
|
$id = explode('_', str_replace('/video/', '', $url['path']), 2)[0]; |
139
|
|
|
} |
140
|
|
|
else if($host === 'dai.ly'){ |
141
|
|
|
$id = $url['path']; |
142
|
|
|
} |
143
|
|
|
else{ |
144
|
|
|
$id = $this->content; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$id = preg_replace('#[^a-z\d]#i', '', $id); |
148
|
|
|
|
149
|
|
|
return $this->flash |
150
|
|
|
? $this->flashPlayer('http://www.dailymotion.com/swf/video/'.$id) |
151
|
|
|
: $this->embedPlayer('http://www.dailymotion.com/embed/video/'.$id); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* @param string $host |
156
|
|
|
* @param array $url |
157
|
|
|
* |
158
|
|
|
* @return string |
159
|
|
|
*/ |
160
|
|
|
protected function moddb(string $host, array $url):string{ |
161
|
|
|
|
162
|
|
|
$id = $host === 'moddb.com' && strpos('http://www.moddb.com/media/', $this->content) === 0 |
163
|
|
|
? $url['path'] |
164
|
|
|
: $this->content; |
165
|
|
|
|
166
|
|
|
$id = preg_replace('/[^\d]/', '', $id); |
167
|
|
|
|
168
|
|
|
return $this->flash |
169
|
|
|
? $this->flashPlayer('http://www.moddb.com/media/embed/'.$id) |
170
|
|
|
: $this->embedPlayer('http://www.moddb.com/media/iframe/'.$id); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @return string |
175
|
|
|
*/ |
176
|
|
|
protected function vimeo():string{ |
177
|
|
|
// since the video id is the only numeric part in a common vimeo share url, we can safely strip anything which is not number |
178
|
|
|
$id = preg_replace('/[^\d]/', '', $this->content); |
179
|
|
|
|
180
|
|
|
// @todo collect & batch request |
181
|
|
|
$response = $this->fetch('https://api.vimeo.com/videos/'.$id, ['access_token' => $this->parserOptions->vimeo_access_token])->json; |
182
|
|
|
|
183
|
|
|
// access token needed - no coverage |
184
|
|
|
// @codeCoverageIgnoreStart |
185
|
|
|
if(isset($response->link)){ |
186
|
|
|
// @todo add fancyness |
187
|
|
|
return $this->flash |
188
|
|
|
? $this->flashPlayer('https://vimeo.com/moogaloop.swf?clip_id='.$id) |
189
|
|
|
: $this->embedPlayer('https://player.vimeo.com/video/'.$id); |
190
|
|
|
} |
191
|
|
|
// @codeCoverageIgnoreEnd |
192
|
|
|
|
193
|
|
|
return ''; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* @param string $host |
198
|
|
|
* @param array $url |
199
|
|
|
* |
200
|
|
|
* @return string |
201
|
|
|
*/ |
202
|
|
|
protected function youtube(string $host, array $url):string{ |
203
|
|
|
|
204
|
|
|
if($host === 'youtube.com'){ |
205
|
|
|
parse_str($url['query'], $q); |
206
|
|
|
$id = $q['v']; |
207
|
|
|
} |
208
|
|
|
else if($host === 'youtu.be'){ |
209
|
|
|
$e = explode('/', $url['path'], 2); |
210
|
|
|
$id = isset($e[1]) ? $e[1] : false; |
211
|
|
|
} |
212
|
|
|
else{ |
213
|
|
|
$id = $this->content; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
if($id){ |
217
|
|
|
|
218
|
|
|
// check video (and get data) |
219
|
|
|
$params = [ |
220
|
|
|
'id' => preg_replace('/[^a-z\d-_]/i', '', $id), |
221
|
|
|
'part' => 'snippet', |
222
|
|
|
'key' => $this->parserOptions->google_api_key, |
223
|
|
|
]; |
224
|
|
|
|
225
|
|
|
$response = $this->fetch('https://www.googleapis.com/youtube/v3/videos', $params)->json; |
226
|
|
|
|
227
|
|
|
// api key needed - no coverage |
228
|
|
|
// @codeCoverageIgnoreStart |
229
|
|
|
if(isset($response->items, $response->items[0]) && $response->items[0]->id === $id){ |
230
|
|
|
// @todo support playlists |
231
|
|
|
return $this->flash |
232
|
|
|
? $this->flashPlayer('https://www.youtube.com/v/'.$id) |
233
|
|
|
: $this->embedPlayer('https://www.youtube.com/embed/'.$id); |
234
|
|
|
} |
235
|
|
|
// @codeCoverageIgnoreEnd |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return ''; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
} |
242
|
|
|
|
This check looks for type mismatches where the missing type is
false
. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTime
object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalse
before passing on the value to another function or method that may not be able to handle afalse
.