PluginProbe
Friends / 2.7.4
Friends v2.7.4
4.3.2 4.3.1 4.3.0 4.2.2 4.2.1 4.2.0 4.1.0 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.1 All 88 releases
friends / libs / blocks-everywhere / classes / class-handler.php

class-handler.php in Friends 2.7.4, at libs/blocks-everywhere/classes/class-handler.php

337 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Friends\Blocks_Everywhere\Handler;
3
4 require_once __DIR__ . '/handlers/class-friends-message.php';
5 require_once __DIR__ . '/handlers/class-friends-status-post.php';
6
7 abstract class Handler {
8 /**
9 * Editor object
10 *
11 * @var Editor|null
12 */
13 protected $editor = null;
14
15 /**
16 * Editor settings
17 *
18 * @var array
19 */
20 protected $settings = [];
21
22 /**
23 * Record the do_blocks hook
24 *
25 * @var string|null
26 */
27 private $doing_hook = null;
28
29 /**
30 * Direct copy of core `do_blocks`, but for comments.
31 *
32 * This also has the benefit that we don't run `wpautop` on block transformed comments, potentially breaking them.
33 *
34 * @param String $content Comment text
35 * @return String
36 */
37 public function do_blocks( $content, $hook ) {
38 $blocks = parse_blocks( $content );
39 $output = '';
40
41 foreach ( $blocks as $block ) {
42 $output .= render_block( $block );
43 }
44
45 // If there are blocks in this content, we shouldn't run wpautop() on it later.
46 $priority = has_filter( $hook, 'wpautop' );
47 if ( false !== $priority && doing_filter( $hook ) && has_blocks( $content ) ) {
48 $this->doing_hook = $hook;
49 remove_filter( $hook, 'wpautop', $priority );
50 add_filter( $hook, [ $this, 'restore_wpautop_hook' ], $priority + 1 );
51 }
52
53 return ltrim( $output );
54 }
55
56 /**
57 * Restore the above `remove_filter` for comments
58 *
59 * @param String $content Comment ext
60 * @return String
61 **/
62 public function restore_wpautop_hook( $content ) {
63 $current_priority = has_filter( $this->doing_hook, [ $this, 'restore_wpautop_hook' ] );
64
65 if ( $current_priority !== false ) {
66 add_filter( $this->doing_hook, 'wpautop', $current_priority - 1 );
67 remove_filter( $this->doing_hook, [ $this, 'restore_wpautop_hook' ], $current_priority );
68 }
69
70 $this->doing_hook = null;
71 return $content;
72 }
73
74 /**
75 * Add the Gutenberg editor to the comment editor, but only if it includes blocks.
76 *
77 * @param string $editor Editor HTML.
78 * @return string
79 */
80 public function the_editor( $editor ) {
81 $editor = preg_replace( '@.*?(<textarea.*?</textarea>).*@', '$1', $editor );
82
83 return '<div class="blocks-everywhere iso-editor__loading">' . $editor . '</div>';
84 }
85
86 public function wp_editor_settings( $settings ) {
87 $settings['tinymce'] = false;
88 $settings['quicktags'] = false;
89 return $settings;
90 }
91
92 public function get_editor_type() {
93 return 'core';
94 }
95
96 /**
97 * Remove blocks that aren't allowed
98 *
99 * @param string $content
100 * @return string
101 */
102 public function remove_blocks( $content ) {
103 if ( ! has_blocks( $content ) ) {
104 return $content;
105 }
106
107 $allowed = $this->get_allowed_blocks();
108 $blocks = parse_blocks( $content );
109 $output = '';
110
111 foreach ( $blocks as $block ) {
112 if ( in_array( $block['blockName'], $allowed, true ) ) {
113 $output .= serialize_block( $block );
114 }
115 }
116
117 return ltrim( $output );
118 }
119
120 /**
121 * Get a list of allowed blocks by looking at the allowed comment tags
122 *
123 * @return string[]
124 */
125 protected function get_allowed_blocks() {
126 global $allowedtags;
127
128 $allowed = [ 'core/paragraph', 'core/list', 'core/code', 'core/list-item' ];
129 $convert = [
130 'blockquote' => 'core/quote',
131 'h1' => 'core/heading',
132 'h2' => 'core/heading',
133 'h3' => 'core/heading',
134 'img' => 'core/image',
135 'ul' => 'core/list',
136 'ol' => 'core/list',
137 'pre' => 'core/code',
138 'table' => 'core/table',
139 'video' => 'core/video',
140 ];
141
142 foreach ( array_keys( $allowedtags ) as $tag ) {
143 if ( isset( $convert[ $tag ] ) ) {
144 $allowed[] = $convert[ $tag ];
145 }
146 }
147
148 return apply_filters( 'blocks_everywhere_allowed_blocks', array_unique( $allowed ), $this->get_editor_type() );
149 }
150
151 /**
152 * Modify KSES filters to match the allowed blocks
153 *
154 * @param array $tags
155 * @return void
156 */
157 public function get_kses_for_allowed_blocks( array $tags ) {
158 $allowed = $this->get_allowed_blocks();
159
160 if ( in_array( 'core/paragraph', $allowed, true ) ) {
161 $tags['p'] = [ 'class' => true ];
162 $tags['br'] = [];
163 }
164
165 if ( in_array( 'core/code', $allowed, true ) ) {
166 if ( ! isset( $tags['pre'] ) ) {
167 $tags['pre'] = [];
168 }
169
170 $tags['pre']['class'] = true;
171 }
172
173 if ( in_array( 'core/quote', $allowed, true ) ) {
174 if ( ! isset( $tags['blockquote'] ) ) {
175 $tags['blockquote'] = [];
176 }
177
178 $tags['blockquote']['class'] = true;
179 }
180
181 if ( in_array( 'core/image', $allowed, true ) ) {
182 $tags['img']['class'] = true;
183 }
184
185 if ( in_array( 'core/image', $allowed, true ) || in_array( 'core/quote', $allowed, true ) ) {
186 $tags['figure'] = [ 'class' => true ];
187 $tags['figcaption'] = [ 'class' => true ];
188 }
189
190 if ( in_array( 'core/embed', $allowed, true ) ) {
191 if ( ! isset( $tags['figure'] ) ) {
192 $tags['figure'] = [];
193 }
194
195 $tags['figure']['class'] = true;
196 $tags['div'] = [ 'class' => true ];
197 }
198
199 if ( in_array( 'core/list', $allowed, true ) ) {
200 if ( ! isset( $tags['ul'] ) ) {
201 $tags['ul'] = [];
202 }
203 if ( ! isset( $tags['ol'] ) ) {
204 $tags['ol'] = [];
205 }
206 if ( ! isset( $tags['li'] ) ) {
207 $tags['li'] = [];
208 }
209
210 $tags['ul']['class'] = true;
211 $tags['ol']['class'] = true;
212 $tags['li']['class'] = true;
213 }
214
215 // General formatting
216 $tags['strike'] = [];
217 $tags['s'] = [];
218 $tags['cite'] = [];
219 $tags['kbd'] = [];
220 $tags['mark'] = [ 'class' => true ];
221 $tags['sub'] = [];
222 $tags['sup'] = [];
223
224 return $tags;
225 }
226
227 /**
228 * Load Gutenberg if a comment form is enabled
229 *
230 * @return void
231 */
232 public function load_editor( $textarea, $container = null ) {
233 $this->editor = new \Friends\Blocks_Everywhere\Editor();
234
235 // Settings for the editor
236 $default_settings = [
237 'editor' => $this->editor->get_editor_settings(),
238 'iso' => [
239 'blocks' => [
240 'allowBlocks' => $this->get_allowed_blocks(),
241 ],
242 'moreMenu' => false,
243 'sidebar' => [
244 'inserter' => false,
245 'inspector' => false,
246 ],
247 'toolbar' => [
248 'navigation' => true,
249 ],
250 'defaultPreferences' => [
251 'fixedToolbar' => true,
252 ],
253 'allowEmbeds' => [
254 'youtube',
255 'vimeo',
256 'wordpress',
257 'wordpress-tv',
258 'videopress',
259 'crowdsignal',
260 'imgur',
261 ],
262 ],
263 'saveTextarea' => $textarea,
264 'container' => $container,
265 'editorType' => $this->get_editor_type(),
266 'allowUrlEmbed' => false,
267 'pastePlainText' => false,
268 'replaceParagraphCode' => false,
269 'pluginsUrl' => plugins_url( '', __DIR__ ),
270 'version' => \Friends\Blocks_Everywhere\Blocks_Everywhere::VERSION,
271 ];
272
273 $settings = apply_filters( 'blocks_everywhere_editor_settings', $default_settings );
274
275 $this->editor->load( $settings );
276 $this->settings = $settings;
277
278 // Enqueue assets
279 $version = $this->enqueue_assets(
280 'blocks-everywhere',
281 'index.min.asset.php',
282 'index.min.js',
283 'style-index.min.css'
284 );
285
286 wp_localize_script( 'blocks-everywhere', 'wpBlocksEverywhere', $settings );
287
288 if ( in_array( 'blocks-everywhere/support-content', $settings['iso']['blocks']['allowBlocks'], true ) ) {
289 $this->enqueue_assets(
290 'support-content-view',
291 'support-content-view.min.asset.php',
292 'support-content-view.min.js',
293 'support-content-view.min.css'
294 );
295 $this->enqueue_assets(
296 'support-content-editor',
297 'support-content-editor.min.asset.php',
298 'support-content-editor.min.js',
299 'support-content-editor.min.css'
300 );
301 }
302
303 $theme_compat = defined( 'BLOCKS_EVERYWHERE_THEME_COMPAT' ) ? BLOCKS_EVERYWHERE_THEME_COMPAT : false;
304 if ( apply_filters( 'blocks_everywhere_theme_compat', $theme_compat ) ) {
305 $plugin = dirname( __DIR__ ) . '/blocks-everywhere.php';
306
307 wp_register_style( 'blocks-everywhere-compat', plugins_url( 'build/theme-compat.min.css', $plugin ), [ 'blocks-everywhere' ], $version );
308 wp_enqueue_style( 'blocks-everywhere-compat' );
309 }
310 }
311
312 private function enqueue_assets( $name, $asset_file, $js_file, $css_file ) {
313 $asset_file = dirname( __DIR__ ) . '/build/' . $asset_file;
314 $asset = file_exists( $asset_file ) ? require_once $asset_file : null;
315 $version = isset( $asset['version'] ) ? $asset['version'] : time();
316 $plugin = dirname( __DIR__ ) . '/blocks-everywhere.php';
317
318 wp_register_script( $name, plugins_url( 'build/' . $js_file, $plugin ), [], $version, true );
319 wp_enqueue_script( $name );
320
321 wp_register_style( $name, plugins_url( 'build/' . $css_file, $plugin ), [], $version );
322 wp_enqueue_style( $name );
323
324 return $version;
325 }
326
327 /**
328 * Callback to show admin editor
329 *
330 * @param string $hook Hook.
331 * @return boolean
332 */
333 public function can_show_admin_editor( $hook ) {
334 return false;
335 }
336 }
337