plug/S1-floating-video/estetika-floating-video.php

327 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/*
Plugin Name: S1 Floating Video
Plugin URI: https://1studi.ru
Description: Плавающее мини-видео в правом нижнем углу с модальным раскрытием
Version: 1.1.0
Author: S1
Text Domain: S1-floating-video
*/
// Защита от прямого доступа
if (!defined('ABSPATH')) {
exit;
}
define('EST_FLOATING_VIDEO_VERSION', '1.1.0');
define('EST_FLOATING_VIDEO_DIR', plugin_dir_path(__FILE__));
define('EST_FLOATING_VIDEO_URL', plugin_dir_url(__FILE__));
// -----------------------------
// Настройки
// -----------------------------
function est_floating_video_settings_init() {
// Регистрируем группу настроек
register_setting(
'est_floating_video_group',
'est_floating_video_options',
'est_floating_video_sanitize'
);
// Секция основных настроек
add_settings_section(
'est_main_section',
'Основные настройки плавающего видео',
'est_main_section_callback',
'est-floating-video'
);
// Поле: включить/выключить
add_settings_field(
'enabled',
'Включить видео',
'est_field_checkbox_cb',
'est-floating-video',
'est_main_section',
['id' => 'enabled']
);
// Поле: URL видео
add_settings_field(
'video_url',
'URL видео (mp4)',
'est_field_text_cb',
'est-floating-video',
'est_main_section',
['id' => 'video_url', 'type' => 'url', 'placeholder' => 'https://.../video.mp4']
);
// Поле: ширина мини-плеера
add_settings_field(
'width',
'Ширина мини-видео (px)',
'est_field_number_cb',
'est-floating-video',
'est_main_section',
['id' => 'width', 'min' => 80, 'max' => 300]
);
// Поле: высота мини-плеера
add_settings_field(
'height',
'Высота мини-видео (px)',
'est_field_number_cb',
'est-floating-video',
'est_main_section',
['id' => 'height', 'min' => 120, 'max' => 500]
);
// Поле: отступ снизу (bottom)
add_settings_field(
'bottom_offset',
'Отступ снизу (px) — полезно над чатом/кнопками',
'est_field_number_cb',
'est-floating-video',
'est_main_section',
['id' => 'bottom_offset', 'min' => 10, 'max' => 300]
);
// Поле: показывать на мобильных
add_settings_field(
'show_on_mobile',
'Показывать на мобильных устройствах',
'est_field_checkbox_cb',
'est-floating-video',
'est_main_section',
['id' => 'show_on_mobile']
);
}
add_action('admin_init', 'est_floating_video_settings_init');
// Колбэки для полей
function est_main_section_callback() {
echo '<p>Настройте отображение плавающего промо-видео.</p>';
}
function est_field_checkbox_cb($args) {
$options = get_option('est_floating_video_options', []);
$value = isset($options[$args['id']]) ? $options[$args['id']] : '1';
?>
<input type="checkbox" name="est_floating_video_options[<?php echo esc_attr($args['id']); ?>]" value="1" <?php checked(1, $value); ?> />
<?php
}
function est_field_text_cb($args) {
$options = get_option('est_floating_video_options', []);
$value = isset($options[$args['id']]) ? esc_attr($options[$args['id']]) : '';
?>
<input type="url" name="est_floating_video_options[<?php echo esc_attr($args['id']); ?>]" value="<?php echo $value; ?>" class="regular-text" placeholder="<?php echo esc_attr($args['placeholder'] ?? ''); ?>" />
<?php
}
function est_field_number_cb($args) {
$options = get_option('est_floating_video_options', []);
$value = isset($options[$args['id']]) ? intval($options[$args['id']]) : 120;
?>
<input type="number" name="est_floating_video_options[<?php echo esc_attr($args['id']); ?>]" value="<?php echo $value; ?>" min="<?php echo $args['min'] ?? 10; ?>" max="<?php echo $args['max'] ?? 500; ?>" style="width:120px;" />
px
<?php
}
// Санитизация
function est_floating_video_sanitize($input) {
$new_input = [];
$new_input['enabled'] = isset($input['enabled']) ? 1 : 0;
$new_input['video_url'] = esc_url_raw(trim($input['video_url'] ?? ''));
$new_input['width'] = max(80, min(300, intval($input['width'] ?? 120)));
$new_input['height'] = max(120, min(500, intval($input['height'] ?? 180)));
$new_input['bottom_offset'] = max(10, min(300, intval($input['bottom_offset'] ?? 20)));
$new_input['show_on_mobile'] = isset($input['show_on_mobile']) ? 1 : 0;
return $new_input;
}
// Добавляем страницу настроек в меню
function est_floating_video_admin_menu() {
add_options_page(
'Плавающее видео',
'Floating Video',
'manage_options',
'est-floating-video',
'est_floating_video_options_page'
);
}
add_action('admin_menu', 'est_floating_video_admin_menu');
// Вывод страницы настроек
function est_floating_video_options_page() {
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields('est_floating_video_group');
do_settings_sections('est-floating-video');
submit_button('Сохранить изменения');
?>
</form>
</div>
<?php
}
// -----------------------------
// Metabox для отдельных страниц/постов
// -----------------------------
function est_floating_video_add_meta_box() {
$post_types = get_post_types(['public' => true], 'names');
foreach ($post_types as $post_type) {
add_meta_box(
'est_floating_video_meta',
'Плавающее видео для этой записи',
'est_floating_video_meta_box_callback',
$post_type,
'side',
'high'
);
}
}
add_action('add_meta_boxes', 'est_floating_video_add_meta_box');
function est_floating_video_meta_box_callback($post) {
wp_nonce_field('est_floating_video_meta_nonce', 'est_floating_video_nonce');
$video_url = get_post_meta($post->ID, 'est_floating_video_url', true);
?>
<p>
<label for="est_floating_video_url">
URL видео (mp4) для этой страницы:<br>
<small>Оставьте пустым — будет использовано глобальное видео</small>
</label>
</p>
<input type="url"
id="est_floating_video_url"
name="est_floating_video_url"
value="<?php echo esc_attr($video_url); ?>"
style="width:100%;"
placeholder="https://.../video.mp4" />
<?php
}
function est_floating_video_save_meta($post_id) {
if (!isset($_POST['est_floating_video_nonce']) ||
!wp_verify_nonce($_POST['est_floating_video_nonce'], 'est_floating_video_meta_nonce')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!current_user_can('edit_post', $post_id)) return;
$video_url = '';
if (isset($_POST['est_floating_video_url'])) {
$video_url = esc_url_raw(trim($_POST['est_floating_video_url']));
}
update_post_meta($post_id, 'est_floating_video_url', $video_url);
}
add_action('save_post', 'est_floating_video_save_meta');
// -----------------------------
// Фронтенд — вывод видео
// -----------------------------
function est_floating_video_enqueue() {
if (is_admin()) return;
$options = get_option('est_floating_video_options', []);
if (empty($options['enabled']) || empty($options['video_url'])) {
return;
}
wp_enqueue_style(
'est-floating-video',
EST_FLOATING_VIDEO_URL . 'assets/floating-video.css',
[],
EST_FLOATING_VIDEO_VERSION
);
wp_enqueue_script(
'est-floating-video',
EST_FLOATING_VIDEO_URL . 'assets/floating-video.js',
[],
EST_FLOATING_VIDEO_VERSION,
true
);
// Передаём настройки в JS (если захотите динамику позже)
wp_localize_script('est-floating-video', 'estVideoConfig', [
'enabled' => !empty($options['enabled']),
]);
}
add_action('wp_enqueue_scripts', 'est_floating_video_enqueue');
function est_floating_video_output() {
$options = get_option('est_floating_video_options', []);
// Глобальные настройки по умолчанию
$global_enabled = !empty($options['enabled']);
$show_on_mobile = isset($options['show_on_mobile']) ? (bool)$options['show_on_mobile'] : true;
$global_video_url = !empty($options['video_url']) ? $options['video_url'] : '';
// Определяем, нужно ли вообще показывать
if (!$global_enabled) {
return;
}
// Проверка мобильного устройства
if (wp_is_mobile() && !$show_on_mobile) {
return;
}
// Определяем видео: сначала индивидуальное, потом глобальное
$video_url = $global_video_url;
if (is_singular()) {
$custom_url = get_post_meta(get_the_ID(), 'est_floating_video_url', true);
if (!empty($custom_url)) {
$video_url = $custom_url;
}
}
// Если в итоге нет видео — выходим
if (empty($video_url)) {
return;
}
$width = $options['width'] ?? 120;
$height = $options['height'] ?? 180;
$bottom = $options['bottom_offset'] ?? 20;
$video_url = esc_url($video_url);
?>
<div class="floating-video-container" style="bottom: <?php echo esc_attr($bottom); ?>px;">
<div class="floating-video-mini" id="miniPlayer" style="width:<?php echo esc_attr($width); ?>px; height:<?php echo esc_attr($height); ?>px;">
<video autoplay muted loop playsinline>
<source src="<?php echo $video_url; ?>" type="video/mp4">
Ваш браузер не поддерживает видео.
</video>
<button class="expand-btn" title="Развернуть видео">↗</button>
<button class="close-btn" title="Закрыть">✕</button>
</div>
<div class="video-modal" id="videoModal">
<div class="modal-content">
<button class="modal-close">✕</button>
<video controls autoplay muted>
<source src="<?php echo $video_url; ?>" type="video/mp4">
</video>
</div>
</div>
</div>
<?php
}
add_action('wp_footer', 'est_floating_video_output', 30);