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

570 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 ]
183 ),
184 'before'
185 );
186
187 // Enqueue style.
188 wp_enqueue_style(
189 $this->script_handle,
190 $this->the_plugin_instance->get_file_uri( 'build/settings.css' ),
191 [],
192 $this->the_plugin_instance->get_script_version( $settings_asset )
193 );
194
195 // Load components style.
196 wp_enqueue_style( 'wp-components' );
197 }
198 }
199
200 /**
201 * Run activated stuff
202 * https://wearnhardt.com/2020/03/redirecting-after-plugin-activation/
203 *
204 * @return void
205 */
206 public function run_the_plugin_setup() {
207 // Deploy core blocks.
208 if ( is_admin() && ! $this->is_deloyed_core_blocks() ) {
209 // Update core blocks.
210 $this->update_core_blocks();
211
212 // Add the marker to the settings to make sure this logic only runs one time.
213 add_option( 'cbb_deployed_core_blocks', 1 );
214 }
215
216 // Run the plugin setup.
217 do_action( 'cbb_plugin_setup', $this->the_plugin_instance );
218
219 // Redirect to the getting started page, ignore bulk activation.
220 if (
221 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
222 ! ( ( isset( $_REQUEST['action'] ) && 'activate-selected' === $_REQUEST['action'] ) &&
223 // phpcs:ignore WordPress.Security.NonceVerification.Missing
224 ( isset( $_POST['checked'] ) && count( $_POST['checked'] ) > 1 ) ) ) {
225 add_option( 'boldblocks_activation_redirect', wp_get_current_user()->ID );
226 }
227 }
228
229 /**
230 * Maybe update core blocks
231 *
232 * @return void
233 */
234 public function maybe_update_core_blocks() {
235 if ( is_admin() && current_user_can( 'manage_options' ) ) {
236 $core_blocks_version = $this->get_core_blocks_version();
237 if ( ! $core_blocks_version || $core_blocks_version !== $this->core_blocks_version ) {
238 $this->update_core_blocks( $core_blocks_version, $this->core_blocks_version );
239 }
240 }
241 }
242
243 /**
244 * Parse core blocks
245 *
246 * @return array
247 */
248 private function get_core_blocks() {
249 $core_blocks = false;
250 $core_blocks_file_path = $this->the_plugin_instance->get_file_path( 'data/core-blocks/blocks.json' );
251
252 if ( \file_exists( $core_blocks_file_path ) ) {
253 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
254 $core_blocks = \file_get_contents( $core_blocks_file_path );
255 $core_blocks = \json_decode( $core_blocks, true );
256 }
257
258 return $core_blocks;
259 }
260
261 /**
262 * Update core blocks
263 *
264 * @param string $prev_blocks_version
265 * @param string $next_blocks_version
266 * @return void
267 */
268 private function update_core_blocks( $prev_blocks_version = '', $next_blocks_version = '' ) {
269 if ( is_admin() ) {
270 $core_blocks_data = $this->get_core_blocks();
271
272 if ( $core_blocks_data ) {
273 $core_blocks = $core_blocks_data['blocks'] ?? [];
274
275 foreach ( $core_blocks as $block ) {
276 $name = $block['slug'] ?? '';
277 $found_posts = get_posts(
278 [
279 'post_type' => 'boldblocks_block',
280 'name' => $name,
281 'posts_per_page' => 1,
282 ]
283 );
284
285 // There is no block with that slug.
286 if ( ! ( is_array( $found_posts ) && count( $found_posts ) > 0 ) ) {
287 $title = $block['title'] ?? '';
288 $content = $block['content'] ?? '';
289 $meta = $block['meta'] ?? [];
290
291 // Insert new block.
292 $block_id = wp_insert_post(
293 [
294 'post_type' => 'boldblocks_block',
295 'post_title' => $title,
296 'post_content' => $content,
297 'post_name' => $name,
298 'post_status' => 'publish',
299 'meta_input' => $meta,
300 ]
301 );
302 } else {
303 $found_post = $found_posts[0];
304 $meta = $block['meta'] ?? [];
305
306 $updating_meta = [];
307 $title = $found_post->post_title ?? '';
308 $description = $meta['boldblocks_block_description'] ?? '';
309 if ( is_array( $description ) && count( $description ) > 0 ) {
310 $description = $description[0] ?? '';
311 }
312 $updating_meta['boldblocks_block_description'] = $description;
313 $icon = $meta['boldblocks_block_icon'] ?? '';
314 if ( is_array( $icon ) && count( $icon ) > 0 ) {
315 $icon = $icon[0] ?? '';
316 }
317 $updating_meta['boldblocks_block_icon'] = $icon;
318
319 $supports = $meta['boldblocks_block_supports'] ?? [];
320 if ( ! empty( $supports ) ) {
321 $updating_meta['boldblocks_block_supports'] = $supports;
322 }
323
324 if ( version_compare( $prev_blocks_version, '2.3.4', '<' ) ) {
325 $updating_meta['boldblocks_enable_custom_attributes'] = $meta['boldblocks_enable_custom_attributes'] ?? false;
326 }
327
328 // New transformable in 2.4.1.
329 if ( $meta['boldblocks_is_transformable'] ?? false ) {
330 $updating_meta['boldblocks_is_transformable'] = $meta['boldblocks_is_transformable'];
331 }
332
333 $enable_repeater = $meta['boldblocks_enable_repeater'] ?? '';
334 if ( is_array( $enable_repeater ) && count( $enable_repeater ) > 0 ) {
335 $enable_repeater = $enable_repeater[0] ?? '';
336 }
337
338 if ( $enable_repeater ) {
339 $parent_title = $meta['boldblocks_parent_block_title'] ?? '';
340 if ( is_array( $parent_title ) && count( $parent_title ) > 0 ) {
341 $parent_title = $parent_title[0] ?? '';
342 }
343 $updating_meta['boldblocks_parent_block_title'] = $parent_title;
344
345 $parent_description = $meta['boldblocks_parent_block_description'] ?? '';
346 if ( is_array( $parent_description ) && count( $parent_description ) > 0 ) {
347 $parent_description = $parent_description[0] ?? '';
348 }
349 $updating_meta['boldblocks_parent_block_description'] = $parent_description;
350
351 $parent_icon = $meta['boldblocks_parent_block_icon'] ?? '';
352 if ( is_array( $parent_icon ) && count( $parent_icon ) > 0 ) {
353 $parent_icon = $parent_icon[0] ?? '';
354 }
355 $updating_meta['boldblocks_parent_block_icon'] = $parent_icon;
356
357 $parent_supports = $meta['boldblocks_parent_block_supports'] ?? [];
358 if ( ! empty( $parent_supports ) ) {
359 $updating_meta['boldblocks_parent_block_supports'] = $parent_supports;
360 }
361
362 if ( version_compare( $prev_blocks_version, '2.3.4', '<' ) ) {
363 $updating_meta['boldblocks_parent_enable_custom_attributes'] = $meta['boldblocks_parent_enable_custom_attributes'] ?? false;
364 }
365 }
366
367 $updating_data = [
368 'ID' => $found_post->ID,
369 'post_title' => $block['title'] ?? '',
370 'meta_input' => $updating_meta,
371 ];
372
373 $post_id = wp_update_post( $updating_data );
374 }
375 }
376
377 update_option( 'cbb_core_blocks_version', $this->core_blocks_version );
378 }
379 }
380 }
381
382 /**
383 * Migrate legacy options
384 *
385 * @param string $prev_version
386 * @return void
387 */
388 public function migrate_legacy_options( $prev_version ) {
389 if ( version_compare( $prev_version, '2.7.8', '<=' ) ) {
390 $legacy_options = [
391 'boldblocks_pattern_categories' => 'cbb_pattern_categories',
392 'boldblocks_pattern_categories_all_label' => 'cbb_pattern_categories_all_label',
393 'boldblocks_typography' => 'cbb_typography',
394 'boldblocks_enable_typography' => 'cbb_enable_typography',
395 'boldblocks_use_bunny_fonts' => 'cbb_use_bunny_fonts',
396 ];
397
398 foreach ( $legacy_options as $old_option => $new_option ) {
399 $option_value = get_option( $old_option );
400 if ( $option_value ) {
401 update_option( $new_option, $option_value );
402 delete_option( $old_option );
403 }
404 }
405 }
406 }
407
408 /**
409 * Build a custom endpoint to query docs.
410 *
411 * @return void
412 */
413 public function register_docs_endpoint() {
414 register_rest_route(
415 'boldblocks/v1',
416 '/getDocs/',
417 array(
418 'methods' => 'GET',
419 'callback' => [ $this, 'get_docs' ],
420 'permission_callback' => function () {
421 return current_user_can( 'publish_posts' );
422 },
423 )
424 );
425 }
426
427 /**
428 * Get docs.
429 *
430 * @param WP_REST_Request $request The request object.
431 * @return void
432 */
433 public function get_docs( $request ) {
434 $cache_key = 'bb_docs';
435 $data = get_transient( $cache_key );
436 $library_component = $this->the_plugin_instance->get_component( Library::class );
437 $library_url = $library_component ? $library_component->get_library_url() : 'https://boldpatterns.net';
438
439 if ( false === $data ) {
440 $response = wp_remote_get(
441 $library_url . '/wp-json/api.boldblocks/v1/getDocs',
442 [
443 'timeout' => 120,
444 'sslverify' => false,
445 ]
446 );
447
448 if ( ! is_wp_error( $response ) ) {
449 $data = json_decode( wp_remote_retrieve_body( $response ), true );
450
451 if ( $data ) {
452 set_transient( $cache_key, $data, DAY_IN_SECONDS );
453 }
454 }
455 }
456
457 wp_send_json(
458 [
459 'data' => $data,
460 'success' => true,
461 ]
462 );
463 }
464
465 /**
466 * Clear transient cache
467 *
468 * @return void
469 */
470 public function clear_transient_cache() {
471 delete_transient( 'bb_docs' );
472 }
473
474 /**
475 * Change the footer text for the settings pages
476 *
477 * @param string $footer_text
478 * @return string
479 */
480 public function admin_footer_text( $footer_text ) {
481 // Get current screen.
482 $current_screen = get_current_screen();
483 if ( 'edit.php?post_type=boldblocks_block' === $current_screen->parent_file ) {
484 $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">�
485
486
487
488
489 </span></a> to help us spread the word. Thank you from the CBB team!</i>';
490 }
491
492 return $footer_text;
493 }
494
495 /**
496 * Delete the entire cache contents.
497 *
498 * @return void
499 */
500 public function boldblocks_purge_cache() {
501 $nonce = sanitize_text_field( wp_unslash( $_REQUEST['_cbb_purge'] ?? '' ) );
502 if ( wp_verify_nonce( $nonce, 'cbb_purce_nonce' ) ) {
503 $cbb = $this->the_plugin_instance;
504
505 // Library cache.
506 $cbb->get_component( Library::class )->clear_library_cache();
507
508 // Blocks.
509 $cbb->get_component( CustomBlocks::class )->clear_transient_cache();
510
511 // Variations.
512 $cbb->get_component( Variations::class )->clear_transient_cache();
513
514 // Patterns.
515 $cbb->get_component( Patterns::class )->clear_transient_cache();
516
517 // Docs.
518 $this->clear_transient_cache();
519
520 $this->is_purged_cache = 1;
521 }
522 }
523
524 /**
525 * Check if the core blocks have been deployed.
526 *
527 * @return boolean
528 */
529 private function is_deloyed_core_blocks() {
530 return get_option( 'cbb_deployed_core_blocks' ) || get_option( 'boldblocks_deployed_core_blocks' );
531 }
532
533 /**
534 * Get core blocks version.
535 *
536 * @return string
537 */
538 private function get_core_blocks_version() {
539 $core_blocks_version = get_option( 'cbb_core_blocks_version' );
540 if ( ! $core_blocks_version ) {
541 $core_blocks_version = get_option( 'boldblocks_core_blocks_version' );
542 }
543
544 return $core_blocks_version;
545 }
546
547 /**
548 * Register setting fields
549 *
550 * @return void
551 */
552 public function register_settings() {
553 // phpcs:disable PluginCheck.CodeAnalysis.SettingSanitization.register_settingDynamic
554 register_setting(
555 'cbb',
556 'cbb_keep_data',
557 [
558 'type' => 'boolean',
559 'sanitize_callback' => 'rest_sanitize_boolean',
560 'show_in_rest' => [
561 'name' => 'KeepDataOnUninstall',
562 ],
563 'default' => false,
564 ]
565 );
566 // phpcs:enable PluginCheck.CodeAnalysis.SettingSanitization.register_settingDynamic
567 }
568 }
569 endif;
570