PluginProbe
VdoCipher: Secure Video Player and Hosting / 1.28
VdoCipher: Secure Video Player and Hosting v1.28
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.28, at vdocipher.php

465 lines 16.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.28
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.28');
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 ),
115 $atts
116 );
117 $width = $vdo_args['width'];
118 $height = $vdo_args['height'];
119 $id = $vdo_args['id'];
120 $no_annotate = $vdo_args['no_annotate'];
121 $vdo_theme = $vdo_args['vdo_theme'];
122
123 if (!preg_match('/.*px$/', $width)) {
124 $width = $width."px";
125 }
126 if (!preg_match('/.*px$/', $height)) {
127 if ($height != 'auto') {
128 $height = $height."px";
129 }
130 }
131 if (!$atts['id']) {
132 return "Required argument id for embedded video not found.";
133 } else {
134 $video = $id;
135 }
136
137 // Initialize $otp_post_array, to be sent as part of OTP request, as for time-to-live 300
138 $otp_post_array = array("ttl" => 300);
139 if (!function_exists("eval_date")) {
140 function eval_date($matches)
141 {
142 return current_time($matches[1]);
143 }
144 }
145 if (get_option('vdo_annotate_code') != "") {
146 $current_user = wp_get_current_user();
147 $vdo_annotate_code = get_option('vdo_annotate_code');
148 $vdo_annotate_code = apply_filters('vdocipher_annotate_preprocess', $vdo_annotate_code);
149 if (is_user_logged_in()) {
150 $vdo_annotate_code = str_replace('{name}', $current_user->display_name, $vdo_annotate_code);
151 $vdo_annotate_code = str_replace('{email}', $current_user->user_email, $vdo_annotate_code);
152 $vdo_annotate_code = str_replace('{username}', $current_user->user_login, $vdo_annotate_code);
153 $vdo_annotate_code = str_replace('{id}', $current_user->ID, $vdo_annotate_code);
154 }
155 $vdo_annotate_code = str_replace('{ip}', $_SERVER['REMOTE_ADDR'], $vdo_annotate_code);
156 $vdo_annotate_code = preg_replace_callback('/{date\.([^}]+)}/', "eval_date", $vdo_annotate_code);
157 $vdo_annotate_code = apply_filters('vdocipher_annotate_postprocess', $vdo_annotate_code);
158 // Add annotate code to $otp_post_array, which will be
159 // converted to Json and then sent as POST body to API endpoint
160 if (!$no_annotate) {
161 $otp_post_array["annotate"] = $vdo_annotate_code;
162 }
163 }
164 // OTP is requested via vdo_otp function
165 $OTP_Response = vdo_otp($video, $otp_post_array);
166
167 // https://www.php.net/manual/en/function.isset.php#86313
168 $message = (isset($OTP_Response->message)) ? $OTP_Response->message : null;
169 $OTP = (isset($OTP_Response->otp)) ? $OTP_Response->otp : null;
170 $playbackInfo = (isset($OTP_Response->playbackInfo)) ? $OTP_Response->playbackInfo : null;
171
172 if (is_null($OTP)) {
173 return "<div id='vdo$OTP'><strong>VdoCipher Error: $message</strong></div>";
174 }
175
176 // Version, legacy, for flash only
177 $version = 0;
178 if (isset($atts['version'])) {
179 $version = $atts['version'];
180 }
181
182 // Video Embed version is retrieved from options table or from shortcode attribute
183 $vdo_embed_version_str = get_option('vdo_embed_version');
184
185 // Video Player theme, update and as shortcode attribute
186 if (!$vdo_theme) {
187 $vdo_player_theme = get_option('vdo_player_theme');
188 } else {
189 $vdo_player_theme = $vdo_theme;
190 }
191 if (strpos($vdo_player_theme, 'v1/') === 0 || strlen($vdo_player_theme) === 32) {
192 $vdo_embed_version_str = '1.6.10';
193 } else if (strlen($vdo_player_theme) === 16) {
194 $vdo_embed_version_str = 'v2';
195 }
196 $speedOptions = esc_attr(get_option('vdo_player_speed'));
197 $speedPattern = '/^\d.\d{1,2}(,\d.\d{1,2})+$/';
198
199 // Old Embed Code
200 if ($vdo_embed_version_str === '1.6.10') {
201 //Old embed code
202 $output = <<<END
203 <div id='vdo$OTP' style='height:$height;width:$width;max-width:100%' ></div>
204 <script>(function(v,i,d,e,o){v[o]=v[o]||{}; v[o].add = v[o].add || function V(a){
205 (v[o].d=v[o].d||[]).push(a);};
206 if(!v[o].l) { v[o].l=1*new Date(); a=i.createElement(d), m=i.getElementsByTagName(d)[0];
207 a.async=1; a.src=e; m.parentNode.insertBefore(a,m);}
208 })(window,document,'script','https://d1z78r8i505acl.cloudfront.net/playerAssets/1.6.10/vdo.js','vdo');
209 vdo.add({
210 otp: '$OTP',
211 playbackInfo: '$playbackInfo',
212 theme: '$vdo_player_theme',
213 plugins: [{
214 name: 'keyboard',
215 options: {
216 preset: 'default',
217 bindings: {
218 'Left' : (player) => player.seek(player.currentTime - 15),
219 'Right' : (player) => player.seek(player.currentTime + 15),
220 },
221 }
222 }],
223 container: document.querySelector('#vdo$OTP'),
224 })
225 </script>
226 END;
227
228 if ($speedOptions !== false && preg_match($speedPattern, $speedOptions)) {
229 $output .= <<<END
230 <script>
231 (function () {
232 var originalReadyFunction = window.onVdoCipherAPIReady;
233 // private API; do not use anywhere else; might change without notice
234 var index = vdo.d.length - 1;
235 window.onVdoCipherAPIReady = () => {
236 if (originalReadyFunction) originalReadyFunction();
237 var v_ = vdo.getObjects()[index];
238 v_.addEventListener('load', () => {
239 v_.availablePlaybackRates = [$speedOptions]
240 });
241 }
242 })()
243 </script>
244 END;
245 }
246 } else if ($vdo_embed_version_str === 'v2') {
247 $uniq = 'u' . rand();
248 $output = <<<END
249 <script src="https://player.vdocipher.com/v2/api.js"></script>
250 <iframe
251 src="https://player.vdocipher.com/v2/?otp=$OTP&playbackInfo=$playbackInfo"
252 id="$uniq"
253 style="height:$height;width:$width;max-width:100%;border:0;display: block;"
254 allow="encrypted-media"
255 allowfullscreen
256 ></iframe>
257 <script>
258 (function() {
259 const iframe = document.querySelector('#$uniq');
260 const player = VdoPlayer.getInstance(iframe);
261 player.video.addEventListener('loadstart', async () => {
262 const aspectRatio = (await player.api.getMetaData()).aspectRatio;
263 if (iframe.style.height === 'auto' && iframe.style.width.endsWith('px')) {
264 iframe.style.maxHeight = '100vh';
265 if (CSS.supports('aspect-ratio', 1)) {
266 iframe.style.aspectRatio = aspectRatio;
267 } else {
268 const offsetWidth = iframe.offsetWidth;
269 iframe.style.height = Math.round(offsetWidth / aspectRatio) + 'px';
270 }
271 }
272 });
273 })();
274 </script>
275 END;
276 if ($speedOptions !== false && preg_match($speedPattern, $speedOptions)) {
277 $output .= <<<END
278 <script>
279 (function() {
280 const iframe = document.querySelector('#$uniq')
281 const player = VdoPlayer.getInstance(iframe);
282 player.video.addEventListener('loadstart', async () => {
283 player.api.updatePlayerConfig({playbackSpeedOptions: [$speedOptions]});
284 });
285 })();
286 </script>
287 END;
288 }
289
290 } else {
291 $output = 'Invalid player selection: ' . $vdo_embed_version_str;
292 }
293 return $output;
294 }
295 add_shortcode('vdo', 'vdo_shortcode');
296 // VdoCipher Shortcode ends
297
298 // adding the Settings link, starts
299 $plugin = plugin_basename(__FILE__);
300 add_filter("plugin_action_links_$plugin", 'vdo_settings_link');
301
302 function vdo_settings_link($links)
303 {
304 $settings_link = '<a href="options-general.php?page=vdocipher">Settings</a>';
305 array_unshift($links, $settings_link);
306 return $links;
307 }
308 // adding the Settings link, ends
309
310 // add the menu item and register settings (3 functions), starts
311 if (is_admin()) { // admin actions
312 add_action('admin_init', 'register_vdo_settings');
313 add_action('admin_menu', 'vdo_menu');
314 }
315 function vdo_menu()
316 {
317 if (get_option('vdo_show_plugin_in_sidebar') === "") {
318 add_options_page(
319 'VdoCipher Options',
320 'VdoCipher',
321 'manage_options',
322 'vdocipher',
323 'vdo_options'
324 );
325 } else {
326 add_menu_page(
327 'VdoCipher Options',
328 'VdoCipher',
329 'manage_options',
330 'vdocipher',
331 'vdo_options',
332 plugin_dir_url(__FILE__).'images/logo.png'
333 );
334 }
335 }
336
337 function vdo_options()
338 {
339 if (!get_option('vdo_default_height')) {
340 update_option('vdo_default_height', 'auto');
341 }
342 if (!get_option('vdo_default_width')) {
343 update_option('vdo_default_width', '1280');
344 }
345 if (!current_user_can('manage_options')) {
346 wp_die(__('You do not have sufficient permissions to access this page.'));
347 }
348 include('include/options.php');
349 return "";
350 }
351
352 function register_vdo_settings()
353 {
354 // whitelist options
355 register_setting('vdo_option-group', 'vdo_client_key');
356 register_setting('vdo_option-group', 'vdo_default_height');
357 register_setting('vdo_option-group', 'vdo_default_width');
358 register_setting('vdo_option-group', 'vdo_annotate_code');
359 register_setting('vdo_option-group', 'vdo_embed_version');
360 register_setting('vdo_option-group', 'vdo_player_theme');
361 register_setting('vdo_option-group', 'vdo_plugin_version');
362 register_setting('vdo_option-group', 'vdo_player_speed');
363 register_setting('vdo_option-group', 'vdo_show_plugin_in_sidebar');
364 }
365 // add the menu item and register settings (3 functions), ends
366
367 // Activation Hook starts
368 function vdo_activate()
369 {
370 add_option('vdo_default_height', 'auto');
371 add_option('vdo_default_width', 1280);
372 add_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
373 add_option('vdo_player_theme', VDOCIPHER_DEFAULT_THEME);
374 add_option('vdo_show_plugin_in_sidebar', 'true');
375 }
376 register_activation_hook(__FILE__, 'vdo_activate');
377
378 // Registering and specifying Gutenberg block
379 function vdo_register_block()
380 {
381 if (!function_exists('register_block_type')) {
382 return ;
383 }
384 wp_register_script(
385 'vdo-block-script',
386 plugins_url('/include/block/dist/blocks.build.js', __FILE__),
387 array('wp-blocks', 'wp-element', 'wp-editor', 'wp-i18n')
388 );
389 wp_register_style(
390 'vdo-block-base-style',
391 plugins_url('/include/block/dist/blocks.style.build.css', __FILE__),
392 array('wp-blocks')
393 );
394 wp_register_style(
395 'vdo-block-editor-style',
396 plugins_url('/include/block/dist/blocks.editor.build.css', __FILE__),
397 array('wp-edit-blocks')
398 );
399 register_block_type(
400 'vdo/block',
401 array(
402 'editor_script'=>'vdo-block-script',
403 'editor_style'=>'vdo-block-editor-style',
404 'style'=>'vdo-block-base-style',
405 'attributes'=>array(
406 'id'=>array(
407 'type'=>'string',
408 ),
409 'width'=>array(
410 'type'=>'string',
411 'default'=>get_option('vdo_default_width')
412 ),
413 'height'=>array(
414 'type'=>'string',
415 'default'=>get_option('vdo_default_height')
416 ),
417 'vdo_theme'=>array(
418 'type'=>'string',
419 'default'=>get_option('vdo_player_theme')
420 ),
421 'vdo_version'=>array(
422 'type'=>'string',
423 'default'=>get_option('vdo_embed_version')
424 ),
425 ),
426 'render_callback'=>'vdo_shortcode'
427 )
428 );
429 }
430
431 add_action('init', 'vdo_register_block');
432
433 // Deactivation Hook starts
434 function vdo_uninstall()
435 {
436 delete_option('vdo_client_key');
437 delete_option('vdo_default_width');
438 delete_option('vdo_default_height');
439 delete_option('vdo_annotate_code');
440 delete_option('vdo_embed_version');
441 delete_option('vdo_player_theme');
442 delete_option('vdo_plugin_version');
443 delete_option('vdo_player_speed');
444 delete_option('vdo_show_plugin_in_sidebar');
445 }
446 register_uninstall_hook(__FILE__, 'vdo_uninstall');
447
448 // Admin notice to configure plugin for new installs, starts
449 function vdo_admin_notice()
450 {
451 if ((!get_option('vdo_client_key') || strlen(get_option('vdo_client_key')) != 64)
452 && basename($_SERVER['PHP_SELF']) == "plugins.php"
453 ) {
454 ?>
455 <div class="error">
456 <p>
457 The VdoCipher plugin is not ready.
458 <a href="options-general.php?page=vdocipher">Click here to configure</a>
459 </p>
460 </div>
461 <?php
462 }
463 }
464 add_action('admin_notices', 'vdo_admin_notice');
465