Предрелиз

This commit is contained in:
Tooweb 2025-05-03 04:32:37 +05:00
commit 9c8720a0d9
9 changed files with 834 additions and 0 deletions

18
.cursorrules Normal file
View File

@ -0,0 +1,18 @@
Не ломай рабочий код проекта!
Старайся добавлять комментарии к коду, который ты вставляешь"
Анализируй все файлы проекта и работай так, чтбы ничего не сломать.
Задача проекта:
Мне нужен плагин для последней версии Wordpress и плагина Elementor который будет выполнять следующий функционал:
1 Для конструктора Elementor и Elementor PRO.
Необходимо чтобы при редактировании через конструктор Elementor добавился виджет, который называется «PDF Viewer».
При перетаскивании виджета в рабочую область страницы, виджет должен отображать демо страницу формата PDF.
Сам же виджет должен иметь настройки аналогично дизайну других настроек плагина Elementor. Первой, это поле для выбора PDF файла из медиатеки wordpress. Так же в поле загрузки плагин должен иметь возможность подтягивать динамические данные.
После этого поля должен быть ряд настроек:
1. Поле для ввода числового значения, которое будет влиять на отображаемое количество страниц на странице соответственно если в настройке указана только одна страница, а сам файл имеет 2 и более страниц, то на странице должна отображаться только одна страница. Если указать цифру 2, то отображаться на странице 2 страницы и так далее. По умолчанию отображается одна страница.
2. Кнопка on/off, которая может переопределять предыдущую настройку. Если ее включить, то виджет должен отображать все страницы в файле pdf.
3. Кнопка on/off, которая позволяет включать полосу прокрутки при просмотре pdf файла.
При необходимости размещай структуру файлов плагина так, чтобы я потом мог загрузить и отправить плагин на модерацию в репозиторий Wordpress.org.
Автор плагина: Александр Головин
Сайт автора: tooweb.ru

View File

@ -0,0 +1,75 @@
.pdf-viewer-widget {
margin: 0 auto;
}
.pdf-viewer-container {
width: 100%;
margin: 0 auto;
transition: all 0.3s ease;
}
.pdf-pages-container {
width: 100%;
}
.pdf-page-container {
display: inline-block;
}
.pdf-page-container:last-child {
margin-bottom: 0 !important;
}
.pdf-canvas {
width: 100%;
height: auto;
display: block;
}
/* Стили для режима прокрутки */
.pdf-viewer-container[data-scrollbar="true"] {
overflow-y: auto;
}
/* Медиа-запросы для адаптивности */
@media (max-width: 767px) {
.pdf-viewer-container {
margin: 0;
}
.pdf-page-container {
width: 100% !important;
}
}
/* Стили для контрола выбора файла */
.elementor-control-media {
padding: 7px;
border: 1px solid #d5dadf;
border-radius: 3px;
background-color: #fff;
}
.elementor-control-media__content {
display: flex;
align-items: center;
justify-content: space-between;
}
.elementor-control-media__preview {
flex: 1;
padding: 0 10px;
}
.elementor-control-media-upload-button {
margin-right: 10px;
}
.elementor-control-media__tools {
display: flex;
align-items: center;
}
.elementor-control-dynamic-switcher {
margin-left: 5px;
}

View File

@ -0,0 +1,108 @@
(function($) {
'use strict';
class PDFViewer {
constructor(element) {
this.element = element;
this.container = element.querySelector('.pdf-viewer-container');
this.pagesContainer = element.querySelector('.pdf-pages-container');
this.pdfUrl = element.dataset.pdfUrl;
this.pages = element.dataset.pages;
this.showAll = element.dataset.showAll === 'true';
this.scrollbar = element.dataset.scrollbar === 'true';
this.layout = element.dataset.layout || 'horizontal';
this.pdfDoc = null;
this.scale = 1.0;
this.init();
}
async init() {
const pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = '//cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
try {
this.pdfDoc = await pdfjsLib.getDocument(this.pdfUrl).promise;
await this.renderPages();
} catch (error) {
console.error('Error loading PDF:', error);
}
}
async renderPages() {
this.pagesContainer.innerHTML = '';
const totalPages = this.pdfDoc.numPages;
const pagesToRender = this.showAll ? totalPages : Math.min(parseInt(this.pages), totalPages);
// Получаем первую страницу для определения масштаба
const firstPage = await this.pdfDoc.getPage(1);
const containerWidth = this.container.clientWidth;
const viewport = firstPage.getViewport({ scale: 1 });
// Настраиваем масштаб и стили контейнера в зависимости от layout
if (!this.showAll && pagesToRender > 1 && this.layout === 'horizontal') {
this.scale = (containerWidth / viewport.width) * 0.49;
this.pagesContainer.style.display = 'flex';
this.pagesContainer.style.flexWrap = 'wrap';
this.pagesContainer.style.justifyContent = 'space-between';
} else {
this.scale = containerWidth / viewport.width;
this.pagesContainer.style.display = this.layout === 'vertical' ? 'block' : 'flex';
this.pagesContainer.style.flexWrap = 'wrap';
}
// Настройка прокрутки
if (this.showAll && this.scrollbar) {
this.container.style.overflowY = 'auto';
this.container.style.maxHeight = '800px';
} else {
this.container.style.overflowY = 'hidden';
this.container.style.maxHeight = 'none';
}
// Рендерим страницы
for (let pageNum = 1; pageNum <= pagesToRender; pageNum++) {
const pageContainer = document.createElement('div');
pageContainer.classList.add('pdf-page-container');
if (!this.showAll && pagesToRender > 1) {
if (this.layout === 'horizontal') {
pageContainer.style.width = '49%';
pageContainer.style.marginBottom = '10px';
} else {
pageContainer.style.width = '100%';
pageContainer.style.marginBottom = '20px';
}
}
const canvas = document.createElement('canvas');
canvas.classList.add('pdf-canvas');
pageContainer.appendChild(canvas);
this.pagesContainer.appendChild(pageContainer);
const page = await this.pdfDoc.getPage(pageNum);
const scaledViewport = page.getViewport({ scale: this.scale });
canvas.height = scaledViewport.height;
canvas.width = scaledViewport.width;
const renderContext = {
canvasContext: canvas.getContext('2d'),
viewport: scaledViewport
};
await page.render(renderContext).promise;
}
}
}
// Инициализация виджетов
$(window).on('elementor/frontend/init', () => {
elementorFrontend.hooks.addAction('frontend/element_ready/pdf_viewer.default', ($element) => {
const widgets = $element[0].querySelectorAll('.pdf-viewer-widget');
widgets.forEach(widget => new PDFViewer(widget));
});
});
})(jQuery);

View File

@ -0,0 +1,43 @@
<?php
if (!defined('ABSPATH')) {
exit; // Exit if accessed directly
}
class PDF_Viewer_URL_Tag extends \Elementor\Core\DynamicTags\Data_Tag {
public function get_name() {
return 'pdf-url';
}
public function get_title() {
return 'URL PDF файла';
}
public function get_group() {
return 'pdf';
}
public function get_categories() {
return [
\Elementor\Modules\DynamicTags\Module::MEDIA_CATEGORY,
\Elementor\Modules\DynamicTags\Module::URL_CATEGORY,
\Elementor\Modules\DynamicTags\Module::POST_META_CATEGORY,
];
}
protected function get_value(array $options = []) {
$post_id = get_the_ID();
// Получаем значение из мета-полей
$pdf_url = get_post_meta($post_id, 'pdf_file_url', true);
// Проверяем ACF поля
if (function_exists('get_field') && empty($pdf_url)) {
$acf_pdf = get_field('pdf_file', $post_id);
if (!empty($acf_pdf)) {
$pdf_url = is_array($acf_pdf) ? $acf_pdf['url'] : $acf_pdf;
}
}
return $pdf_url;
}
}

View File

@ -0,0 +1,310 @@
<?php
class PDF_Viewer_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'pdf_viewer';
}
public function get_title() {
return 'PDF Viewer';
}
public function get_icon() {
return 'eicon-document-file';
}
public function get_categories() {
return ['general'];
}
protected function register_controls() {
$this->start_controls_section(
'content_section',
[
'label' => 'Настройки PDF',
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'pdf_source',
[
'label' => 'Источник PDF',
'type' => \Elementor\Controls_Manager::SELECT,
'default' => 'media',
'options' => [
'media' => 'Медиафайл',
'dynamic' => 'Динамический',
],
]
);
$this->add_control(
'pdf_file',
[
'label' => 'PDF Файл',
'type' => \Elementor\Controls_Manager::MEDIA,
'media_types' => ['application/pdf'],
'default' => [
'url' => '',
'id' => null,
],
'condition' => [
'pdf_source' => 'media',
],
]
);
$this->add_control(
'pdf_dynamic',
[
'label' => 'Динамический PDF',
'type' => \Elementor\Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
'categories' => [
\Elementor\Modules\DynamicTags\Module::URL_CATEGORY,
\Elementor\Modules\DynamicTags\Module::POST_META_CATEGORY,
\Elementor\Modules\DynamicTags\Module::MEDIA_CATEGORY,
],
],
'condition' => [
'pdf_source' => 'dynamic',
],
]
);
$this->add_control(
'show_all_pages',
[
'label' => 'Показать все страницы',
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => 'Да',
'label_off' => 'Нет',
'default' => '',
]
);
$this->add_control(
'pages_to_show',
[
'label' => 'Количество страниц для показа',
'type' => \Elementor\Controls_Manager::NUMBER,
'min' => 1,
'max' => 100,
'step' => 1,
'default' => 1,
'condition' => [
'show_all_pages' => '',
],
]
);
$this->add_control(
'pages_layout',
[
'label' => 'Расположение страниц',
'type' => \Elementor\Controls_Manager::SELECT,
'default' => 'horizontal',
'options' => [
'horizontal' => 'Горизонтально',
'vertical' => 'Вертикально',
],
'condition' => [
'pages_to_show!' => '1',
],
]
);
$this->add_control(
'enable_scrollbar',
[
'label' => 'Включить полосу прокрутки',
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => 'Да',
'label_off' => 'Нет',
'default' => '',
'condition' => [
'show_all_pages' => 'yes',
],
]
);
$this->add_control(
'pdf_file_style',
[
'label' => '',
'type' => \Elementor\Controls_Manager::HIDDEN,
'selectors' => [
'{{WRAPPER}} .elementor-control-media' => 'border: 1px solid #d5dadf; padding: 7px; border-radius: 3px;',
'{{WRAPPER}} .elementor-control-media__content' => 'display: flex; align-items: center;',
'{{WRAPPER}} .elementor-control-media__preview' => 'height: 40px; width: auto; max-width: 100%; margin-right: 10px;',
'{{WRAPPER}} .elementor-control-media-upload-button' => 'margin-right: 10px;',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'style_section',
[
'label' => 'Стили',
'tab' => \Elementor\Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'background_color',
[
'label' => 'Цвет фона',
'type' => \Elementor\Controls_Manager::COLOR,
'default' => '#525659',
'selectors' => [
'{{WRAPPER}} .pdf-viewer-container' => 'background-color: {{VALUE}}',
],
]
);
$this->add_responsive_control(
'viewer_width',
[
'label' => 'Ширина виджета',
'type' => \Elementor\Controls_Manager::SLIDER,
'size_units' => ['px', '%'],
'range' => [
'px' => [
'min' => 0,
'max' => 2000,
'step' => 1,
],
'%' => [
'min' => 0,
'max' => 100,
'step' => 1,
],
],
'default' => [
'unit' => '%',
'size' => 100,
],
'selectors' => [
'{{WRAPPER}} .pdf-viewer-widget' => 'width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_group_control(
\Elementor\Group_Control_Border::get_type(),
[
'name' => 'border',
'label' => 'Граница',
'selector' => '{{WRAPPER}} .pdf-viewer-container',
]
);
$this->add_responsive_control(
'border_radius',
[
'label' => 'Скругление углов',
'type' => \Elementor\Controls_Manager::DIMENSIONS,
'size_units' => ['px', '%'],
'default' => [
'top' => 4,
'right' => 4,
'bottom' => 4,
'left' => 4,
'unit' => 'px',
'isLinked' => true,
],
'selectors' => [
'{{WRAPPER}} .pdf-viewer-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_group_control(
\Elementor\Group_Control_Box_Shadow::get_type(),
[
'name' => 'box_shadow',
'label' => 'Тень',
'selector' => '{{WRAPPER}} .pdf-viewer-container',
'fields_options' => [
'box_shadow_type' => [
'default' => 'yes',
],
'box_shadow' => [
'default' => [
'horizontal' => 0,
'vertical' => 2,
'blur' => 5,
'spread' => 0,
'color' => 'rgba(0,0,0,0.2)',
],
],
],
]
);
$this->add_responsive_control(
'padding',
[
'label' => 'Внутренний отступ',
'type' => \Elementor\Controls_Manager::DIMENSIONS,
'size_units' => ['px', 'em', '%'],
'selectors' => [
'{{WRAPPER}} .pdf-pages-container' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'default' => [
'top' => 20,
'right' => 20,
'bottom' => 20,
'left' => 20,
'unit' => 'px',
'isLinked' => true,
],
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
$pdf_url = '';
if ($settings['pdf_source'] === 'media' && !empty($settings['pdf_file']['url'])) {
$pdf_url = $settings['pdf_file']['url'];
} elseif ($settings['pdf_source'] === 'dynamic' && !empty($settings['pdf_dynamic'])) {
$pdf_url = $settings['pdf_dynamic'];
}
if (empty($pdf_url)) {
echo 'Пожалуйста, выберите PDF файл или настройте динамический источник';
return;
}
$show_all_pages = $settings['show_all_pages'] === 'yes';
$pages_to_show = $show_all_pages ? 'all' : intval($settings['pages_to_show']);
$enable_scrollbar = $settings['enable_scrollbar'] === 'yes';
$pages_layout = $settings['pages_layout'];
?>
<div class="pdf-viewer-widget"
data-pdf-url="<?php echo esc_url($pdf_url); ?>"
data-pages="<?php echo esc_attr($pages_to_show); ?>"
data-show-all="<?php echo esc_attr($show_all_pages ? 'true' : 'false'); ?>"
data-scrollbar="<?php echo esc_attr($enable_scrollbar ? 'true' : 'false'); ?>"
data-layout="<?php echo esc_attr($pages_layout); ?>">
<div class="pdf-viewer-container">
<div class="pdf-pages-container">
</div>
</div>
</div>
<?php
wp_enqueue_script('pdfjs', 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js', [], '3.11.174', true);
wp_enqueue_script('pdf-viewer-widget');
wp_enqueue_style('pdf-viewer-widget');
}
}

View File

149
pdf-viewer-elementor.php Normal file
View File

@ -0,0 +1,149 @@
<?php
/**
* Plugin Name: PDF Viewer for Elementor
* Description: Добавляет виджет PDF Viewer для Elementor с возможностью просмотра PDF файлов
* Plugin URI: https://tooweb.ru
* Version: 1.0.0
* Author: Александр Головин
* Author URI: https://tooweb.ru
* Text Domain: pdf-viewer-elementor
* Domain Path: /languages
* Requires at least: 5.0
* Requires PHP: 7.0
* Elementor tested up to: 3.20
* Elementor Pro tested up to: 3.20
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Основной класс плагина
*/
final class PDF_Viewer_Elementor {
const VERSION = '1.0.0';
const MINIMUM_ELEMENTOR_VERSION = '3.0.0';
const MINIMUM_PHP_VERSION = '7.0';
private static $_instance = null;
public static function instance() {
if (is_null(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
add_action('init', [$this, 'i18n']);
add_action('plugins_loaded', [$this, 'init']);
// Добавляем поддержку PDF в медиабиблиотеку
add_filter('upload_mimes', [$this, 'add_pdf_mime_type']);
add_filter('wp_prepare_attachment_for_js', [$this, 'update_pdf_attachment_details'], 10, 2);
}
public function i18n() {
load_plugin_textdomain('pdf-viewer-elementor', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
public function init() {
// Проверка наличия Elementor
if (!did_action('elementor/loaded')) {
add_action('admin_notices', [$this, 'admin_notice_missing_main_plugin']);
return;
}
// Проверка версии Elementor
if (!version_compare(ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=')) {
add_action('admin_notices', [$this, 'admin_notice_minimum_elementor_version']);
return;
}
// Проверка версии PHP
if (version_compare(PHP_VERSION, self::MINIMUM_PHP_VERSION, '<')) {
add_action('admin_notices', [$this, 'admin_notice_minimum_php_version']);
return;
}
// Добавляем поддержку динамических тегов
add_action('elementor/dynamic_tags/register', [$this, 'register_dynamic_tags']);
// Регистрируем виджет
add_action('elementor/widgets/register', [$this, 'register_widgets']);
// Регистрируем скрипты и стили
add_action('elementor/frontend/after_register_scripts', [$this, 'register_scripts']);
add_action('elementor/frontend/after_register_styles', [$this, 'register_styles']);
}
public function register_widgets($widgets_manager) {
require_once(__DIR__ . '/includes/widgets/pdf-viewer-widget.php');
$widgets_manager->register(new \PDF_Viewer_Widget());
}
public function register_scripts() {
wp_register_script(
'pdf-viewer-widget',
plugins_url('assets/js/pdf-viewer-widget.js', __FILE__),
['jquery', 'pdfjs'],
self::VERSION,
true
);
}
public function register_styles() {
wp_register_style(
'pdf-viewer-widget',
plugins_url('assets/css/pdf-viewer-widget.css', __FILE__),
[],
self::VERSION
);
}
public function register_dynamic_tags($dynamic_tags_manager) {
// Регистрируем категорию для PDF
\Elementor\Plugin::$instance->dynamic_tags->register_group(
'pdf',
[
'title' => 'PDF'
]
);
// Подключаем и регистрируем наш тег
require_once(__DIR__ . '/includes/dynamic-tags/pdf-url.php');
$dynamic_tags_manager->register(new \PDF_Viewer_URL_Tag());
}
public function admin_notice_missing_main_plugin() {
if (isset($_GET['activate'])) unset($_GET['activate']);
$message = sprintf(
esc_html__('"%1$s" requires "%2$s" to be installed and activated.', 'pdf-viewer-elementor'),
'<strong>' . esc_html__('PDF Viewer for Elementor', 'pdf-viewer-elementor') . '</strong>',
'<strong>' . esc_html__('Elementor', 'pdf-viewer-elementor') . '</strong>'
);
printf('<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message);
}
public function add_pdf_mime_type($mimes) {
$mimes['pdf'] = 'application/pdf';
return $mimes;
}
public function update_pdf_attachment_details($response, $attachment) {
if ($response['mime'] === 'application/pdf') {
$response['icon'] = includes_url('images/media/document.png');
$response['sizes'] = [
'full' => [
'url' => $response['url'],
],
];
}
return $response;
}
}
PDF_Viewer_Elementor::instance();

113
readme.txt Normal file
View File

@ -0,0 +1,113 @@
=== PDF Viewer for Elementor ===
Contributors: Alexander Golovin
Tags: elementor, pdf, viewer, pdf viewer, elementor widget
Requires at least: 5.0
Tested up to: 6.8
Requires PHP: 7.0
Stable tag: 1.0.1
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Добавляет виджет PDF Viewer для Elementor с расширенными возможностями просмотра PDF файлов.
== Description ==
PDF Viewer for Elementor позволяет легко добавлять и настраивать отображение PDF файлов на вашем сайте с помощью удобного виджета Elementor.
= Основные возможности =
Выбор источника PDF файла:
* Загрузка из медиабиблиотеки WordPress
* Поддержка динамических данных (мета-поля, ACF поля, URL)
* Интеграция с медиабиблиотекой WordPress
Настройки отображения страниц:
* Выбор количества отображаемых страниц
* Возможность показа всех страниц файла
* Два режима отображения страниц:
- Горизонтальное (страницы в ряд)
- Вертикальное (страницы друг под другом)
* Настраиваемая полоса прокрутки при просмотре всех страниц
Гибкие настройки стилей:
* Настройка ширины виджета (пиксели или проценты)
* Настройка цвета фона
* Настройка границ:
- Толщина границ
- Цвет границ
- Стиль границ
* Настройка скругления углов
* Настройка тени:
- Горизонтальное и вертикальное смещение
- Размытие
- Растяжение
- Цвет тени
* Настройка внутренних отступов
= Особенности работы =
* Автоматическое масштабирование PDF под размер контейнера
* Поддержка адаптивного дизайна
* Оптимизированная загрузка страниц
* Интуитивно понятный интерфейс в стиле Elementor
* Полная интеграция с динамическими тегами Elementor
= Использование =
1. Установите и активируйте плагин
2. В редакторе Elementor найдите виджет "PDF Viewer"
3. Перетащите виджет в нужное место на странице
4. Выберите PDF файл из медиабиблиотеки или настройте динамический источник
5. Настройте параметры отображения и стили
= Поддержка динамического контента =
Плагин поддерживает различные источники динамического контента:
* Произвольные поля WordPress
* Поля ACF (при наличии плагина Advanced Custom Fields)
* URL-адреса
* Мета-поля постов и страниц
* Другие источники данных, поддерживаемые Elementor
= Технические требования =
* WordPress 5.0 или выше
* Elementor 3.0.0 или выше
* PHP 7.0 или выше
* Поддержка JavaScript в браузере
== Installation ==
1. Загрузите плагин в папку `/wp-content/plugins/`
2. Активируйте плагин через меню 'Плагины' в WordPress
3. Используйте виджет 'PDF Viewer' в редакторе Elementor
== Frequently Asked Questions ==
= Какие форматы файлов поддерживаются? =
Плагин поддерживает работу с файлами в формате PDF.
= Можно ли ограничить количество отображаемых страниц? =
Да, в настройках виджета можно указать конкретное количество страниц для отображения или показать все страницы документа.
= Поддерживается ли адаптивный дизайн? =
Да, виджет полностью адаптивен и корректно отображается на всех устройствах.
= Можно ли использовать PDF файлы из внешних источников? =
Да, через систему динамических тегов можно использовать PDF файлы из любых доступных источников.
== Screenshots ==
1. Интерфейс виджета в редакторе Elementor
2. Настройки отображения PDF
3. Настройки стилей
4. Пример отображения на сайте
== Changelog ==
= 1.0.0 =
* Первый релиз
* Базовый функционал просмотра PDF
* Поддержка динамического контента
* Настройки отображения страниц
* Настройки стилей
== Upgrade Notice ==
= 1.0.0 =
Первый релиз плагина.
== Additional Info ==
Автор: Александр Головин
Сайт автора: tooweb.ru

18
uninstall.php Normal file
View File

@ -0,0 +1,18 @@
<?php
// Если WordPress не вызывает этот файл напрямую, выходим
if (!defined('WP_UNINSTALL_PLUGIN')) {
exit;
}
// Здесь мы удаляем все данные плагина из базы данных
// В нашем случае, нам нужно удалить настройки виджета, если они были сохранены
// Удаляем опции плагина, если они есть
delete_option('pdf_viewer_elementor_settings');
// Удаляем мета-данные постов, связанные с нашим виджетом
global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE '_elementor_data' AND meta_value LIKE '%pdf_viewer%'");
// Очищаем кэш
wp_cache_flush();