PluginProbe
Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts / 2.8.3
Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts v2.8.3
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 2.8.3, at includes/settings.php

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