PluginProbe
Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts / trunk
Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts vtrunk
2.8.14 2.8.13 2.8.12 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.10 2.8.11 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 trunk 1.0.1 1.0.2 1.1.0 1.1.1 All 147 releases
content-blocks-builder / includes / settings.php

settings.php in Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts trunk, at includes/settings.php

578 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The settings: import/export blocks, variants, patterns.
4 *
5 * @package BoldBlocks
6 * @author Phi Phan <mrphipv@gmail.com>
7 * @copyright Copyright (c) 2022, Phi Phan
8 */
9
10 namespace BoldBlocks;
11
12 // Exit if accessed directly.
13 defined( 'ABSPATH' ) || exit;
14
15 if ( ! class_exists( Settings::class ) ) :
16 /**
17 * The controller class for the settings.
18 */
19 class Settings extends CoreComponent {
20 /**
21 * Store the version of core blocks
22 *
23 * @var string
24 */
25 protected $core_blocks_version = '2.7.3';
26
27 /**
28 * The plugin title
29 *
30 * @var string
31 */
32 private $plugin_title = 'Content Blocks Builder';
33
34 /**
35 * The script handle
36 *
37 * @var string
38 */
39 protected $script_handle = 'boldblocks-settings';
40
41 /**
42 * Purged cache status
43 *
44 * @var boolean
45 */
46 protected $is_purged_cache = false;
47
48 /**
49 * Run main hooks
50 *
51 * @return void
52 */
53 public function run() {
54 // Add admin toolbar.
55 add_action( 'in_admin_header', [ $this, 'in_admin_header' ] );
56
57 // Create the settings page.
58 add_action( 'admin_menu', [ $this, 'add_admin_page' ] );
59
60 // Enqueue settings script.
61 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_settings_scripts' ] );
62
63 // Do setting up stuff when the plugin is activated.
64 add_action( 'cbb/activate', [ $this, 'run_the_plugin_setup' ] );
65
66 // Maybe update core blocks.
67 add_action( 'init', [ $this, 'maybe_update_core_blocks' ] );
68
69 // Add rest api endpoint to query docs.
70 add_action( 'rest_api_init', [ $this, 'register_docs_endpoint' ] );
71
72 // Clear the transient cache on upgraded.
73 add_action( 'cbb/version_upgraded', [ $this, 'clear_transient_cache' ] );
74
75 // Change the footer text for the settings pages.
76 add_action( 'admin_footer_text', [ $this, 'admin_footer_text' ] );
77
78 // Purge the cache.
79 add_action( 'admin_init', [ $this, 'boldblocks_purge_cache' ] );
80
81 // Migrate legacy options.
82 add_action( 'cbb/version_upgraded', [ $this, 'migrate_legacy_options' ] );
83
84 // Register setting fields.
85 add_action( 'init', [ $this, 'register_settings' ] );
86 }
87
88 /**
89 * Print the admin toolbar.
90 *
91 * @return void
92 */
93 public function in_admin_header() {
94 $screen = get_current_screen();
95 if ( 'boldblocks_block_page_cbb-settings' === $screen->base ) {
96 // Left links.
97 $left_links = [
98 [
99 'url' => 'https://wordpress.org/support/plugin/content-blocks-builder',
100 'title' => __( 'Feedback & Support ↗', 'content-blocks-builder' ),
101 'target' => '_blank',
102 'icon' => '<span class="dashicons dashicons-editor-help"></span> ',
103 'class' => '',
104 ],
105 [
106 'url' => 'https://wordpress.org/support/plugin/content-blocks-builder/reviews/#new-post',
107 'title' => __( 'Review ↗', 'content-blocks-builder' ),
108 'target' => '_blank',
109 'icon' => '<span class="dashicons dashicons-star-filled"></span> ',
110 'class' => '',
111 ],
112 ];
113
114 $left_links = apply_filters( 'cbb_get_header_left_links', $left_links );
115
116 ?>
117 <div class="cbb-settings-header">
118 <h1><strong><?php echo esc_html( $this->plugin_title ); ?></strong> <code><?php echo esc_html( $this->the_plugin_instance->get_plugin_version() ); ?></code></h1>
119 <ul class="lelf-links">
120 <?php foreach ( $left_links as $link ) : ?>
121 <?php
122 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
123 printf( '<li %5$s><a href="%1$s" target="%3$s"%6$s>%4$s%2$s</a></li>', $link['url'], $link['title'], $link['target'], $link['icon'], ( $link['class'] ?? '' ) ? 'class="' . $link['class'] . '"' : '', $link['style'] ?? '' ? ' style="' . $link['style'] . '"' : '' );
124 ?>
125 <?php endforeach; ?>
126 </ul>
127 </div>
128 <?php
129 }
130 }
131
132 /**
133 * Create the admin page
134 *
135 * @return void
136 */
137 public function add_admin_page() {
138 // Make "Custom Blocks" as parent slug.
139 $parent_slug = 'edit.php?post_type=boldblocks_block';
140
141 add_submenu_page(
142 $parent_slug,
143 $this->plugin_title,
144 __( 'Settings', 'content-blocks-builder' ),
145 'manage_options',
146 'cbb-settings',
147 function () {
148 ?>
149 <div class="wrap">
150 <h2 class="screen-reader-text"><?php echo esc_html( $this->plugin_title ); ?></h2>
151 <div class="boldblocks-settings js-boldblocks-settings-root"></div>
152 </div>
153 <?php
154 }
155 );
156 }
157
158 /**
159 * Enqueue scripts for the settings page.
160 *
161 * @param string $hook_suffix
162 * @return void
163 */
164 public function enqueue_settings_scripts( $hook_suffix ) {
165 // Only load scripts for the settings page.
166 if ( 'boldblocks_block_page_cbb-settings' === $hook_suffix ) {
167 // Settings asset file.
168 $settings_asset = $this->the_plugin_instance->include_file( 'build/settings.asset.php' );
169
170 // Enqueue scripts.
171 wp_enqueue_script(
172 $this->script_handle,
173 $this->the_plugin_instance->get_file_uri( 'build/settings.js' ),
174 $settings_asset['dependencies'] ?? [],
175 $this->the_plugin_instance->get_script_version( $settings_asset ),
176 [ 'in_footer' => true ]
177 );
178
179 // For debuging.
180 $this->the_plugin_instance->enqueue_debug_information( $this->script_handle );
181
182 // Add data to the script.
183 wp_add_inline_script(
184 $this->script_handle,
185 'const CBBSettings=' . wp_json_encode(
186 [
187 'nonce' => wp_create_nonce( 'cbb_purce_nonce' ),
188 'isPurgedCache' => $this->is_purged_cache ? 1 : 0,
189 'variationNonce' => wp_create_nonce( 'cbb_variation_nonce' ),
190 ]
191 ),
192 'before'
193 );
194
195 // Enqueue style.
196 wp_enqueue_style(
197 $this->script_handle,
198 $this->the_plugin_instance->get_file_uri( 'build/settings.css' ),
199 [],
200 $this->the_plugin_instance->get_script_version( $settings_asset )
201 );
202
203 // Load components style.
204 wp_enqueue_style( 'wp-components' );
205 }
206 }
207
208 /**
209 * Run activated stuff
210 * https://wearnhardt.com/2020/03/redirecting-after-plugin-activation/
211 *
212 * @return void
213 */
214 public function run_the_plugin_setup() {
215 // Deploy core blocks.
216 if ( is_admin() && ! $this->is_deloyed_core_blocks() ) {
217 // Update core blocks.
218 $this->update_core_blocks();
219
220 // Add the marker to the settings to make sure this logic only runs one time.
221 add_option( 'cbb_deployed_core_blocks', 1 );
222 }
223
224 // Run the plugin setup.
225 do_action( 'cbb_plugin_setup', $this->the_plugin_instance );
226
227 // Redirect to the getting started page, ignore bulk activation.
228 if (
229 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
230 ! ( ( isset( $_REQUEST['action'] ) && 'activate-selected' === $_REQUEST['action'] ) &&
231 // phpcs:ignore WordPress.Security.NonceVerification.Missing
232 ( isset( $_POST['checked'] ) && count( $_POST['checked'] ) > 1 ) ) ) {
233 add_option( 'boldblocks_activation_redirect', wp_get_current_user()->ID );
234 }
235 }
236
237 /**
238 * Maybe update core blocks
239 *
240 * @return void
241 */
242 public function maybe_update_core_blocks() {
243 if ( is_admin() && current_user_can( 'manage_options' ) ) {
244 $core_blocks_version = $this->get_core_blocks_version();
245 if ( ! $core_blocks_version || $core_blocks_version !== $this->core_blocks_version ) {
246 $this->update_core_blocks( $core_blocks_version, $this->core_blocks_version );
247 }
248 }
249 }
250
251 /**
252 * Parse core blocks
253 *
254 * @return array
255 */
256 private function get_core_blocks() {
257 $core_blocks = false;
258 $core_blocks_file_path = $this->the_plugin_instance->get_file_path( 'data/core-blocks/blocks.json' );
259
260 if ( \file_exists( $core_blocks_file_path ) ) {
261 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
262 $core_blocks = \file_get_contents( $core_blocks_file_path );
263 $core_blocks = \json_decode( $core_blocks, true );
264 }
265
266 return $core_blocks;
267 }
268
269 /**
270 * Update core blocks
271 *
272 * @param string $prev_blocks_version
273 * @param string $next_blocks_version
274 * @return void
275 */
276 private function update_core_blocks( $prev_blocks_version = '', $next_blocks_version = '' ) {
277 if ( is_admin() ) {
278 $core_blocks_data = $this->get_core_blocks();
279
280 if ( $core_blocks_data ) {
281 $core_blocks = $core_blocks_data['blocks'] ?? [];
282
283 foreach ( $core_blocks as $block ) {
284 $name = $block['slug'] ?? '';
285 $found_posts = get_posts(
286 [
287 'post_type' => 'boldblocks_block',
288 'name' => $name,
289 'posts_per_page' => 1,
290 ]
291 );
292
293 // There is no block with that slug.
294 if ( ! ( is_array( $found_posts ) && count( $found_posts ) > 0 ) ) {
295 $title = $block['title'] ?? '';
296 $content = $block['content'] ?? '';
297 $meta = $block['meta'] ?? [];
298
299 // Insert new block.
300 $block_id = wp_insert_post(
301 [
302 'post_type' => 'boldblocks_block',
303 'post_title' => $title,
304 'post_content' => $content,
305 'post_name' => $name,
306 'post_status' => 'publish',
307 'meta_input' => $meta,
308 ]
309 );
310 } else {
311 $found_post = $found_posts[0];
312 $meta = $block['meta'] ?? [];
313
314 $updating_meta = [];
315 $title = $found_post->post_title ?? '';
316 $description = $meta['boldblocks_block_description'] ?? '';
317 if ( is_array( $description ) && count( $description ) > 0 ) {
318 $description = $description[0] ?? '';
319 }
320 $updating_meta['boldblocks_block_description'] = $description;
321 $icon = $meta['boldblocks_block_icon'] ?? '';
322 if ( is_array( $icon ) && count( $icon ) > 0 ) {
323 $icon = $icon[0] ?? '';
324 }
325 $updating_meta['boldblocks_block_icon'] = $icon;
326
327 $supports = $meta['boldblocks_block_supports'] ?? [];
328 if ( ! empty( $supports ) ) {
329 $updating_meta['boldblocks_block_supports'] = $supports;
330 }
331
332 if ( version_compare( $prev_blocks_version, '2.3.4', '<' ) ) {
333 $updating_meta['boldblocks_enable_custom_attributes'] = $meta['boldblocks_enable_custom_attributes'] ?? false;
334 }
335
336 // New transformable in 2.4.1.
337 if ( $meta['boldblocks_is_transformable'] ?? false ) {
338 $updating_meta['boldblocks_is_transformable'] = $meta['boldblocks_is_transformable'];
339 }
340
341 $enable_repeater = $meta['boldblocks_enable_repeater'] ?? '';
342 if ( is_array( $enable_repeater ) && count( $enable_repeater ) > 0 ) {
343 $enable_repeater = $enable_repeater[0] ?? '';
344 }
345
346 if ( $enable_repeater ) {
347 $parent_title = $meta['boldblocks_parent_block_title'] ?? '';
348 if ( is_array( $parent_title ) && count( $parent_title ) > 0 ) {
349 $parent_title = $parent_title[0] ?? '';
350 }
351 $updating_meta['boldblocks_parent_block_title'] = $parent_title;
352
353 $parent_description = $meta['boldblocks_parent_block_description'] ?? '';
354 if ( is_array( $parent_description ) && count( $parent_description ) > 0 ) {
355 $parent_description = $parent_description[0] ?? '';
356 }
357 $updating_meta['boldblocks_parent_block_description'] = $parent_description;
358
359 $parent_icon = $meta['boldblocks_parent_block_icon'] ?? '';
360 if ( is_array( $parent_icon ) && count( $parent_icon ) > 0 ) {
361 $parent_icon = $parent_icon[0] ?? '';
362 }
363 $updating_meta['boldblocks_parent_block_icon'] = $parent_icon;
364
365 $parent_supports = $meta['boldblocks_parent_block_supports'] ?? [];
366 if ( ! empty( $parent_supports ) ) {
367 $updating_meta['boldblocks_parent_block_supports'] = $parent_supports;
368 }
369
370 if ( version_compare( $prev_blocks_version, '2.3.4', '<' ) ) {
371 $updating_meta['boldblocks_parent_enable_custom_attributes'] = $meta['boldblocks_parent_enable_custom_attributes'] ?? false;
372 }
373 }
374
375 $updating_data = [
376 'ID' => $found_post->ID,
377 'post_title' => $block['title'] ?? '',
378 'meta_input' => $updating_meta,
379 ];
380
381 $post_id = wp_update_post( $updating_data );
382 }
383 }
384
385 update_option( 'cbb_core_blocks_version', $this->core_blocks_version );
386 }
387 }
388 }
389
390 /**
391 * Migrate legacy options
392 *
393 * @param string $prev_version
394 * @return void
395 */
396 public function migrate_legacy_options( $prev_version ) {
397 if ( version_compare( $prev_version, '2.7.8', '<=' ) ) {
398 $legacy_options = [
399 'boldblocks_pattern_categories' => 'cbb_pattern_categories',
400 'boldblocks_pattern_categories_all_label' => 'cbb_pattern_categories_all_label',
401 'boldblocks_typography' => 'cbb_typography',
402 'boldblocks_enable_typography' => 'cbb_enable_typography',
403 'boldblocks_use_bunny_fonts' => 'cbb_use_bunny_fonts',
404 ];
405
406 foreach ( $legacy_options as $old_option => $new_option ) {
407 $option_value = get_option( $old_option );
408 if ( $option_value ) {
409 update_option( $new_option, $option_value );
410 delete_option( $old_option );
411 }
412 }
413 }
414 }
415
416 /**
417 * Build a custom endpoint to query docs.
418 *
419 * @return void
420 */
421 public function register_docs_endpoint() {
422 register_rest_route(
423 'boldblocks/v1',
424 '/getDocs/',
425 array(
426 'methods' => 'GET',
427 'callback' => [ $this, 'get_docs' ],
428 'permission_callback' => function () {
429 return current_user_can( 'publish_posts' );
430 },
431 )
432 );
433 }
434
435 /**
436 * Get docs.
437 *
438 * @param WP_REST_Request $request The request object.
439 * @return void
440 */
441 public function get_docs( $request ) {
442 $cache_key = 'bb_docs';
443 $data = get_transient( $cache_key );
444 $library_component = $this->the_plugin_instance->get_component( Library::class );
445 $library_url = $library_component ? $library_component->get_library_url() : 'https://boldpatterns.net';
446
447 if ( false === $data ) {
448 $response = wp_remote_get(
449 $library_url . '/wp-json/api.boldblocks/v1/getDocs',
450 [
451 'timeout' => 120,
452 'sslverify' => false,
453 ]
454 );
455
456 if ( ! is_wp_error( $response ) ) {
457 $data = json_decode( wp_remote_retrieve_body( $response ), true );
458
459 if ( $data ) {
460 set_transient( $cache_key, $data, DAY_IN_SECONDS );
461 }
462 }
463 }
464
465 wp_send_json(
466 [
467 'data' => $data,
468 'success' => true,
469 ]
470 );
471 }
472
473 /**
474 * Clear transient cache
475 *
476 * @return void
477 */
478 public function clear_transient_cache() {
479 delete_transient( 'bb_docs' );
480 }
481
482 /**
483 * Change the footer text for the settings pages
484 *
485 * @param string $footer_text
486 * @return string
487 */
488 public function admin_footer_text( $footer_text ) {
489 // Get current screen.
490 $current_screen = get_current_screen();
491 if ( 'edit.php?post_type=boldblocks_block' === $current_screen->parent_file ) {
492 $footer_text = '<i><a href="https://contentblocksbuilder.com/?utm_source=CBB&utm_campaign=CBB+visit+site&utm_medium=link&utm_content=footer-text" target="_blank" title="' . __( 'Visit the Plugin website', 'content-blocks-builder' ) . '" style="text-decoration:none"><strong>CBB</strong></a> <code>' . esc_html( $this->the_plugin_instance->get_plugin_version() ) . '</code>. Please <a target="_blank" href="https://wordpress.org/support/plugin/content-blocks-builder/reviews/#new-post" title="Rate the plugin" style="text-decoration:none">rate the plugin <span style="color:#ffb900">�
493
494
495
496
497 </span></a> to help us spread the word. Thank you from the CBB team!</i>';
498 }
499
500 return $footer_text;
501 }
502
503 /**
504 * Delete the entire cache contents.
505 *
506 * @return void
507 */
508 public function boldblocks_purge_cache() {
509 $nonce = sanitize_text_field( wp_unslash( $_REQUEST['_cbb_purge'] ?? '' ) );
510 if ( wp_verify_nonce( $nonce, 'cbb_purce_nonce' ) ) {
511 $cbb = $this->the_plugin_instance;
512
513 // Library cache.
514 $cbb->get_component( Library::class )->clear_library_cache();
515
516 // Blocks.
517 $cbb->get_component( CustomBlocks::class )->clear_transient_cache();
518
519 // Variations.
520 $cbb->get_component( Variations::class )->clear_transient_cache();
521
522 // Patterns.
523 $cbb->get_component( Patterns::class )->clear_transient_cache();
524
525 // Docs.
526 $this->clear_transient_cache();
527
528 $this->is_purged_cache = 1;
529 }
530 }
531
532 /**
533 * Check if the core blocks have been deployed.
534 *
535 * @return boolean
536 */
537 private function is_deloyed_core_blocks() {
538 return get_option( 'cbb_deployed_core_blocks' ) || get_option( 'boldblocks_deployed_core_blocks' );
539 }
540
541 /**
542 * Get core blocks version.
543 *
544 * @return string
545 */
546 private function get_core_blocks_version() {
547 $core_blocks_version = get_option( 'cbb_core_blocks_version' );
548 if ( ! $core_blocks_version ) {
549 $core_blocks_version = get_option( 'boldblocks_core_blocks_version' );
550 }
551
552 return $core_blocks_version;
553 }
554
555 /**
556 * Register setting fields
557 *
558 * @return void
559 */
560 public function register_settings() {
561 // phpcs:disable PluginCheck.CodeAnalysis.SettingSanitization.register_settingDynamic
562 register_setting(
563 'cbb',
564 'cbb_keep_data',
565 [
566 'type' => 'boolean',
567 'sanitize_callback' => 'rest_sanitize_boolean',
568 'show_in_rest' => [
569 'name' => 'KeepDataOnUninstall',
570 ],
571 'default' => false,
572 ]
573 );
574 // phpcs:enable PluginCheck.CodeAnalysis.SettingSanitization.register_settingDynamic
575 }
576 }
577 endif;
578