-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimage-spoiler.php
More file actions
184 lines (153 loc) · 6.04 KB
/
Copy pathimage-spoiler.php
File metadata and controls
184 lines (153 loc) · 6.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
<?php
/**
* Plugin Name: Image Spoiler
* Plugin URI: http://bychko.ru
* Description: Добавляет возможность размытия изображений в блоке Gutenberg с опциональным текстом предупреждения
* Version: 1.0.1
* Author: Владимир Бычко
* Author URI: http://bychko.ru
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: image-spoiler
* Domain Path: /languages
* Requires at least: 5.8
* Requires PHP: 7.4
*/
// Запрет прямого доступа
if (!defined('ABSPATH')) {
exit;
}
// Константы плагина
define('IMAGE_SPOILER_VERSION', '1.0.1');
define('IMAGE_SPOILER_PATH', plugin_dir_path(__FILE__));
define('IMAGE_SPOILER_URL', plugin_dir_url(__FILE__));
/**
* Основной класс плагина Image Spoiler
*/
class Image_Spoiler {
/**
* Инициализация плагина
*/
public function __construct() {
add_action('init', array($this, 'load_textdomain'));
add_action('enqueue_block_editor_assets', array($this, 'enqueue_editor_assets'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
}
/**
* Загрузка файлов локализации
*/
public function load_textdomain() {
load_plugin_textdomain(
'image-spoiler',
false,
dirname(plugin_basename(__FILE__)) . '/languages'
);
}
/**
* Подключение ассетов для редактора
*/
public function enqueue_editor_assets() {
// Получаем информацию о зависимостях из сборки
$asset_file = IMAGE_SPOILER_PATH . 'build/index.asset.php';
if (!file_exists($asset_file)) {
return;
}
$asset = require $asset_file;
// Подключаем скрипт редактора
wp_enqueue_script(
'image-spoiler-editor',
IMAGE_SPOILER_URL . 'build/index.js',
$asset['dependencies'],
$asset['version'],
true
);
// Подключаем стили редактора
wp_enqueue_style(
'image-spoiler-editor',
IMAGE_SPOILER_URL . 'build/index.css',
array('wp-edit-blocks'),
IMAGE_SPOILER_VERSION
);
// Передаем переводы для JS
wp_set_script_translations(
'image-spoiler-editor',
'image-spoiler',
IMAGE_SPOILER_PATH . 'languages'
);
}
/**
* Подключение ассетов для фронтенда
*/
public function enqueue_frontend_assets() {
// Подключаем стили для фронтенда
wp_enqueue_style(
'image-spoiler-frontend',
IMAGE_SPOILER_URL . 'build/style-index.css',
array(),
IMAGE_SPOILER_VERSION
);
}
}
/**
* Модификация вывода блока Image для добавления спойлера
*
* @param string $block_content Содержимое блока
* @param array $block Данные блока
* @return string Модифицированное содержимое
*/
function image_spoiler_render_block($block_content, $block) {
// Проверяем, что это блок Image
if ('core/image' !== $block['blockName']) {
return $block_content;
}
// Проверяем, включен ли спойлер
if (empty($block['attrs']['isSpoiler'])) {
return $block_content;
}
// Получаем текст спойлера
$spoiler_text = isset($block['attrs']['spoilerText']) ? $block['attrs']['spoilerText'] : '';
// Используем DOMDocument для корректной модификации HTML
$dom = new DOMDocument('1.0', 'UTF-8');
// Подавляем предупреждения о невалидном HTML
libxml_use_internal_errors(true);
// Добавляем мета-теги для правильной работы с UTF-8
$dom->loadHTML('<?xml encoding="UTF-8">' . $block_content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();
// Находим элемент img
$images = $dom->getElementsByTagName('img');
if ($images->length === 0) {
return $block_content;
}
$img = $images->item(0);
// Добавляем класс спойлера к изображению
$current_class = $img->getAttribute('class');
$new_class = trim($current_class . ' image-spoiler');
$img->setAttribute('class', $new_class);
// Находим figure (обертку блока)
$figures = $dom->getElementsByTagName('figure');
if ($figures->length > 0) {
$figure = $figures->item(0);
// Добавляем класс к figure
$current_figure_class = $figure->getAttribute('class');
$new_figure_class = trim($current_figure_class . ' has-image-spoiler');
$figure->setAttribute('class', $new_figure_class);
// Если есть текст спойлера, добавляем его
if (!empty($spoiler_text)) {
$text_div = $dom->createElement('div');
$text_div->setAttribute('class', 'image-spoiler-text');
$text_div->setAttribute('aria-hidden', 'true');
$text_node = $dom->createTextNode($spoiler_text);
$text_div->appendChild($text_node);
// Добавляем текст после img
$img->parentNode->insertBefore($text_div, $img->nextSibling);
}
}
// Возвращаем модифицированный HTML
$output = $dom->saveHTML();
// Убираем добавленные теги
$output = str_replace('<?xml encoding="UTF-8">', '', $output);
return $output;
}
add_filter('render_block', 'image_spoiler_render_block', 10, 2);
// Инициализация плагина
new Image_Spoiler();