PluginProbe
VdoCipher: Secure Video Player and Hosting / 1.29
VdoCipher: Secure Video Player and Hosting v1.29
trunk 1.10 1.11 1.12 1.13 1.14 1.15 1.17 1.18 1.19 1.20 1.21 1.22 1.23 1.24 1.25 1.26 1.27 1.28 1.29 1.3 1.30 1.4 1.5 1.6 All 28 releases
vdocipher / vdocipher.php

vdocipher.php in VdoCipher: Secure Video Player and Hosting 1.29, at vdocipher.php

496 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: VdoCipher
4 * Plugin URI: https://www.vdocipher.com
5 * Description: Secured video hosting for WordPress
6 * Version: 1.29
7 * Author: VdoCipher
8 * Author URI: https://www.vdocipher.com
9 * License: GPL2
10 */
11
12 if (__FILE__ == $_SERVER['SCRIPT_FILENAME']) {
13 header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
14 exit("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html lang='en'><head>\r\n<title>404 Not Found</title>\r\n".
15 "</head><body>\r\n<h1>Not Found</h1>\r\n<p>The requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on ".
16 "this server.</p>\r\n</body></html>");
17 }
18
19 if (!defined('VDOCIPHER_PLUGIN_VERSION')) {
20 define('VDOCIPHER_PLUGIN_VERSION', '1.29');
21 }
22
23 if (!defined('VDOCIPHER_PLAYER_VERSION')) {
24 define('VDOCIPHER_PLAYER_VERSION', 'v2');
25 }
26
27 if (!defined('VDOCIPHER_DEFAULT_THEME')) {
28 define('VDOCIPHER_DEFAULT_THEME', '');
29 }
30
31 function vdo_plugin_check_version()
32 {
33 // This applies only for installs 1.24 and below
34 if (!get_option('vdo_plugin_version')) {
35 if (preg_match('/^1\.[0123456]\.[0-9]{1,2}$/', get_option('vdo_embed_version'))) {
36 update_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
37 }
38 if (preg_match('/^1\.[01234]\.[0-9]{1,2}$/', get_option('vdo_embed_version'))) {
39 update_option('vdo_default_height', 'auto');
40 }
41 update_option('vdo_plugin_version', VDOCIPHER_PLUGIN_VERSION);
42 return ;
43 }
44 // This applies for all new installations after 1.25
45 if (VDOCIPHER_PLUGIN_VERSION !== get_option('vdo_plugin_version')) {
46 if (preg_match('/^1\.[0-9]{1,2}\.[0-9]{1,2}$/', get_option('vdo_embed_version'))) {
47 update_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
48 }
49 update_option('vdo_plugin_version', VDOCIPHER_PLUGIN_VERSION);
50 }
51 }
52
53 add_action('plugins_loaded', 'vdo_plugin_check_version');
54
55 // Function called to get OTP, starts
56 function vdo_otp($video, $otp_post_array = array())
57 {
58 $client_key = get_option('vdo_client_key');
59 if ($client_key == false || $client_key == "") {
60 return (object)['message' => 'Plugin not configured. API Key missing.'];
61 } else if (strlen($client_key) !== 64) {
62 return (object)["message" => "Invalid API Key."];
63 }
64 $url = "https://dev.vdocipher.com/api/videos/$video/otp";
65 $headers = array(
66 'Authorization'=>'Apisecret '.$client_key,
67 'Content-Type'=>'application/json',
68 'Accept'=>'application/json'
69 );
70 $otp_post_json = json_encode($otp_post_array);
71 $response = wp_remote_post(
72 $url,
73 array(
74 'method' => 'POST',
75 'headers' => $headers,
76 'body' => $otp_post_json
77 )
78 );
79 if (is_wp_error($response)) {
80 $error_message = $response->get_error_message();
81 if (false !== stripos($error_message, 'Operation timed out')) {
82 $error_message = 'Operation timed out. Check your firewall at web host or try after sometime.';
83 } else if (false !== stripos($error_message, 'Could not resolve host')) {
84 $error_message = 'Connectivity issue. Check firewall at web host.';
85 }
86 return ["message" => $error_message];
87 }
88
89 $responseCode = $response['response']['code'];
90 if ($responseCode === 404) {
91 return (object)["message" => "Video ID not found"];
92 }
93 else if ($responseCode === 403) {
94 return (object)["message" => "API key does not have OTP creator permission"];
95 }
96 else if ($responseCode === 400 || $responseCode === 401) {
97 return (object)["message" => "Incorrect API key"];
98 } else {
99 return json_decode($response['body']);
100 }
101 }
102 // Function called to get OTP, ends
103
104 // VdoCipher Shortcode starts
105 function vdo_shortcode($atts)
106 {
107 $vdo_args = shortcode_atts(
108 array(
109 'width' => get_option('vdo_default_width'),
110 'height' => get_option('vdo_default_height'),
111 'id' => 'id',
112 'no_annotate'=> false,
113 'vdo_theme'=> false,
114 'autoplay'=> false,
115 'loop'=> false,
116 'controls'=> 'on',
117 'cc_language'=> false,
118 'litemode'=> false,
119 ),
120 $atts
121 );
122 $width = $vdo_args['width'];
123 $height = $vdo_args['height'];
124 $id = $vdo_args['id'];
125 $no_annotate = $vdo_args['no_annotate'];
126 $vdo_theme = $vdo_args['vdo_theme'];
127
128 if (!preg_match('/.*px$/', $width)) {
129 $width = $width."px";
130 }
131 if (!preg_match('/.*px$/', $height)) {
132 if ($height != 'auto') {
133 $height = $height."px";
134 }
135 }
136 if (!$atts['id']) {
137 return "Required argument id for embedded video not found.";
138 } else {
139 $video = $id;
140 }
141
142 // Initialize $otp_post_array, to be sent as part of OTP request, as for time-to-live 300
143 $otp_post_array = array("ttl" => 300);
144 if (!function_exists("eval_date")) {
145 function eval_date($matches)
146 {
147 return current_time($matches[1]);
148 }
149 }
150 if (get_option('vdo_annotate_code') != "") {
151 $current_user = wp_get_current_user();
152 $vdo_annotate_code = get_option('vdo_annotate_code');
153 $vdo_annotate_code = apply_filters('vdocipher_annotate_preprocess', $vdo_annotate_code);
154 if (is_user_logged_in()) {
155 $vdo_annotate_code = str_replace('{name}', $current_user->display_name, $vdo_annotate_code);
156 $vdo_annotate_code = str_replace('{email}', $current_user->user_email, $vdo_annotate_code);
157 $vdo_annotate_code = str_replace('{username}', $current_user->user_login, $vdo_annotate_code);
158 $vdo_annotate_code = str_replace('{id}', $current_user->ID, $vdo_annotate_code);
159 }
160 $vdo_annotate_code = str_replace('{ip}', $_SERVER['REMOTE_ADDR'], $vdo_annotate_code);
161 $vdo_annotate_code = preg_replace_callback('/{date\.([^}]+)}/', "eval_date", $vdo_annotate_code);
162 $vdo_annotate_code = apply_filters('vdocipher_annotate_postprocess', $vdo_annotate_code);
163 // Add annotate code to $otp_post_array, which will be
164 // converted to Json and then sent as POST body to API endpoint
165 if (!$no_annotate) {
166 $otp_post_array["annotate"] = $vdo_annotate_code;
167 }
168 }
169 // OTP is requested via vdo_otp function
170 $OTP_Response = vdo_otp($video, $otp_post_array);
171
172 // https://www.php.net/manual/en/function.isset.php#86313
173 $message = (isset($OTP_Response->message)) ? $OTP_Response->message : null;
174 $OTP = (isset($OTP_Response->otp)) ? $OTP_Response->otp : null;
175 $playbackInfo = (isset($OTP_Response->playbackInfo)) ? $OTP_Response->playbackInfo : null;
176
177 if (is_null($OTP)) {
178 return "<div id='vdo$OTP'><strong>VdoCipher Error: $message</strong></div>";
179 }
180
181 // Version, legacy, for flash only
182 $version = 0;
183 if (isset($atts['version'])) {
184 $version = $atts['version'];
185 }
186
187 // Video Embed version is retrieved from options table or from shortcode attribute
188 $vdo_embed_version_str = get_option('vdo_embed_version');
189
190 // Video Player theme, update and as shortcode attribute
191 if (!$vdo_theme) {
192 $vdo_player_theme = get_option('vdo_player_theme');
193 } else {
194 $vdo_player_theme = $vdo_theme;
195 }
196 if (strpos($vdo_player_theme, 'v1/') === 0 || strlen($vdo_player_theme) === 32) {
197 $vdo_embed_version_str = '1.6.10';
198 } else if (strlen($vdo_player_theme) === 16) {
199 $vdo_embed_version_str = 'v2';
200 }
201 $speedOptions = esc_attr(get_option('vdo_player_speed'));
202 $speedPattern = '/^\d.\d{1,2}(,\d.\d{1,2})+$/';
203
204 // Old Embed Code
205 if ($vdo_embed_version_str === '1.6.10') {
206 //Old embed code
207 $output = <<<END
208 <div id='vdo$OTP' style='height:$height;width:$width;max-width:100%' ></div>
209 <script>(function(v,i,d,e,o){v[o]=v[o]||{}; v[o].add = v[o].add || function V(a){
210 (v[o].d=v[o].d||[]).push(a);};
211 if(!v[o].l) { v[o].l=1*new Date(); a=i.createElement(d), m=i.getElementsByTagName(d)[0];
212 a.async=1; a.src=e; m.parentNode.insertBefore(a,m);}
213 })(window,document,'script','https://d1z78r8i505acl.cloudfront.net/playerAssets/1.6.10/vdo.js','vdo');
214 vdo.add({
215 otp: '$OTP',
216 playbackInfo: '$playbackInfo',
217 theme: '$vdo_player_theme',
218 plugins: [{
219 name: 'keyboard',
220 options: {
221 preset: 'default',
222 bindings: {
223 'Left' : (player) => player.seek(player.currentTime - 15),
224 'Right' : (player) => player.seek(player.currentTime + 15),
225 },
226 }
227 }],
228 container: document.querySelector('#vdo$OTP'),
229 })
230 </script>
231 END;
232
233 if ($speedOptions !== false && preg_match($speedPattern, $speedOptions)) {
234 $output .= <<<END
235 <script>
236 (function () {
237 var originalReadyFunction = window.onVdoCipherAPIReady;
238 // private API; do not use anywhere else; might change without notice
239 var index = vdo.d.length - 1;
240 window.onVdoCipherAPIReady = () => {
241 if (originalReadyFunction) originalReadyFunction();
242 var v_ = vdo.getObjects()[index];
243 v_.addEventListener('load', () => {
244 v_.availablePlaybackRates = [$speedOptions]
245 });
246 }
247 })()
248 </script>
249 END;
250 }
251 } else if ($vdo_embed_version_str === 'v2') {
252 $uniq = 'u' . rand();
253 $url = "https://player.vdocipher.com/v2/?otp=$OTP&playbackInfo=$playbackInfo";
254 if (strlen($vdo_player_theme) === 16) {
255 $url .= "&player=$vdo_player_theme";
256 }
257 if ($vdo_args['autoplay']) {
258 $url .= "&autoplay=true";
259 }
260 if ($vdo_args['loop']) {
261 $url .= "&loop=true";
262 }
263 if (in_array($vdo_args['controls'], ['off', 'native'])) {
264 $url .= "&controls=" . $vdo_args['controls'];
265 }
266 if ($vdo_args['cc_language']) {
267 $url .= "&ccLanguage=" . $vdo_args['cc_language'];
268 }
269 if ($vdo_args['litemode'] === 'true') {
270 $url .= "&litemode=true";
271 }
272 $output = <<<END
273 <script src="https://player.vdocipher.com/v2/api.js"></script>
274 <iframe
275 src="$url"
276 id="$uniq"
277 style="height:$height;width:$width;max-width:100%;border:0;display: block;"
278 allow="encrypted-media"
279 allowfullscreen
280 ></iframe>
281 <script>
282 (function() {
283 const iframe = document.querySelector('#$uniq');
284 const player = VdoPlayer.getInstance(iframe);
285 const isAutoHeight = () => iframe.style.height === 'auto' && iframe.style.width.endsWith('px');
286 const setAspectRatio = (ratio) => {
287 iframe.style.maxHeight = '100vh';
288 if (CSS.supports('aspect-ratio', 1)) {
289 iframe.style.aspectRatio = ratio;
290 } else {
291 const offsetWidth = iframe.offsetWidth;
292 iframe.style.height = Math.round(offsetWidth / ratio) + 'px';
293 }
294 }
295 if (isAutoHeight()) {
296 if (iframe.src.includes('litemode')) {
297 setAspectRatio(16/9);
298 }
299 player.video.addEventListener('loadstart', async () => {
300 const aspectRatio = (await player.api.getMetaData()).aspectRatio;
301 setAspectRatio(aspectRatio);
302 });
303 }
304 })();
305 </script>
306 END;
307 if ($speedOptions !== false && preg_match($speedPattern, $speedOptions)) {
308 $output .= <<<END
309 <script>
310 (function() {
311 const iframe = document.querySelector('#$uniq')
312 const player = VdoPlayer.getInstance(iframe);
313 player.video.addEventListener('loadstart', async () => {
314 player.api.updatePlayerConfig({playbackSpeedOptions: [$speedOptions]});
315 });
316 })();
317 </script>
318 END;
319 }
320
321 } else {
322 $output = 'Invalid player selection: ' . $vdo_embed_version_str;
323 }
324 return $output;
325 }
326 add_shortcode('vdo', 'vdo_shortcode');
327 // VdoCipher Shortcode ends
328
329 // adding the Settings link, starts
330 $plugin = plugin_basename(__FILE__);
331 add_filter("plugin_action_links_$plugin", 'vdo_settings_link');
332
333 function vdo_settings_link($links)
334 {
335 $settings_link = '<a href="options-general.php?page=vdocipher">Settings</a>';
336 array_unshift($links, $settings_link);
337 return $links;
338 }
339 // adding the Settings link, ends
340
341 // add the menu item and register settings (3 functions), starts
342 if (is_admin()) { // admin actions
343 add_action('admin_init', 'register_vdo_settings');
344 add_action('admin_menu', 'vdo_menu');
345 }
346 function vdo_menu()
347 {
348 if (get_option('vdo_show_plugin_in_sidebar') === "") {
349 add_options_page(
350 'VdoCipher Options',
351 'VdoCipher',
352 'manage_options',
353 'vdocipher',
354 'vdo_options'
355 );
356 } else {
357 add_menu_page(
358 'VdoCipher Options',
359 'VdoCipher',
360 'manage_options',
361 'vdocipher',
362 'vdo_options',
363 plugin_dir_url(__FILE__).'images/logo.png'
364 );
365 }
366 }
367
368 function vdo_options()
369 {
370 if (!get_option('vdo_default_height')) {
371 update_option('vdo_default_height', 'auto');
372 }
373 if (!get_option('vdo_default_width')) {
374 update_option('vdo_default_width', '1280');
375 }
376 if (!current_user_can('manage_options')) {
377 wp_die(__('You do not have sufficient permissions to access this page.'));
378 }
379 include('include/options.php');
380 return "";
381 }
382
383 function register_vdo_settings()
384 {
385 // whitelist options
386 register_setting('vdo_option-group', 'vdo_client_key');
387 register_setting('vdo_option-group', 'vdo_default_height');
388 register_setting('vdo_option-group', 'vdo_default_width');
389 register_setting('vdo_option-group', 'vdo_annotate_code');
390 register_setting('vdo_option-group', 'vdo_embed_version');
391 register_setting('vdo_option-group', 'vdo_player_theme');
392 register_setting('vdo_option-group', 'vdo_plugin_version');
393 register_setting('vdo_option-group', 'vdo_player_speed');
394 register_setting('vdo_option-group', 'vdo_show_plugin_in_sidebar');
395 }
396 // add the menu item and register settings (3 functions), ends
397
398 // Activation Hook starts
399 function vdo_activate()
400 {
401 add_option('vdo_default_height', 'auto');
402 add_option('vdo_default_width', 1280);
403 add_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
404 add_option('vdo_player_theme', VDOCIPHER_DEFAULT_THEME);
405 add_option('vdo_show_plugin_in_sidebar', 'true');
406 }
407 register_activation_hook(__FILE__, 'vdo_activate');
408
409 // Registering and specifying Gutenberg block
410 function vdo_register_block()
411 {
412 if (!function_exists('register_block_type')) {
413 return ;
414 }
415 wp_register_script(
416 'vdo-block-script',
417 plugins_url('/include/block/dist/blocks.build.js', __FILE__),
418 array('wp-blocks', 'wp-element', 'wp-editor', 'wp-i18n')
419 );
420 wp_register_style(
421 'vdo-block-base-style',
422 plugins_url('/include/block/dist/blocks.style.build.css', __FILE__),
423 array('wp-blocks')
424 );
425 wp_register_style(
426 'vdo-block-editor-style',
427 plugins_url('/include/block/dist/blocks.editor.build.css', __FILE__),
428 array('wp-edit-blocks')
429 );
430 register_block_type(
431 'vdo/block',
432 array(
433 'editor_script'=>'vdo-block-script',
434 'editor_style'=>'vdo-block-editor-style',
435 'style'=>'vdo-block-base-style',
436 'attributes'=>array(
437 'id'=>array(
438 'type'=>'string',
439 ),
440 'width'=>array(
441 'type'=>'string',
442 'default'=>get_option('vdo_default_width')
443 ),
444 'height'=>array(
445 'type'=>'string',
446 'default'=>get_option('vdo_default_height')
447 ),
448 'vdo_theme'=>array(
449 'type'=>'string',
450 'default'=>get_option('vdo_player_theme')
451 ),
452 'vdo_version'=>array(
453 'type'=>'string',
454 'default'=>get_option('vdo_embed_version')
455 ),
456 ),
457 'render_callback'=>'vdo_shortcode'
458 )
459 );
460 }
461
462 add_action('init', 'vdo_register_block');
463
464 // Deactivation Hook starts
465 function vdo_uninstall()
466 {
467 delete_option('vdo_client_key');
468 delete_option('vdo_default_width');
469 delete_option('vdo_default_height');
470 delete_option('vdo_annotate_code');
471 delete_option('vdo_embed_version');
472 delete_option('vdo_player_theme');
473 delete_option('vdo_plugin_version');
474 delete_option('vdo_player_speed');
475 delete_option('vdo_show_plugin_in_sidebar');
476 }
477 register_uninstall_hook(__FILE__, 'vdo_uninstall');
478
479 // Admin notice to configure plugin for new installs, starts
480 function vdo_admin_notice()
481 {
482 if ((!get_option('vdo_client_key') || strlen(get_option('vdo_client_key')) != 64)
483 && basename($_SERVER['PHP_SELF']) == "plugins.php"
484 ) {
485 ?>
486 <div class="error">
487 <p>
488 The VdoCipher plugin is not ready.
489 <a href="options-general.php?page=vdocipher">Click here to configure</a>
490 </p>
491 </div>
492 <?php
493 }
494 }
495 add_action('admin_notices', 'vdo_admin_notice');
496