\r\n
\r\n404 Not Found\r\n".
"\r\nNot Found
\r\nThe requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on ".
"this server.
\r\n"
);
}
if (!defined('VDOCIPHER_PLUGIN_VERSION')) {
define('VDOCIPHER_PLUGIN_VERSION', '1.30');
}
if (!defined('VDOCIPHER_PLAYER_VERSION')) {
define('VDOCIPHER_PLAYER_VERSION', 'v2');
}
if (!defined('VDOCIPHER_DEFAULT_THEME')) {
define('VDOCIPHER_DEFAULT_THEME', '');
}
function vdo_plugin_check_version()
{
// This applies only for installs 1.24 and below
if (!get_option('vdo_plugin_version')) {
if (preg_match('/^1\.[0123456]\.[0-9]{1,2}$/', get_option('vdo_embed_version'))) {
update_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
}
if (preg_match('/^1\.[01234]\.[0-9]{1,2}$/', get_option('vdo_embed_version'))) {
update_option('vdo_default_height', 'auto');
}
update_option('vdo_plugin_version', VDOCIPHER_PLUGIN_VERSION);
return ;
}
// This applies for all new installations after 1.25
if (VDOCIPHER_PLUGIN_VERSION !== get_option('vdo_plugin_version')) {
if (preg_match('/^1\.[0-9]{1,2}\.[0-9]{1,2}$/', get_option('vdo_embed_version'))) {
update_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
}
update_option('vdo_plugin_version', VDOCIPHER_PLUGIN_VERSION);
}
}
add_action('plugins_loaded', 'vdo_plugin_check_version');
// Function called to get OTP, starts
function vdo_otp($video, $otp_post_array = array())
{
$client_key = get_option('vdo_client_key');
if (empty($client_key)) {
return (object)['message' => 'Plugin not configured. API Key missing.'];
} elseif (strlen($client_key) !== 64) {
return (object)["message" => "Invalid API Key."];
}
$url = "https://dev.vdocipher.com/api/videos/$video/otp";
$pluginVersion = VDOCIPHER_PLUGIN_VERSION;
$phpVersion = phpversion();
$headers = array(
'Authorization' => 'Apisecret '.$client_key,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'vdo-sdk' => "VdoWP/$pluginVersion PHP/$phpVersion" // for backward compatibility
);
$otp_post_json = json_encode($otp_post_array);
$response = wp_remote_post(
$url,
array(
'method' => 'POST',
'headers' => $headers,
'body' => $otp_post_json
)
);
if (is_wp_error($response)) {
$error_message = $response->get_error_message();
if (false !== stripos($error_message, 'Operation timed out')) {
$error_message = 'Operation timed out. Check your firewall at web host or try after sometime.';
} elseif (false !== stripos($error_message, 'Could not resolve host')) {
$error_message = 'DNS Connectivity issue. Check firewall at web host.';
}
return (object)["message" => $error_message];
}
$responseCode = $response['response']['code'];
if ($responseCode === 404) {
return (object)["message" => "Video ID not found"];
} elseif ($responseCode === 403) {
return (object)["message" => "API key does not have OTP creator permission"];
} elseif ($responseCode === 401) {
return (object)["message" => "Incorrect API key"];
} elseif ($responseCode === 400) {
return (object)["message" => "Invalid configuration"];
} elseif ($responseCode >= 500) {
return (object)["message" => "Service unavailable. Please try after sometime."];
} else {
return json_decode($response['body']);
}
}
// Function called to get OTP, ends
/**
* Generate player code for V2
*
* @param string $url iframe URL
* @param string $styleAttr style attribute
* @param string $speedOptions comma separated float for playback speed
*
* @return string
*/
function buildPlayerV2($url, $styleAttr, $speedOptions)
{
$url = esc_url($url);
$styleAttr = esc_attr($styleAttr);
$uniq = 'u' . rand();
$output = <<
END;
$speedPattern = '/^\d.\d{1,2}(,\d.\d{1,2})+$/';
if ($speedOptions !== false && preg_match($speedPattern, $speedOptions)) {
$speedOptions = esc_js($speedOptions);
$output .= <<
(function() {
const iframe = document.querySelector('#$uniq')
const player = VdoPlayer.getInstance(iframe);
player.video.addEventListener('loadstart', async () => {
player.api.updatePlayerConfig({playbackSpeedOptions: [$speedOptions]});
});
})();
END;
}
return $output;
}
/**
* Process watermark, to insert WordPress variables, ip, date
*
* @param string $inputWatermark watermark entered in options
*
* @return string json string with variables replaced
*/
function processWatermark($inputWatermark)
{
$current_user = wp_get_current_user();
$vdo_annotate_code = get_option('vdo_annotate_code');
$vdo_annotate_code = apply_filters('vdocipher_annotate_preprocess', $vdo_annotate_code);
if (is_user_logged_in()) {
$vdo_annotate_code = str_replace('{name}', esc_js($current_user->display_name), $vdo_annotate_code);
$vdo_annotate_code = str_replace('{email}', esc_js($current_user->user_email), $vdo_annotate_code);
$vdo_annotate_code = str_replace('{username}', esc_js($current_user->user_login), $vdo_annotate_code);
$vdo_annotate_code = str_replace('{id}', esc_js($current_user->ID), $vdo_annotate_code);
}
$vdo_annotate_code = str_replace('{ip}', $_SERVER['REMOTE_ADDR'], $vdo_annotate_code);
$vdo_annotate_code = preg_replace_callback('/{date\.([^}]+)}/', "eval_date", $vdo_annotate_code);
return apply_filters('vdocipher_annotate_postprocess', $vdo_annotate_code);
}
function buildPlayerV1Speed($speedOptions)
{
$speedOptions = esc_js($speedOptions);
return <<
(function () {
var originalReadyFunction = window.onVdoCipherAPIReady;
// private API; do not use anywhere else; might change without notice
var index = vdo.d.length - 1;
window.onVdoCipherAPIReady = () => {
if (originalReadyFunction) originalReadyFunction();
var v_ = vdo.getObjects()[index];
v_.addEventListener('load', () => {
v_.availablePlaybackRates = [$speedOptions]
});
}
})()
END;
}
/**
* Generate player code for V1
*
* @param string $OTP otp
* @param string $playbackInfo playbackInfo
* @param string $styleAttr string for inline styles
* @param string $vdo_player_theme optional theme id applicable to player v1
*
* @return string string html for embed code
*/
function buildPlayerV1($OTP, $playbackInfo, $styleAttr, $vdo_player_theme)
{
$styleAttr = esc_attr($styleAttr);
$OTP = esc_attr($OTP);
$playbackInfo = esc_attr($playbackInfo);
$vdo_player_theme = esc_attr($vdo_player_theme);
return <<
END;
}
// VdoCipher Shortcode starts
function vdo_shortcode($atts)
{
$vdo_args = shortcode_atts(
array(
'width' => get_option('vdo_default_width'),
'height' => get_option('vdo_default_height'),
'id' => 'id',
'no_annotate' => false,
'vdo_theme' => false,
'autoplay' => false,
'loop' => false,
'controls' => 'on',
'cc_language' => false,
'litemode' => false,
),
$atts
);
$width = $vdo_args['width'];
$height = $vdo_args['height'];
$id = $vdo_args['id'];
$no_annotate = $vdo_args['no_annotate'];
$vdo_theme = $vdo_args['vdo_theme'];
if (!preg_match('/.*px$/', $width)) {
$width = $width."px";
}
if (!preg_match('/.*px$/', $height)) {
if ($height != 'auto') {
$height = $height."px";
}
}
if (!$atts['id']) {
return "Required argument id for embedded video not found.";
} else {
$video = $id;
}
// Initialize $otp_post_array, to be sent as part of OTP request, as for time-to-live 300
$otp_post_array = array("ttl" => 300);
if (!function_exists("eval_date")) {
function eval_date($matches)
{
return current_time($matches[1]);
}
}
if (get_option('vdo_annotate_code') != "") {
// Add annotate code to $otp_post_array, which will be
// converted to Json and then sent as POST body to API endpoint
if (!$no_annotate) {
$otp_post_array["annotate"] = processWatermark(get_option('vdo_annotate_code'));
}
}
$userId = get_current_user_id();
if (get_option('vdo_send_user_id_in_api') && $userId !== 0) {
$otp_post_array["userId"] = $userId;
}
// OTP is requested via vdo_otp function
$OTP_Response = vdo_otp($video, $otp_post_array);
// https://www.php.net/manual/en/function.isset.php#86313
$message = (isset($OTP_Response->message)) ? $OTP_Response->message : null;
$OTP = (isset($OTP_Response->otp)) ? $OTP_Response->otp : null;
$playbackInfo = (isset($OTP_Response->playbackInfo)) ? $OTP_Response->playbackInfo : null;
if (is_null($OTP)) {
return "VdoCipher Error: $message
";
}
// Video Embed version is retrieved from options table or from shortcode attribute
$vdo_embed_version_str = get_option('vdo_embed_version');
// Video Player theme, update and as shortcode attribute
if (!$vdo_theme) {
$vdo_player_theme = get_option('vdo_player_theme');
} else {
$vdo_player_theme = $vdo_theme;
}
if (strpos($vdo_player_theme, 'v1/') === 0 || strlen($vdo_player_theme) === 32) {
$vdo_embed_version_str = '1.6.10';
} elseif (strlen($vdo_player_theme) === 16) {
$vdo_embed_version_str = 'v2';
}
$speedOptions = esc_attr(get_option('vdo_player_speed'));
$styleAttr = "height:$height;width:$width;max-width:100%;border:0;display: block;";
// Old Embed Code
if ($vdo_embed_version_str === '1.6.10') {
//Old embed code
$output = buildPlayerV1($OTP, $playbackInfo, $styleAttr, $vdo_player_theme);
$speedPattern = '/^\d.\d{1,2}(,\d.\d{1,2})+$/';
if ($speedOptions !== false && preg_match($speedPattern, $speedOptions)) {
$output .= buildPlayerV1Speed($speedOptions);
}
} elseif ($vdo_embed_version_str === 'v2') {
$url = "https://player.vdocipher.com/v2/?otp=$OTP&playbackInfo=$playbackInfo";
if (strlen($vdo_player_theme) === 16) {
$url .= "&player=$vdo_player_theme";
}
if ($vdo_args['autoplay']) {
$url .= "&autoplay=true";
}
if ($vdo_args['loop']) {
$url .= "&loop=true";
}
if (in_array($vdo_args['controls'], ['off', 'native'])) {
$url .= "&controls=" . $vdo_args['controls'];
}
if ($vdo_args['cc_language']) {
$url .= "&ccLanguage=" . $vdo_args['cc_language'];
}
if ($vdo_args['litemode'] === 'true') {
$url .= "&litemode=true";
}
$output = buildPlayerV2($url, $styleAttr, $speedOptions);
} else {
$output = 'Invalid player selection: ' . $vdo_embed_version_str;
}
return $output;
}
add_shortcode('vdo', 'vdo_shortcode');
// VdoCipher Shortcode ends
// adding the Settings link, starts
$plugin = plugin_basename(__FILE__);
add_filter("plugin_action_links_$plugin", 'vdo_settings_link');
function vdo_settings_link($links)
{
$settings_link = 'Settings';
array_unshift($links, $settings_link);
return $links;
}
// adding the Settings link, ends
// add the menu item and register settings (3 functions), starts
if (is_admin()) { // admin actions
add_action('admin_init', 'register_vdo_settings');
add_action('admin_menu', 'vdo_menu');
}
function vdo_menu()
{
if (get_option('vdo_show_plugin_in_sidebar') === "") {
add_options_page(
'VdoCipher Options',
'VdoCipher',
'manage_options',
'vdocipher',
'vdo_options'
);
} else {
add_menu_page(
'VdoCipher Options',
'VdoCipher',
'manage_options',
'vdocipher',
'vdo_options',
plugin_dir_url(__FILE__).'images/logo.png'
);
}
}
function vdo_options()
{
if (!get_option('vdo_default_height')) {
update_option('vdo_default_height', 'auto');
}
if (!get_option('vdo_default_width')) {
update_option('vdo_default_width', '1280');
}
if (!current_user_can('manage_options')) {
wp_die(__('You do not have sufficient permissions to access this page.'));
}
include('include/options.php');
return "";
}
function register_vdo_settings()
{
// whitelist options
register_setting('vdo_option-group', 'vdo_client_key');
register_setting('vdo_option-group', 'vdo_default_height');
register_setting('vdo_option-group', 'vdo_default_width');
register_setting('vdo_option-group', 'vdo_annotate_code');
register_setting('vdo_option-group', 'vdo_embed_version');
register_setting('vdo_option-group', 'vdo_player_theme');
register_setting('vdo_option-group', 'vdo_plugin_version');
register_setting('vdo_option-group', 'vdo_player_speed');
register_setting('vdo_option-group', 'vdo_show_plugin_in_sidebar');
register_setting('vdo_option-group', 'vdo_send_user_id_in_api');
}
// add the menu item and register settings (3 functions), ends
// Activation Hook starts
function vdo_activate()
{
add_option('vdo_default_height', 'auto');
add_option('vdo_default_width', 1280);
add_option('vdo_embed_version', VDOCIPHER_PLAYER_VERSION);
add_option('vdo_player_theme', VDOCIPHER_DEFAULT_THEME);
add_option('vdo_show_plugin_in_sidebar', 'true');
}
register_activation_hook(__FILE__, 'vdo_activate');
// Registering and specifying Gutenberg block
function vdo_register_block()
{
if (!function_exists('register_block_type')) {
return ;
}
wp_register_script(
'vdo-block-script',
plugins_url('/include/block/dist/blocks.build.js', __FILE__),
array('wp-blocks', 'wp-element', 'wp-editor', 'wp-i18n')
);
wp_register_style(
'vdo-block-editor-style',
plugins_url('/include/block/dist/blocks.editor.build.css', __FILE__),
array('wp-edit-blocks')
);
register_block_type(
'vdo/block',
array(
'editor_script' => 'vdo-block-script',
'editor_style' => 'vdo-block-editor-style',
'attributes' => array(
'id' => array(
'type' => 'string',
),
'width' => array(
'type' => 'string',
'default' => get_option('vdo_default_width')
),
'height' => array(
'type' => 'string',
'default' => get_option('vdo_default_height')
),
'vdo_theme' => array(
'type' => 'string',
'default' => get_option('vdo_player_theme')
),
'vdo_version' => array(
'type' => 'string',
'default' => get_option('vdo_embed_version')
),
),
'render_callback' => 'vdo_shortcode'
)
);
}
add_action('init', 'vdo_register_block');
// Deactivation Hook starts
function vdo_uninstall()
{
delete_option('vdo_client_key');
delete_option('vdo_default_width');
delete_option('vdo_default_height');
delete_option('vdo_annotate_code');
delete_option('vdo_embed_version');
delete_option('vdo_player_theme');
delete_option('vdo_plugin_version');
delete_option('vdo_player_speed');
delete_option('vdo_show_plugin_in_sidebar');
delete_option('vdo_send_user_id_in_api');
}
register_uninstall_hook(__FILE__, 'vdo_uninstall');
// Admin notice to configure plugin for new installs, starts
function vdo_admin_notice()
{
if ((!get_option('vdo_client_key') || strlen(get_option('vdo_client_key')) != 64)
&& basename($_SERVER['PHP_SELF']) == "plugins.php"
) {
?>