PluginProbe
GutSlider – All in One Slider and Carousel Blocks for Gutenberg / trunk
GutSlider – All in One Slider and Carousel Blocks for Gutenberg vtrunk
3.1.0 3.0.0 2.13.2 2.13.1 2.13.0 trunk 1.0.0 2.1.0 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.2.1 2.2.2 2.3.0 2.4.0 2.5.1 2.5.3 2.5.4 2.5.5 2.6.1 All 56 releases
slider-blocks / includes / Api / BlocksApi.php

BlocksApi.php in GutSlider – All in One Slider and Carousel Blocks for Gutenberg trunk, at includes/Api/BlocksApi.php

234 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 declare( strict_types=1 );
3
4 namespace GutSlider\Api;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 /**
11 * REST API controller for managing GutSlider block settings.
12 *
13 * Provides endpoints for retrieving block definitions and updating
14 * individual block enabled/disabled status via the WordPress REST API.
15 *
16 * @package GutSlider\Api
17 * @since 3.0.0
18 */
19 final class BlocksApi {
20
21 /**
22 * Constructor.
23 *
24 * Registers WordPress hooks for REST API routes and default block syncing.
25 *
26 * @since 3.0.0
27 */
28 public function __construct() {
29 add_action( 'rest_api_init', array( $this, 'register_endpoints' ) );
30 add_action( 'init', array( $this, 'save_default_blocks' ) );
31 }
32
33 /**
34 * Register REST API endpoints.
35 *
36 * Creates separate GET and POST routes for the blocks endpoint
37 * with appropriate permission callbacks and argument schemas.
38 *
39 * @since 3.0.0
40 *
41 * @return void
42 */
43 public function register_endpoints(): void {
44 register_rest_route(
45 'gutslider/v1',
46 '/blocks',
47 array(
48 array(
49 'methods' => \WP_REST_Server::READABLE,
50 'callback' => array( $this, 'get_blocks' ),
51 'permission_callback' => array( $this, 'check_read_permission' ),
52 ),
53 array(
54 'methods' => \WP_REST_Server::CREATABLE,
55 'callback' => array( $this, 'update_block_status' ),
56 'permission_callback' => array( $this, 'check_write_permission' ),
57 'args' => array(
58 'nonce' => array(
59 'required' => true,
60 'type' => 'string',
61 'sanitize_callback' => 'sanitize_text_field',
62 ),
63 'name' => array(
64 'type' => 'string',
65 'sanitize_callback' => 'sanitize_text_field',
66 ),
67 'names' => array(
68 'type' => 'array',
69 'items' => array( 'type' => 'string' ),
70 ),
71 'active' => array(
72 'required' => true,
73 'type' => 'boolean',
74 ),
75 ),
76 ),
77 )
78 );
79 }
80
81 /**
82 * Retrieve all block definitions.
83 *
84 * @since 3.0.0
85 *
86 * @return \WP_REST_Response Block definitions array wrapped in a REST response.
87 */
88 public function get_blocks(): \WP_REST_Response {
89 return rest_ensure_response( get_option( 'gutslider_blocks' ) );
90 }
91
92 /**
93 * Update the active status of one or more blocks.
94 *
95 * Accepts a single block name or an array of block names and sets
96 * their active status. Protected by nonce verification.
97 *
98 * @since 3.0.0
99 *
100 * @param \WP_REST_Request $request The REST request object.
101 * @return \WP_REST_Response|\WP_Error Updated blocks or error response.
102 */
103 public function update_block_status( \WP_REST_Request $request ) {
104 $nonce = $request->get_param( 'nonce' );
105
106 if ( ! is_string( $nonce ) || ! wp_verify_nonce( $nonce, 'gutslider_nonce' ) ) {
107 return new \WP_Error(
108 'invalid_nonce',
109 __( 'Invalid security token.', 'slider-blocks' ),
110 array( 'status' => 403 )
111 );
112 }
113
114 $single_block_name = $request->get_param( 'name' );
115 $block_names = $request->get_param( 'names' );
116 $active_status = (bool) $request->get_param( 'active' );
117
118 if ( ! empty( $single_block_name ) ) {
119 $block_names = array( sanitize_text_field( (string) $single_block_name ) );
120 } elseif ( is_array( $block_names ) ) {
121 $block_names = array_map( 'sanitize_text_field', $block_names );
122 } else {
123 return new \WP_Error(
124 'invalid_request',
125 __( 'Invalid block name(s) provided.', 'slider-blocks' ),
126 array( 'status' => 400 )
127 );
128 }
129
130 $blocks = get_option( 'gutslider_blocks' );
131
132 if ( ! is_array( $blocks ) ) {
133 return new \WP_Error(
134 'no_blocks',
135 __( 'No blocks found.', 'slider-blocks' ),
136 array( 'status' => 404 )
137 );
138 }
139
140 foreach ( $blocks as &$block ) {
141 if ( in_array( $block['name'], $block_names, true ) ) {
142 $block['active'] = $active_status;
143 }
144 }
145 unset( $block );
146
147 update_option( 'gutslider_blocks', $blocks );
148
149 return rest_ensure_response( $blocks );
150 }
151
152 /**
153 * Check read permission for the blocks endpoint.
154 *
155 * @since 3.0.0
156 *
157 * @return bool Whether the current user can read block data.
158 */
159 public function check_read_permission(): bool {
160 return current_user_can( 'edit_posts' );
161 }
162
163 /**
164 * Check write permission for the blocks endpoint.
165 *
166 * @since 3.0.0
167 *
168 * @return bool Whether the current user can modify block settings.
169 */
170 public function check_write_permission(): bool {
171 return current_user_can( 'manage_options' );
172 }
173
174 /**
175 * Synchronize default block definitions with stored options.
176 *
177 * Merges new block definitions with existing stored blocks while
178 * preserving user-set active statuses. Only runs when the plugin
179 * version changes to avoid unnecessary database writes.
180 *
181 * @since 3.0.0
182 *
183 * @return void
184 */
185 public function save_default_blocks(): void {
186 $saved_version = get_option( 'gutslider_blocks_version', '' );
187
188 if ( $saved_version === GUTSLIDER_VERSION ) {
189 return;
190 }
191
192 $existing_blocks = get_option( 'gutslider_blocks', array() );
193
194 if ( ! is_array( $existing_blocks ) ) {
195 $existing_blocks = array();
196 }
197
198 $new_blocks = $this->get_gutslider_blocks();
199 $merged_blocks = array();
200
201 foreach ( $new_blocks as $new_block ) {
202 $found = false;
203
204 foreach ( $existing_blocks as $existing_block ) {
205 if ( $existing_block['name'] === $new_block['name'] ) {
206 $merged_blocks[] = array_merge( $new_block, array( 'active' => $existing_block['active'] ) );
207 $found = true;
208 break;
209 }
210 }
211
212 if ( ! $found ) {
213 $merged_blocks[] = $new_block;
214 }
215 }
216
217 $merged_blocks = array_values( $merged_blocks );
218
219 update_option( 'gutslider_blocks', $merged_blocks );
220 update_option( 'gutslider_blocks_version', GUTSLIDER_VERSION );
221 }
222
223 /**
224 * Get the default GutSlider block definitions from the data file.
225 *
226 * @since 3.0.0
227 *
228 * @return array<int, array<string, mixed>> Array of block definition arrays.
229 */
230 private function get_gutslider_blocks(): array {
231 return require GUTSLIDER_DIR_PATH . 'includes/Api/blocks.php';
232 }
233 }
234