PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.15.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.15.0
2.15.0 2.14.0 2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 All 82 releases
← All changes | includes/ajax/settings.php +145 -16 2.10.0 → 2.15.0 View file →
@@ -7,10 +7,12 @@
7 7 }
8 8
9 9 use ABlocks\Classes\AbstractAjaxHandler;
10 10 use ABlocks\Classes\Sanitizer;
11 +use ABlocks\Classes\Breakpoints;
11 12 use ABlocks\Helper;
12 13 use ABlocks\Admin\Settings\Base as BaseSettings;
14 +use ABlocks\Permissions\SettingsGuard;
13 15
14 16 class Settings extends AbstractAjaxHandler {
15 17 public function __construct() {
16 18 $this->actions = array(
@@ -15,13 +17,13 @@
15 17 public function __construct() {
16 18 $this->actions = array(
17 19 'get_blocks_visibility' => array(
18 20 'callback' => array( $this, 'get_blocks_visibility' ),
19 - 'capability' => 'manage_options'
21 + 'capability' => 'ablocks_manage_settings'
20 22 ),
21 23 'save_block_visibility' => array(
22 24 'callback' => array( $this, 'save_block_visibility' ),
23 - 'capability' => 'manage_options',
25 + 'capability' => 'ablocks_manage_settings',
24 26 'fields' => array(
25 27 'block_name' => 'string',
26 28 'status' => 'boolean',
27 29 )
@@ -27,9 +29,9 @@
27 29 )
28 30 ),
29 31 'save_bulk_block_visibility' => array(
30 32 'callback' => array( $this, 'save_bulk_block_visibility' ),
31 - 'capability' => 'manage_options',
33 + 'capability' => 'ablocks_manage_settings',
32 34 'fields' => array(
33 35 'blocks' => 'json',
34 36 )
35 37 ),
@@ -34,13 +36,13 @@
34 36 )
35 37 ),
36 38 'get_settings' => array(
37 39 'callback' => array( $this, 'get_settings' ),
38 - 'capability' => 'manage_options',
40 + 'capability' => 'ablocks_access',
39 41 ),
40 42 'save_settings' => array(
41 43 'callback' => array( $this, 'save_settings' ),
42 - 'capability' => 'manage_options',
44 + 'capability' => 'ablocks_save_settings',
43 45 'fields' => array(
44 46 'default_container_width' => 'integer',
45 47 'container_padding' => 'integer',
46 48 'container_element_gap' => 'integer',
@@ -45,10 +47,14 @@
45 47 'container_padding' => 'integer',
46 48 'container_element_gap' => 'integer',
47 49 'enabled_assets_file_generation' => 'boolean',
48 50 'enabled_block_copy_paste_style' => 'boolean',
51 + 'lock_global_typography' => 'boolean',
52 + 'lock_global_typography_strict' => 'boolean',
53 + 'lock_global_colors' => 'boolean',
49 54 'enabled_load_google_font_locally' => 'boolean',
50 55 'enabled_only_selected_fonts' => 'boolean',
56 + 'font_metric_fallback' => 'boolean',
51 57 'enabled_coming_soon_page' => 'boolean',
52 58 'coming_soon_page' => 'integer',
53 59 'enabled_maintenance_page' => 'boolean',
54 60 'maintenance_page' => 'integer',
@@ -63,9 +69,16 @@
63 69 'mailerlite_api_key' => 'string',
64 70 // Performance Suite
65 71 'perf_lazy_images' => 'boolean',
66 72 'perf_lcp_eager_count' => 'integer',
73 + 'perf_image_dimensions' => 'boolean',
74 + 'perf_responsive_images' => 'boolean',
75 + 'perf_preload_lcp' => 'boolean',
76 + 'perf_touch_targets' => 'boolean',
67 77 'perf_inline_css' => 'boolean',
78 + 'perf_async_css' => 'boolean',
79 + 'perf_critical_css' => 'boolean',
80 + 'perf_defer_js' => 'boolean',
68 81 'perf_delay_js' => 'boolean',
69 82 'perf_delay_js_timeout' => 'integer',
70 83 'perf_disable_emojis' => 'boolean',
71 84 'perf_disable_embeds' => 'boolean',
@@ -72,8 +85,47 @@
72 85 'perf_disable_dashicons' => 'boolean',
73 86 'perf_disable_jquery_migrate' => 'boolean',
74 87 'perf_control_heartbeat' => 'boolean',
75 88 'perf_heartbeat_frequency' => 'integer',
89 + // Editor paste
90 + 'paste_google_docs' => 'boolean',
91 + 'paste_convert_webp' => 'boolean',
92 + 'paste_webp_quality' => 'integer',
93 + // Responsive breakpoints
94 + 'breakpoint_tablet' => 'integer',
95 + 'breakpoint_mobile' => 'integer',
96 + 'breakpoint_mode' => 'string',
97 + 'breakpoint_custom' => 'json',
98 + // Performance Suite — full-page cache.
99 + 'perf_page_cache' => 'boolean',
100 + 'perf_page_cache_scope' => 'string',
101 + 'perf_page_cache_ttl' => 'integer',
102 + 'perf_page_cache_gzip' => 'boolean',
103 + 'perf_page_cache_prewarm' => 'boolean',
104 + 'perf_page_cache_mobile_variant' => 'boolean',
105 + 'perf_page_cache_crawler' => 'boolean',
106 + 'perf_page_cache_crawl_batch' => 'integer',
107 + 'perf_consolidate_css' => 'boolean',
108 + 'perf_consolidate_css_min' => 'integer',
109 + 'perf_fragment_cache' => 'boolean',
110 + 'perf_fragment_cache_ttl' => 'integer',
111 + 'perf_template_cache' => 'boolean',
112 + 'perf_template_cache_ttl' => 'integer',
113 + 'perf_image_optimize_on_upload' => 'boolean',
114 + 'perf_image_level' => 'string',
115 + 'perf_image_webp' => 'boolean',
116 + 'perf_image_quarantine_autodelete' => 'boolean',
117 + 'perf_image_quarantine_days' => 'integer',
118 + 'perf_image_require_filename' => 'boolean',
119 + 'perf_image_require_alt' => 'boolean',
120 + // Marketing — query param passthrough
121 + 'param_passthrough_enabled' => 'boolean',
122 + 'param_passthrough_keys' => 'string',
123 + 'param_passthrough_match' => 'string',
124 + 'param_passthrough_class' => 'string',
125 + 'param_passthrough_keyword' => 'string',
126 + 'param_passthrough_persist' => 'boolean',
127 + 'param_passthrough_cookie_days' => 'integer',
76 128 // global color & typography
77 129 'global_color' => 'json',
78 130 'global_typography' => 'json',
79 131 'global_font_family_fallback' => 'string',
@@ -99,9 +151,9 @@
99 151 )
100 152 ),
101 153 'fetch_posts' => array(
102 154 'callback' => array( $this, 'fetch_posts' ),
103 - 'capability' => 'manage_options',
155 + 'capability' => 'ablocks_access',
104 156 'fields' => array(
105 157 'postId' => 'integer',
106 158 'postType' => 'string',
107 159 'keyword' => 'string',
@@ -108,13 +160,13 @@
108 160 )
109 161 ),
110 162 'get_fronted_dashboard_pages' => array(
111 163 'callback' => array( $this, 'get_fronted_dashboard_pages' ),
112 - 'capability' => 'manage_options',
164 + 'capability' => 'ablocks_manage_settings',
113 165 ),
114 166 'create_fronted_dashboard_page' => array(
115 167 'callback' => array( $this, 'create_fronted_dashboard_page' ),
116 - 'capability' => 'manage_options',
168 + 'capability' => 'ablocks_manage_settings',
117 169 'fields' => [
118 170 'label' => 'string',
119 171 'slug' => 'string',
120 172 'icon' => 'string',
@@ -124,9 +176,9 @@
124 176 ]
125 177 ),
126 178 'create_fronted_dashboard_link' => array(
127 179 'callback' => array( $this, 'create_fronted_dashboard_link' ),
128 - 'capability' => 'manage_options',
180 + 'capability' => 'ablocks_manage_settings',
129 181 'fields' => [
130 182 'label' => 'string',
131 183 'link' => 'string',
132 184 'icon' => 'string',
@@ -136,9 +188,9 @@
136 188 ]
137 189 ),
138 190 'edit_fronted_dashboard_link' => array(
139 191 'callback' => array( $this, 'edit_fronted_dashboard_link' ),
140 - 'capability' => 'manage_options',
192 + 'capability' => 'ablocks_manage_settings',
141 193 'fields' => [
142 194 'label' => 'string',
143 195 'link' => 'string',
144 196 'icon' => 'string',
@@ -148,9 +200,9 @@
148 200 ]
149 201 ),
150 202 'delete_fronted_dashboard_link' => array(
151 203 'callback' => array( $this, 'delete_fronted_dashboard_link' ),
152 - 'capability' => 'manage_options',
204 + 'capability' => 'ablocks_manage_settings',
153 205 'fields' => array(
154 206 'page_id' => 'string',
155 207 )
156 208 ),
@@ -155,9 +207,9 @@
155 207 )
156 208 ),
157 209 'edit_fronted_dashboard_page' => array(
158 210 'callback' => array( $this, 'edit_fronted_dashboard_page' ),
159 - 'capability' => 'manage_options',
211 + 'capability' => 'ablocks_manage_settings',
160 212 'fields' => [
161 213 'label' => 'string',
162 214 'slug' => 'string',
163 215 'icon' => 'string',
@@ -168,9 +220,9 @@
168 220 ]
169 221 ),
170 222 'move_fronted_dashboard_page' => array(
171 223 'callback' => array( $this, 'move_fronted_dashboard_page' ),
172 - 'capability' => 'manage_options',
224 + 'capability' => 'ablocks_manage_settings',
173 225 'fields' => [
174 226 'reordered_items' => 'string',
175 227 ]
176 228 ),
@@ -175,9 +227,9 @@
175 227 ]
176 228 ),
177 229 'delete_fronted_dashboard_page' => array(
178 230 'callback' => array( $this, 'delete_fronted_dashboard_page' ),
179 - 'capability' => 'manage_options',
231 + 'capability' => 'ablocks_manage_settings',
180 232 'fields' => array(
181 233 'slug' => 'string',
182 234 'page_id' => 'integer',
183 235 )
@@ -239,12 +291,20 @@
239 291 wp_send_json_success( $settings );
240 292 }
241 293
242 294 public function save_settings( $payload ) {
295 + // The design system, the performance suite and site configuration are
296 + // three separate permissions but one endpoint. Keys this user may not
297 + // change are rewritten back to what is already saved, so the save
298 + // succeeds and simply leaves them alone.
299 + $payload = SettingsGuard::filter_payload( $payload );
300 +
243 301 // phpcs:ignore WordPress.Security.NonceVerification.Missing
244 302 do_action( 'ablocks/before_save_settings', $payload, 'base' );
245 303 $json_payload = Sanitizer::sanitize_payload([
246 304 'selected_fonts' => 'json',
305 + 'perf_page_cache_query_args' => 'json',
306 + 'perf_page_cache_exclusions' => 'json',
247 307 'global_color' => 'json',
248 308 'global_typography' => 'json',
249 309 'global_body_typography' => 'json',
250 310 'global_body_paragraph_space' => 'json',
@@ -255,20 +315,45 @@
255 315 'global_h3_typography' => 'json',
256 316 'global_h4_typography' => 'json',
257 317 'global_h5_typography' => 'json',
258 318 'global_h6_typography' => 'json',
319 + 'breakpoint_custom' => 'json',
259 320 ], $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
260 321
322 + // The JSON fields are read straight from $_POST rather than the sanitized
323 + // payload, so they need the same guard — the global colour and typography
324 + // presets live in here, and they are the design system.
325 + $json_payload = SettingsGuard::filter_payload( $json_payload );
326 +
327 + // Breakpoints are only written when the request carries them, so a save
328 + // that omits them keeps the stored list rather than resetting it.
329 + $breakpoints = [];
330 + foreach ( [ 'breakpoint_tablet', 'breakpoint_mobile' ] as $key ) {
331 + if ( isset( $payload[ $key ] ) && $payload[ $key ] > 0 ) {
332 + $breakpoints[ $key ] = $payload[ $key ];
333 + }
334 + }
335 + if ( isset( $payload['breakpoint_mode'] ) ) {
336 + $breakpoints['breakpoint_mode'] = 'strict' === $payload['breakpoint_mode'] ? 'strict' : 'cascade';
337 + }
338 + if ( isset( $json_payload['breakpoint_custom'] ) && is_array( $json_payload['breakpoint_custom'] ) ) {
339 + $breakpoints['breakpoint_custom'] = Breakpoints::sanitize( $json_payload['breakpoint_custom'] );
340 + }
341 +
261 342 $default = BaseSettings::get_default_data();
262 - $is_update = BaseSettings::save_settings( [
343 + $is_update = BaseSettings::save_settings( $breakpoints + [
263 344 'default_container_width' => $payload['default_container_width'] ?? $default['default_container_width'],
264 345 'container_padding' => $payload['container_padding'] ?? $default['container_padding'],
265 346 'container_element_gap' => $payload['container_element_gap'] ?? $default['container_element_gap'],
266 347 'enabled_assets_file_generation' => $payload['enabled_assets_file_generation'] ?? $default['enabled_assets_file_generation'],
267 348 'enabled_block_copy_paste_style' => $payload['enabled_block_copy_paste_style'] ?? $default['enabled_block_copy_paste_style'],
349 + 'lock_global_typography' => $payload['lock_global_typography'] ?? $default['lock_global_typography'],
350 + 'lock_global_typography_strict' => $payload['lock_global_typography_strict'] ?? $default['lock_global_typography_strict'],
351 + 'lock_global_colors' => $payload['lock_global_colors'] ?? $default['lock_global_colors'],
268 352 'enabled_load_google_font_locally' => $payload['enabled_load_google_font_locally'] ?? $default['enabled_load_google_font_locally'],
269 353 'enabled_only_selected_fonts' => $payload['enabled_only_selected_fonts'] ?? $default['enabled_only_selected_fonts'],
270 354 'selected_fonts' => $json_payload['selected_fonts'] ?? $default['selected_fonts'],
355 + 'font_metric_fallback' => $payload['font_metric_fallback'] ?? $default['font_metric_fallback'],
271 356 // Performance Suite — platform optimizations.
272 357 'perf_disable_emojis' => $payload['perf_disable_emojis'] ?? $default['perf_disable_emojis'],
273 358 'perf_disable_embeds' => $payload['perf_disable_embeds'] ?? $default['perf_disable_embeds'],
274 359 'perf_disable_dashicons' => $payload['perf_disable_dashicons'] ?? $default['perf_disable_dashicons'],
@@ -278,9 +363,52 @@
278 363 'perf_delay_js' => $payload['perf_delay_js'] ?? $default['perf_delay_js'],
279 364 'perf_delay_js_timeout' => $payload['perf_delay_js_timeout'] ?? $default['perf_delay_js_timeout'],
280 365 'perf_lazy_images' => $payload['perf_lazy_images'] ?? $default['perf_lazy_images'],
281 366 'perf_lcp_eager_count' => $payload['perf_lcp_eager_count'] ?? $default['perf_lcp_eager_count'],
367 + 'perf_image_dimensions' => $payload['perf_image_dimensions'] ?? $default['perf_image_dimensions'],
368 + 'perf_responsive_images' => $payload['perf_responsive_images'] ?? $default['perf_responsive_images'],
369 + 'perf_preload_lcp' => $payload['perf_preload_lcp'] ?? $default['perf_preload_lcp'],
370 + 'perf_touch_targets' => $payload['perf_touch_targets'] ?? $default['perf_touch_targets'],
282 371 'perf_inline_css' => $payload['perf_inline_css'] ?? $default['perf_inline_css'],
372 + 'perf_async_css' => $payload['perf_async_css'] ?? $default['perf_async_css'],
373 + 'perf_critical_css' => $payload['perf_critical_css'] ?? $default['perf_critical_css'],
374 + 'perf_defer_js' => $payload['perf_defer_js'] ?? $default['perf_defer_js'],
375 + // Editor paste.
376 + 'paste_google_docs' => $payload['paste_google_docs'] ?? $default['paste_google_docs'],
377 + 'paste_convert_webp' => $payload['paste_convert_webp'] ?? $default['paste_convert_webp'],
378 + 'paste_webp_quality' => $payload['paste_webp_quality'] ?? $default['paste_webp_quality'],
379 + // Performance Suite — full-page cache.
380 + 'perf_page_cache' => $payload['perf_page_cache'] ?? $default['perf_page_cache'],
381 + 'perf_page_cache_scope' => $payload['perf_page_cache_scope'] ?? $default['perf_page_cache_scope'],
382 + 'perf_page_cache_ttl' => $payload['perf_page_cache_ttl'] ?? $default['perf_page_cache_ttl'],
383 + 'perf_page_cache_gzip' => $payload['perf_page_cache_gzip'] ?? $default['perf_page_cache_gzip'],
384 + 'perf_page_cache_prewarm' => $payload['perf_page_cache_prewarm'] ?? $default['perf_page_cache_prewarm'],
385 + 'perf_page_cache_mobile_variant' => $payload['perf_page_cache_mobile_variant'] ?? $default['perf_page_cache_mobile_variant'],
386 + 'perf_page_cache_crawler' => $payload['perf_page_cache_crawler'] ?? $default['perf_page_cache_crawler'],
387 + 'perf_page_cache_crawl_batch' => $payload['perf_page_cache_crawl_batch'] ?? $default['perf_page_cache_crawl_batch'],
388 + 'perf_page_cache_query_args' => $json_payload['perf_page_cache_query_args'] ?? $default['perf_page_cache_query_args'],
389 + 'perf_page_cache_exclusions' => $json_payload['perf_page_cache_exclusions'] ?? $default['perf_page_cache_exclusions'],
390 + 'perf_consolidate_css' => $payload['perf_consolidate_css'] ?? $default['perf_consolidate_css'],
391 + 'perf_consolidate_css_min' => $payload['perf_consolidate_css_min'] ?? $default['perf_consolidate_css_min'],
392 + 'perf_fragment_cache' => $payload['perf_fragment_cache'] ?? $default['perf_fragment_cache'],
393 + 'perf_fragment_cache_ttl' => $payload['perf_fragment_cache_ttl'] ?? $default['perf_fragment_cache_ttl'],
394 + 'perf_template_cache' => $payload['perf_template_cache'] ?? $default['perf_template_cache'],
395 + 'perf_template_cache_ttl' => $payload['perf_template_cache_ttl'] ?? $default['perf_template_cache_ttl'],
396 + 'perf_image_optimize_on_upload' => $payload['perf_image_optimize_on_upload'] ?? $default['perf_image_optimize_on_upload'],
397 + 'perf_image_level' => $payload['perf_image_level'] ?? $default['perf_image_level'],
398 + 'perf_image_webp' => $payload['perf_image_webp'] ?? $default['perf_image_webp'],
399 + 'perf_image_quarantine_autodelete' => $payload['perf_image_quarantine_autodelete'] ?? $default['perf_image_quarantine_autodelete'],
400 + 'perf_image_quarantine_days' => $payload['perf_image_quarantine_days'] ?? $default['perf_image_quarantine_days'],
401 + 'perf_image_require_filename' => $payload['perf_image_require_filename'] ?? $default['perf_image_require_filename'],
402 + 'perf_image_require_alt' => $payload['perf_image_require_alt'] ?? $default['perf_image_require_alt'],
403 + // Marketing — query param passthrough
404 + 'param_passthrough_enabled' => $payload['param_passthrough_enabled'] ?? $default['param_passthrough_enabled'],
405 + 'param_passthrough_keys' => $payload['param_passthrough_keys'] ?? $default['param_passthrough_keys'],
406 + 'param_passthrough_match' => $payload['param_passthrough_match'] ?? $default['param_passthrough_match'],
407 + 'param_passthrough_class' => $payload['param_passthrough_class'] ?? $default['param_passthrough_class'],
408 + 'param_passthrough_keyword' => $payload['param_passthrough_keyword'] ?? $default['param_passthrough_keyword'],
409 + 'param_passthrough_persist' => $payload['param_passthrough_persist'] ?? $default['param_passthrough_persist'],
410 + 'param_passthrough_cookie_days' => $payload['param_passthrough_cookie_days'] ?? $default['param_passthrough_cookie_days'],
283 411 'enabled_coming_soon_page' => $payload['enabled_coming_soon_page'] ?? $default['enabled_coming_soon_page'],
284 412 'coming_soon_page' => $payload['coming_soon_page'] ?? $default['coming_soon_page'],
285 413 'enabled_maintenance_page' => $payload['enabled_maintenance_page'] ?? $default['enabled_maintenance_page'],
286 414 'maintenance_page' => $payload['maintenance_page'] ?? $default['maintenance_page'],
@@ -340,9 +468,10 @@
340 468 );
341 469 if ( ! empty( $keyword ) ) {
342 470 $args['s'] = $keyword;
343 471 }
344 - if ( ! current_user_can( 'manage_options' ) ) {
472 + // Anyone who cannot edit other people's posts only picks from their own.
473 + if ( ! current_user_can( 'edit_others_posts' ) ) {
345 474 $args['author'] = get_current_user_id();
346 475 }
347 476 }
348 477 $results = array();