| 1 |
<?php |
| 2 |
/** |
| 3 |
* GutSlider admin dashboard bootstrap. |
| 4 |
* |
| 5 |
* Registers the admin menu, loads dashboard assets, and exposes the REST |
| 6 |
* endpoints used by the dashboard UI to persist changes. |
| 7 |
* |
| 8 |
* @package GutSliderBlocks |
| 9 |
*/ |
| 10 |
|
| 11 |
if ( ! defined( 'ABSPATH' ) ) { |
| 12 |
exit; |
| 13 |
} |
| 14 |
|
| 15 |
if ( ! class_exists( 'GutSlider_Admin' ) ) { |
| 16 |
|
| 17 |
/** |
| 18 |
* Admin dashboard controller. |
| 19 |
*/ |
| 20 |
class GutSlider_Admin { |
| 21 |
|
| 22 |
/** |
| 23 |
* Option key holding the general settings array. |
| 24 |
* |
| 25 |
* @var string |
| 26 |
*/ |
| 27 |
const SETTINGS_OPTION = 'gutslider_settings'; |
| 28 |
|
| 29 |
/** |
| 30 |
* Top level menu slug. |
| 31 |
* |
| 32 |
* @var string |
| 33 |
*/ |
| 34 |
const MENU_SLUG = 'gutslider-blocks'; |
| 35 |
|
| 36 |
/** |
| 37 |
* Page slug for the blocks manager. |
| 38 |
* |
| 39 |
* @var string |
| 40 |
*/ |
| 41 |
const BLOCKS_SLUG = 'gutslider-blocks-settings'; |
| 42 |
|
| 43 |
/** |
| 44 |
* Page slug for the settings screen. |
| 45 |
* |
| 46 |
* @var string |
| 47 |
*/ |
| 48 |
const SETTINGS_SLUG = 'gutslider-settings'; |
| 49 |
|
| 50 |
/** |
| 51 |
* Default values for the general settings. |
| 52 |
* |
| 53 |
* @var array<string, mixed> |
| 54 |
*/ |
| 55 |
private static $settings_defaults = array( |
| 56 |
'css_delivery' => 'file', |
| 57 |
'google_fonts' => true, |
| 58 |
'pattern_library' => true, |
| 59 |
'remove_data' => false, |
| 60 |
); |
| 61 |
|
| 62 |
/** |
| 63 |
* Constructor. |
| 64 |
*/ |
| 65 |
public function __construct() { |
| 66 |
add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 ); |
| 67 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) ); |
| 68 |
add_action( 'rest_api_init', array( $this, 'register_routes' ) ); |
| 69 |
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) ); |
| 70 |
add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ) ); |
| 71 |
} |
| 72 |
|
| 73 |
/* --------------------------------------------------------------- |
| 74 |
* Settings helpers |
| 75 |
* ------------------------------------------------------------- */ |
| 76 |
|
| 77 |
/** |
| 78 |
* Get the general settings, merged over the defaults. |
| 79 |
* |
| 80 |
* @return array<string, mixed> Settings array. |
| 81 |
*/ |
| 82 |
public static function get_settings() { |
| 83 |
$stored = get_option( self::SETTINGS_OPTION, array() ); |
| 84 |
|
| 85 |
if ( ! is_array( $stored ) ) { |
| 86 |
$stored = array(); |
| 87 |
} |
| 88 |
|
| 89 |
return wp_parse_args( $stored, self::$settings_defaults ); |
| 90 |
} |
| 91 |
|
| 92 |
/** |
| 93 |
* Get a single setting value. |
| 94 |
* |
| 95 |
* @param string $key Setting key. |
| 96 |
* @param mixed $default Fallback when the key is unknown. |
| 97 |
* @return mixed Setting value. |
| 98 |
*/ |
| 99 |
public static function get_setting( $key, $default = null ) { |
| 100 |
$settings = self::get_settings(); |
| 101 |
|
| 102 |
return array_key_exists( $key, $settings ) ? $settings[ $key ] : $default; |
| 103 |
} |
| 104 |
|
| 105 |
/** |
| 106 |
* Build the option key that stores a block's enabled state. |
| 107 |
* |
| 108 |
* @param string $block_name Block directory name. |
| 109 |
* @return string Option key. |
| 110 |
*/ |
| 111 |
public static function block_option_key( $block_name ) { |
| 112 |
return 'gut_' . str_replace( '-', '_', $block_name ); |
| 113 |
} |
| 114 |
|
| 115 |
/** |
| 116 |
* Read the block definitions from the shared data file. |
| 117 |
* |
| 118 |
* @return array<int, array<string, mixed>> Block definitions. |
| 119 |
*/ |
| 120 |
public function get_blocks() { |
| 121 |
$blocks_file = GUTSLIDER_DIR . '/includes/Api/blocks.php'; |
| 122 |
|
| 123 |
if ( ! file_exists( $blocks_file ) ) { |
| 124 |
return array(); |
| 125 |
} |
| 126 |
|
| 127 |
$blocks = include $blocks_file; |
| 128 |
|
| 129 |
return is_array( $blocks ) ? $blocks : array(); |
| 130 |
} |
| 131 |
|
| 132 |
/** |
| 133 |
* Decorate the block definitions with their current state. |
| 134 |
* |
| 135 |
* @return array<int, array<string, mixed>> Block definitions. |
| 136 |
*/ |
| 137 |
public function get_blocks_with_state() { |
| 138 |
$has_pro = defined( 'GUTSLIDER_PRO_VERSION' ); |
| 139 |
$blocks = array(); |
| 140 |
|
| 141 |
foreach ( $this->get_blocks() as $block ) { |
| 142 |
$is_pro = ! empty( $block['is_pro'] ); |
| 143 |
|
| 144 |
$block['is_pro'] = $is_pro; |
| 145 |
$block['locked'] = $is_pro && ! $has_pro; |
| 146 |
$block['option_key'] = self::block_option_key( $block['name'] ); |
| 147 |
$block['enabled'] = $block['locked'] |
| 148 |
? false |
| 149 |
: (bool) get_option( $block['option_key'], true ); |
| 150 |
|
| 151 |
$blocks[] = $block; |
| 152 |
} |
| 153 |
|
| 154 |
return $blocks; |
| 155 |
} |
| 156 |
|
| 157 |
/** |
| 158 |
* Count how many blocks are currently enabled. |
| 159 |
* |
| 160 |
* @param array<int, array<string, mixed>> $blocks Decorated blocks. |
| 161 |
* @return int Enabled block count. |
| 162 |
*/ |
| 163 |
public static function count_enabled( array $blocks ) { |
| 164 |
$count = 0; |
| 165 |
|
| 166 |
foreach ( $blocks as $block ) { |
| 167 |
if ( ! empty( $block['enabled'] ) ) { |
| 168 |
++$count; |
| 169 |
} |
| 170 |
} |
| 171 |
|
| 172 |
return $count; |
| 173 |
} |
| 174 |
|
| 175 |
/* --------------------------------------------------------------- |
| 176 |
* Menu + assets |
| 177 |
* ------------------------------------------------------------- */ |
| 178 |
|
| 179 |
/** |
| 180 |
* Register the admin menu and its sub pages. |
| 181 |
* |
| 182 |
* @return void |
| 183 |
*/ |
| 184 |
public function admin_menu() { |
| 185 |
$icon = 'data:image/svg+xml;base64,' . base64_encode( '<svg width="20" height="20" viewBox="0 0 45 45" xmlns="http://www.w3.org/2000/svg"><path fill="black" d="M5 45C3.625 45 2.44833 44.5108 1.47 43.5325C0.491667 42.5542 0.00166667 41.3767 0 40V5C0 3.625 0.49 2.44833 1.47 1.47C2.45 0.491667 3.62667 0.00166667 5 0H40C41.375 0 42.5525 0.49 43.5325 1.47C44.5125 2.45 45.0017 3.62667 45 5V40C45 41.375 44.5108 42.5525 43.5325 43.5325C42.5542 44.5125 41.3767 45.0017 40 45H5ZM17.5 35H27.5C28.875 35 30.0525 34.5108 31.0325 33.5325C32.0125 32.5542 32.5017 31.3767 32.5 30V20H22.5V25H27.5V30H17.5V15H32.5C32.5 13.625 32.0108 12.4483 31.0325 11.47C30.0542 10.4917 28.8767 10.0017 27.5 10H17.5C16.125 10 14.9483 10.49 13.97 11.47C12.9917 12.45 12.5017 13.6267 12.5 15V30C12.5 31.375 12.99 32.5525 13.97 33.5325C14.95 34.5125 16.1267 35.0017 17.5 35Z"/></svg>' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Inline menu icon. |
| 186 |
|
| 187 |
add_menu_page( |
| 188 |
__( 'GutSlider', 'slider-blocks' ), |
| 189 |
__( 'GutSlider', 'slider-blocks' ), |
| 190 |
'manage_options', |
| 191 |
self::MENU_SLUG, |
| 192 |
array( $this, 'render_dashboard_page' ), |
| 193 |
$icon, |
| 194 |
100 |
| 195 |
); |
| 196 |
|
| 197 |
add_submenu_page( |
| 198 |
self::MENU_SLUG, |
| 199 |
__( 'Dashboard', 'slider-blocks' ), |
| 200 |
__( 'Dashboard', 'slider-blocks' ), |
| 201 |
'manage_options', |
| 202 |
self::MENU_SLUG, |
| 203 |
array( $this, 'render_dashboard_page' ) |
| 204 |
); |
| 205 |
|
| 206 |
add_submenu_page( |
| 207 |
self::MENU_SLUG, |
| 208 |
__( 'Blocks', 'slider-blocks' ), |
| 209 |
__( 'Blocks', 'slider-blocks' ), |
| 210 |
'manage_options', |
| 211 |
self::BLOCKS_SLUG, |
| 212 |
array( $this, 'render_blocks_page' ) |
| 213 |
); |
| 214 |
|
| 215 |
add_submenu_page( |
| 216 |
self::MENU_SLUG, |
| 217 |
__( 'Settings', 'slider-blocks' ), |
| 218 |
__( 'Settings', 'slider-blocks' ), |
| 219 |
'manage_options', |
| 220 |
self::SETTINGS_SLUG, |
| 221 |
array( $this, 'render_settings_page' ) |
| 222 |
); |
| 223 |
} |
| 224 |
|
| 225 |
/** |
| 226 |
* Screen IDs that should receive the dashboard assets. |
| 227 |
* |
| 228 |
* @return array<int, string> Screen IDs. |
| 229 |
*/ |
| 230 |
public static function screen_ids() { |
| 231 |
return array( |
| 232 |
'toplevel_page_' . self::MENU_SLUG, |
| 233 |
'gutslider_page_' . self::BLOCKS_SLUG, |
| 234 |
'gutslider_page_' . self::SETTINGS_SLUG, |
| 235 |
'gutslider_page_gutslider-license', |
| 236 |
); |
| 237 |
} |
| 238 |
|
| 239 |
/** |
| 240 |
* Whether the current request is a GutSlider dashboard screen. |
| 241 |
* |
| 242 |
* @param string $screen Current screen ID. |
| 243 |
* @return bool True on a dashboard screen. |
| 244 |
*/ |
| 245 |
public static function is_dashboard_screen( $screen = '' ) { |
| 246 |
if ( '' === $screen ) { |
| 247 |
$current = function_exists( 'get_current_screen' ) ? get_current_screen() : null; |
| 248 |
$screen = $current ? $current->id : ''; |
| 249 |
} |
| 250 |
|
| 251 |
return in_array( $screen, self::screen_ids(), true ); |
| 252 |
} |
| 253 |
|
| 254 |
/** |
| 255 |
* Enqueue the dashboard stylesheet and script. |
| 256 |
* |
| 257 |
* @param string $screen Current screen ID. |
| 258 |
* @return void |
| 259 |
*/ |
| 260 |
public function admin_assets( $screen ) { |
| 261 |
if ( ! self::is_dashboard_screen( $screen ) ) { |
| 262 |
return; |
| 263 |
} |
| 264 |
|
| 265 |
wp_enqueue_style( |
| 266 |
'gutslider-admin', |
| 267 |
GUTSLIDER_URL . 'admin/css/admin.css', |
| 268 |
array(), |
| 269 |
GUTSLIDER_VERSION |
| 270 |
); |
| 271 |
|
| 272 |
wp_enqueue_script( |
| 273 |
'gutslider-admin', |
| 274 |
GUTSLIDER_URL . 'admin/js/admin.js', |
| 275 |
array( 'wp-i18n' ), |
| 276 |
GUTSLIDER_VERSION, |
| 277 |
true |
| 278 |
); |
| 279 |
|
| 280 |
wp_localize_script( |
| 281 |
'gutslider-admin', |
| 282 |
'gutslider', |
| 283 |
array( |
| 284 |
'version' => GUTSLIDER_VERSION, |
| 285 |
'isPro' => defined( 'GUTSLIDER_PRO_VERSION' ), |
| 286 |
'proVersion' => defined( 'GUTSLIDER_PRO_VERSION' ) ? GUTSLIDER_PRO_VERSION : '', |
| 287 |
'restUrl' => esc_url_raw( rest_url( 'gutslider/v1/' ) ), |
| 288 |
'nonce' => wp_create_nonce( 'wp_rest' ), |
| 289 |
'pricingUrl' => 'https://gutslider.com/pricing', |
| 290 |
'i18n' => array( |
| 291 |
'saved' => __( 'Changes saved', 'slider-blocks' ), |
| 292 |
'saveFailed' => __( 'Could not save. Please try again.', 'slider-blocks' ), |
| 293 |
'discarded' => __( 'Changes discarded', 'slider-blocks' ), |
| 294 |
'cacheCleared' => __( 'Style cache cleared', 'slider-blocks' ), |
| 295 |
/* translators: %d: number of unsaved changes. */ |
| 296 |
'changeSingle' => __( '%d unsaved change', 'slider-blocks' ), |
| 297 |
/* translators: %d: number of unsaved changes. */ |
| 298 |
'changePlural' => __( '%d unsaved changes', 'slider-blocks' ), |
| 299 |
'leaveWarning' => __( 'You have unsaved changes.', 'slider-blocks' ), |
| 300 |
/* translators: 1: enabled block count, 2: total block count. */ |
| 301 |
'enabledCount' => __( '%1$d of %2$d enabled', 'slider-blocks' ), |
| 302 |
), |
| 303 |
) |
| 304 |
); |
| 305 |
} |
| 306 |
|
| 307 |
/** |
| 308 |
* Add a marker class so the stylesheet can reset the admin chrome. |
| 309 |
* |
| 310 |
* @param string $classes Existing body classes. |
| 311 |
* @return string Filtered body classes. |
| 312 |
*/ |
| 313 |
public function admin_body_class( $classes ) { |
| 314 |
if ( self::is_dashboard_screen() ) { |
| 315 |
$classes .= ' gutslider-admin-page '; |
| 316 |
} |
| 317 |
|
| 318 |
return $classes; |
| 319 |
} |
| 320 |
|
| 321 |
/** |
| 322 |
* Replace the admin footer credit on dashboard screens. |
| 323 |
* |
| 324 |
* @param string $text Default footer text. |
| 325 |
* @return string Filtered footer text. |
| 326 |
*/ |
| 327 |
public function admin_footer_text( $text ) { |
| 328 |
if ( ! self::is_dashboard_screen() ) { |
| 329 |
return $text; |
| 330 |
} |
| 331 |
|
| 332 |
return sprintf( |
| 333 |
/* translators: %s: link to the review page. */ |
| 334 |
esc_html__( 'Enjoying GutSlider? %s on WordPress.org.', 'slider-blocks' ), |
| 335 |
'<a href="https://wordpress.org/support/plugin/slider-blocks/reviews/" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Leave a review', 'slider-blocks' ) . '</a>' |
| 336 |
); |
| 337 |
} |
| 338 |
|
| 339 |
/* --------------------------------------------------------------- |
| 340 |
* Views |
| 341 |
* ------------------------------------------------------------- */ |
| 342 |
|
| 343 |
/** |
| 344 |
* Load a dashboard view. |
| 345 |
* |
| 346 |
* @param string $view View file name without extension. |
| 347 |
* @param array<string, mixed> $args Variables exposed to the view. |
| 348 |
* @return void |
| 349 |
*/ |
| 350 |
private function view( $view, array $args = array() ) { |
| 351 |
$file = GUTSLIDER_DIR . '/admin/views/' . $view . '.php'; |
| 352 |
|
| 353 |
if ( ! file_exists( $file ) ) { |
| 354 |
return; |
| 355 |
} |
| 356 |
|
| 357 |
$admin = $this; |
| 358 |
$has_pro = defined( 'GUTSLIDER_PRO_VERSION' ); |
| 359 |
|
| 360 |
// phpcs:ignore WordPress.PHP.DontExtract.extract_extract -- Controlled, internal view data. |
| 361 |
extract( $args, EXTR_SKIP ); |
| 362 |
|
| 363 |
include $file; |
| 364 |
} |
| 365 |
|
| 366 |
/** |
| 367 |
* Render the dashboard (overview) screen. |
| 368 |
* |
| 369 |
* @return void |
| 370 |
*/ |
| 371 |
public function render_dashboard_page() { |
| 372 |
$blocks = $this->get_blocks_with_state(); |
| 373 |
|
| 374 |
$this->view( |
| 375 |
'dashboard', |
| 376 |
array( |
| 377 |
'blocks' => $blocks, |
| 378 |
'total' => count( $blocks ), |
| 379 |
'enabled' => self::count_enabled( $blocks ), |
| 380 |
'current' => self::MENU_SLUG, |
| 381 |
) |
| 382 |
); |
| 383 |
} |
| 384 |
|
| 385 |
/** |
| 386 |
* Render the blocks manager screen. |
| 387 |
* |
| 388 |
* @return void |
| 389 |
*/ |
| 390 |
public function render_blocks_page() { |
| 391 |
$blocks = $this->get_blocks_with_state(); |
| 392 |
|
| 393 |
$this->view( |
| 394 |
'blocks', |
| 395 |
array( |
| 396 |
'blocks' => $blocks, |
| 397 |
'total' => count( $blocks ), |
| 398 |
'enabled' => self::count_enabled( $blocks ), |
| 399 |
'current' => self::BLOCKS_SLUG, |
| 400 |
) |
| 401 |
); |
| 402 |
} |
| 403 |
|
| 404 |
/** |
| 405 |
* Render the settings screen. |
| 406 |
* |
| 407 |
* @return void |
| 408 |
*/ |
| 409 |
public function render_settings_page() { |
| 410 |
$this->view( |
| 411 |
'settings', |
| 412 |
array( |
| 413 |
'settings' => self::get_settings(), |
| 414 |
'current' => self::SETTINGS_SLUG, |
| 415 |
) |
| 416 |
); |
| 417 |
} |
| 418 |
|
| 419 |
/* --------------------------------------------------------------- |
| 420 |
* REST endpoints |
| 421 |
* ------------------------------------------------------------- */ |
| 422 |
|
| 423 |
/** |
| 424 |
* Register the dashboard REST routes. |
| 425 |
* |
| 426 |
* @return void |
| 427 |
*/ |
| 428 |
public function register_routes() { |
| 429 |
register_rest_route( |
| 430 |
'gutslider/v1', |
| 431 |
'/dashboard/blocks', |
| 432 |
array( |
| 433 |
'methods' => WP_REST_Server::CREATABLE, |
| 434 |
'callback' => array( $this, 'rest_save_blocks' ), |
| 435 |
'permission_callback' => array( $this, 'can_manage' ), |
| 436 |
'args' => array( |
| 437 |
'blocks' => array( |
| 438 |
'required' => true, |
| 439 |
'type' => 'object', |
| 440 |
), |
| 441 |
), |
| 442 |
) |
| 443 |
); |
| 444 |
|
| 445 |
register_rest_route( |
| 446 |
'gutslider/v1', |
| 447 |
'/dashboard/settings', |
| 448 |
array( |
| 449 |
'methods' => WP_REST_Server::CREATABLE, |
| 450 |
'callback' => array( $this, 'rest_save_settings' ), |
| 451 |
'permission_callback' => array( $this, 'can_manage' ), |
| 452 |
'args' => array( |
| 453 |
'settings' => array( |
| 454 |
'required' => true, |
| 455 |
'type' => 'object', |
| 456 |
), |
| 457 |
), |
| 458 |
) |
| 459 |
); |
| 460 |
|
| 461 |
register_rest_route( |
| 462 |
'gutslider/v1', |
| 463 |
'/dashboard/clear-cache', |
| 464 |
array( |
| 465 |
'methods' => WP_REST_Server::CREATABLE, |
| 466 |
'callback' => array( $this, 'rest_clear_cache' ), |
| 467 |
'permission_callback' => array( $this, 'can_manage' ), |
| 468 |
) |
| 469 |
); |
| 470 |
} |
| 471 |
|
| 472 |
/** |
| 473 |
* Permission callback for the dashboard routes. |
| 474 |
* |
| 475 |
* @return bool True when the user may manage options. |
| 476 |
*/ |
| 477 |
public function can_manage() { |
| 478 |
return current_user_can( 'manage_options' ); |
| 479 |
} |
| 480 |
|
| 481 |
/** |
| 482 |
* Persist the enabled state of one or more blocks. |
| 483 |
* |
| 484 |
* Writes both the per-block option consumed by the block registrar |
| 485 |
* and the `active` flag on the cached block list, keeping the two |
| 486 |
* storage formats in sync. |
| 487 |
* |
| 488 |
* @param WP_REST_Request $request Incoming request. |
| 489 |
* @return WP_REST_Response|WP_Error Response payload. |
| 490 |
*/ |
| 491 |
public function rest_save_blocks( WP_REST_Request $request ) { |
| 492 |
$requested = $request->get_param( 'blocks' ); |
| 493 |
|
| 494 |
if ( ! is_array( $requested ) || empty( $requested ) ) { |
| 495 |
return new WP_Error( |
| 496 |
'gutslider_invalid_payload', |
| 497 |
__( 'No block changes were supplied.', 'slider-blocks' ), |
| 498 |
array( 'status' => 400 ) |
| 499 |
); |
| 500 |
} |
| 501 |
|
| 502 |
$has_pro = defined( 'GUTSLIDER_PRO_VERSION' ); |
| 503 |
$known = array(); |
| 504 |
|
| 505 |
foreach ( $this->get_blocks() as $block ) { |
| 506 |
$known[ $block['name'] ] = ! empty( $block['is_pro'] ); |
| 507 |
} |
| 508 |
|
| 509 |
$saved = array(); |
| 510 |
|
| 511 |
foreach ( $requested as $name => $enabled ) { |
| 512 |
$name = sanitize_text_field( (string) $name ); |
| 513 |
|
| 514 |
if ( ! isset( $known[ $name ] ) ) { |
| 515 |
continue; |
| 516 |
} |
| 517 |
|
| 518 |
// Pro blocks cannot be enabled without the Pro plugin. |
| 519 |
if ( $known[ $name ] && ! $has_pro ) { |
| 520 |
continue; |
| 521 |
} |
| 522 |
|
| 523 |
$enabled = rest_sanitize_boolean( $enabled ); |
| 524 |
|
| 525 |
/* |
| 526 |
* Store '1'/'0' rather than a boolean: update_option() treats a |
| 527 |
* `false` value as identical to a missing option and skips the |
| 528 |
* write, which would silently drop the first "disable" of a |
| 529 |
* block that has never been toggled before. |
| 530 |
*/ |
| 531 |
update_option( self::block_option_key( $name ), $enabled ? '1' : '0' ); |
| 532 |
$saved[ $name ] = $enabled; |
| 533 |
} |
| 534 |
|
| 535 |
$this->sync_block_list( $saved ); |
| 536 |
|
| 537 |
return rest_ensure_response( |
| 538 |
array( |
| 539 |
'success' => true, |
| 540 |
'blocks' => $saved, |
| 541 |
) |
| 542 |
); |
| 543 |
} |
| 544 |
|
| 545 |
/** |
| 546 |
* Mirror enabled states onto the cached `gutslider_blocks` option. |
| 547 |
* |
| 548 |
* @param array<string, bool> $saved Map of block name to enabled state. |
| 549 |
* @return void |
| 550 |
*/ |
| 551 |
private function sync_block_list( array $saved ) { |
| 552 |
if ( empty( $saved ) ) { |
| 553 |
return; |
| 554 |
} |
| 555 |
|
| 556 |
$blocks = get_option( 'gutslider_blocks' ); |
| 557 |
|
| 558 |
if ( ! is_array( $blocks ) || empty( $blocks ) ) { |
| 559 |
return; |
| 560 |
} |
| 561 |
|
| 562 |
$changed = false; |
| 563 |
|
| 564 |
foreach ( $blocks as $index => $block ) { |
| 565 |
if ( isset( $block['name'], $saved[ $block['name'] ] ) ) { |
| 566 |
$blocks[ $index ]['active'] = $saved[ $block['name'] ]; |
| 567 |
$changed = true; |
| 568 |
} |
| 569 |
} |
| 570 |
|
| 571 |
if ( $changed ) { |
| 572 |
update_option( 'gutslider_blocks', $blocks ); |
| 573 |
} |
| 574 |
} |
| 575 |
|
| 576 |
/** |
| 577 |
* Persist the general settings. |
| 578 |
* |
| 579 |
* @param WP_REST_Request $request Incoming request. |
| 580 |
* @return WP_REST_Response|WP_Error Response payload. |
| 581 |
*/ |
| 582 |
public function rest_save_settings( WP_REST_Request $request ) { |
| 583 |
$incoming = $request->get_param( 'settings' ); |
| 584 |
|
| 585 |
if ( ! is_array( $incoming ) ) { |
| 586 |
return new WP_Error( |
| 587 |
'gutslider_invalid_payload', |
| 588 |
__( 'No settings were supplied.', 'slider-blocks' ), |
| 589 |
array( 'status' => 400 ) |
| 590 |
); |
| 591 |
} |
| 592 |
|
| 593 |
$settings = self::get_settings(); |
| 594 |
$previous_delivery = $settings['css_delivery']; |
| 595 |
|
| 596 |
if ( isset( $incoming['css_delivery'] ) ) { |
| 597 |
$settings['css_delivery'] = in_array( $incoming['css_delivery'], array( 'file', 'inline' ), true ) |
| 598 |
? $incoming['css_delivery'] |
| 599 |
: 'file'; |
| 600 |
} |
| 601 |
|
| 602 |
if ( isset( $incoming['google_fonts'] ) ) { |
| 603 |
$settings['google_fonts'] = rest_sanitize_boolean( $incoming['google_fonts'] ); |
| 604 |
} |
| 605 |
|
| 606 |
if ( isset( $incoming['pattern_library'] ) ) { |
| 607 |
$settings['pattern_library'] = rest_sanitize_boolean( $incoming['pattern_library'] ); |
| 608 |
} |
| 609 |
|
| 610 |
if ( isset( $incoming['remove_data'] ) ) { |
| 611 |
$settings['remove_data'] = rest_sanitize_boolean( $incoming['remove_data'] ); |
| 612 |
} |
| 613 |
|
| 614 |
update_option( self::SETTINGS_OPTION, $settings ); |
| 615 |
|
| 616 |
/* |
| 617 |
* Switching to inline delivery leaves the previously generated |
| 618 |
* stylesheets orphaned in the uploads directory, so clear them out. |
| 619 |
*/ |
| 620 |
if ( 'inline' === $settings['css_delivery'] && 'inline' !== $previous_delivery ) { |
| 621 |
self::delete_generated_css(); |
| 622 |
} |
| 623 |
|
| 624 |
return rest_ensure_response( |
| 625 |
array( |
| 626 |
'success' => true, |
| 627 |
'settings' => $settings, |
| 628 |
) |
| 629 |
); |
| 630 |
} |
| 631 |
|
| 632 |
/** |
| 633 |
* Delete every generated stylesheet in the uploads directory. |
| 634 |
* |
| 635 |
* @return WP_REST_Response Response payload. |
| 636 |
*/ |
| 637 |
public function rest_clear_cache() { |
| 638 |
return rest_ensure_response( |
| 639 |
array( |
| 640 |
'success' => true, |
| 641 |
'deleted' => self::delete_generated_css(), |
| 642 |
) |
| 643 |
); |
| 644 |
} |
| 645 |
|
| 646 |
/** |
| 647 |
* Remove all generated stylesheets from the uploads directory. |
| 648 |
* |
| 649 |
* @return int Number of files deleted. |
| 650 |
*/ |
| 651 |
private static function delete_generated_css() { |
| 652 |
$upload_dir = wp_upload_dir(); |
| 653 |
$css_dir = trailingslashit( $upload_dir['basedir'] ) . 'gutslider-styles'; |
| 654 |
$deleted = 0; |
| 655 |
|
| 656 |
if ( is_dir( $css_dir ) ) { |
| 657 |
$files = glob( $css_dir . '/*.css' ); |
| 658 |
|
| 659 |
if ( is_array( $files ) ) { |
| 660 |
foreach ( $files as $file ) { |
| 661 |
if ( is_file( $file ) && wp_delete_file_from_directory( $file, $css_dir ) ) { |
| 662 |
++$deleted; |
| 663 |
} |
| 664 |
} |
| 665 |
} |
| 666 |
} |
| 667 |
|
| 668 |
return $deleted; |
| 669 |
} |
| 670 |
} |
| 671 |
} |
| 672 |
|
| 673 |
new GutSlider_Admin(); |
| 674 |
|