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
ablocks / includes / ajax / settings.php

settings.php in aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder 2.15.0, at includes/ajax/settings.php

846 lines 33.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ABlocks\Ajax;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 use ABlocks\Classes\AbstractAjaxHandler;
10 use ABlocks\Classes\Sanitizer;
11 use ABlocks\Classes\Breakpoints;
12 use ABlocks\Helper;
13 use ABlocks\Admin\Settings\Base as BaseSettings;
14 use ABlocks\Permissions\SettingsGuard;
15
16 class Settings extends AbstractAjaxHandler {
17 public function __construct() {
18 $this->actions = array(
19 'get_blocks_visibility' => array(
20 'callback' => array( $this, 'get_blocks_visibility' ),
21 'capability' => 'ablocks_manage_settings'
22 ),
23 'save_block_visibility' => array(
24 'callback' => array( $this, 'save_block_visibility' ),
25 'capability' => 'ablocks_manage_settings',
26 'fields' => array(
27 'block_name' => 'string',
28 'status' => 'boolean',
29 )
30 ),
31 'save_bulk_block_visibility' => array(
32 'callback' => array( $this, 'save_bulk_block_visibility' ),
33 'capability' => 'ablocks_manage_settings',
34 'fields' => array(
35 'blocks' => 'json',
36 )
37 ),
38 'get_settings' => array(
39 'callback' => array( $this, 'get_settings' ),
40 'capability' => 'ablocks_access',
41 ),
42 'save_settings' => array(
43 'callback' => array( $this, 'save_settings' ),
44 'capability' => 'ablocks_save_settings',
45 'fields' => array(
46 'default_container_width' => 'integer',
47 'container_padding' => 'integer',
48 'container_element_gap' => 'integer',
49 'enabled_assets_file_generation' => 'boolean',
50 'enabled_block_copy_paste_style' => 'boolean',
51 'lock_global_typography' => 'boolean',
52 'lock_global_typography_strict' => 'boolean',
53 'lock_global_colors' => 'boolean',
54 'enabled_load_google_font_locally' => 'boolean',
55 'enabled_only_selected_fonts' => 'boolean',
56 'font_metric_fallback' => 'boolean',
57 'enabled_coming_soon_page' => 'boolean',
58 'coming_soon_page' => 'integer',
59 'enabled_maintenance_page' => 'boolean',
60 'maintenance_page' => 'integer',
61 'login_page' => 'integer',
62 'registration_page' => 'integer',
63 'forget_password_page' => 'integer',
64 'frontend_dashboard_page' => 'string',
65 'mailchimp_api_key' => 'string',
66 'drip_api_key' => 'string',
67 'getresponse_api_key' => 'string',
68 'convertkit_api_key' => 'string',
69 'mailerlite_api_key' => 'string',
70 // Performance Suite
71 'perf_lazy_images' => 'boolean',
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',
77 'perf_inline_css' => 'boolean',
78 'perf_async_css' => 'boolean',
79 'perf_critical_css' => 'boolean',
80 'perf_defer_js' => 'boolean',
81 'perf_delay_js' => 'boolean',
82 'perf_delay_js_timeout' => 'integer',
83 'perf_disable_emojis' => 'boolean',
84 'perf_disable_embeds' => 'boolean',
85 'perf_disable_dashicons' => 'boolean',
86 'perf_disable_jquery_migrate' => 'boolean',
87 'perf_control_heartbeat' => 'boolean',
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',
128 // global color & typography
129 'global_color' => 'json',
130 'global_typography' => 'json',
131 'global_font_family_fallback' => 'string',
132 'global_body_text_color' => 'string',
133 'global_body_typography' => 'json',
134 'global_body_paragraph_space' => 'json',
135 'global_link_color' => 'string',
136 'global_link_hover_color' => 'string',
137 'global_link_typography' => 'json',
138 'global_link_hover_typography' => 'json',
139 'global_h1_color' => 'string',
140 'global_h1_typography' => 'json',
141 'global_h2_color' => 'string',
142 'global_h2_typography' => 'json',
143 'global_h3_color' => 'string',
144 'global_h3_typography' => 'json',
145 'global_h4_color' => 'string',
146 'global_h4_typography' => 'json',
147 'global_h5_color' => 'string',
148 'global_h5_typography' => 'json',
149 'global_h6_color' => 'string',
150 'global_h6_typography' => 'json',
151 )
152 ),
153 'fetch_posts' => array(
154 'callback' => array( $this, 'fetch_posts' ),
155 'capability' => 'ablocks_access',
156 'fields' => array(
157 'postId' => 'integer',
158 'postType' => 'string',
159 'keyword' => 'string',
160 )
161 ),
162 'get_fronted_dashboard_pages' => array(
163 'callback' => array( $this, 'get_fronted_dashboard_pages' ),
164 'capability' => 'ablocks_manage_settings',
165 ),
166 'create_fronted_dashboard_page' => array(
167 'callback' => array( $this, 'create_fronted_dashboard_page' ),
168 'capability' => 'ablocks_manage_settings',
169 'fields' => [
170 'label' => 'string',
171 'slug' => 'string',
172 'icon' => 'string',
173 'class_name' => 'string',
174 'priority' => 'integer',
175 'parent_id' => 'integer',
176 ]
177 ),
178 'create_fronted_dashboard_link' => array(
179 'callback' => array( $this, 'create_fronted_dashboard_link' ),
180 'capability' => 'ablocks_manage_settings',
181 'fields' => [
182 'label' => 'string',
183 'link' => 'string',
184 'icon' => 'string',
185 'class_name' => 'string',
186 'priority' => 'integer',
187 'parent_id' => 'string',
188 ]
189 ),
190 'edit_fronted_dashboard_link' => array(
191 'callback' => array( $this, 'edit_fronted_dashboard_link' ),
192 'capability' => 'ablocks_manage_settings',
193 'fields' => [
194 'label' => 'string',
195 'link' => 'string',
196 'icon' => 'string',
197 'class_name' => 'string',
198 'priority' => 'integer',
199 'page_id' => 'string',
200 ]
201 ),
202 'delete_fronted_dashboard_link' => array(
203 'callback' => array( $this, 'delete_fronted_dashboard_link' ),
204 'capability' => 'ablocks_manage_settings',
205 'fields' => array(
206 'page_id' => 'string',
207 )
208 ),
209 'edit_fronted_dashboard_page' => array(
210 'callback' => array( $this, 'edit_fronted_dashboard_page' ),
211 'capability' => 'ablocks_manage_settings',
212 'fields' => [
213 'label' => 'string',
214 'slug' => 'string',
215 'icon' => 'string',
216 'class_name' => 'string',
217 'priority' => 'integer',
218 'parent_id' => 'integer',
219 'page_id' => 'integer',
220 ]
221 ),
222 'move_fronted_dashboard_page' => array(
223 'callback' => array( $this, 'move_fronted_dashboard_page' ),
224 'capability' => 'ablocks_manage_settings',
225 'fields' => [
226 'reordered_items' => 'string',
227 ]
228 ),
229 'delete_fronted_dashboard_page' => array(
230 'callback' => array( $this, 'delete_fronted_dashboard_page' ),
231 'capability' => 'ablocks_manage_settings',
232 'fields' => array(
233 'slug' => 'string',
234 'page_id' => 'integer',
235 )
236 ),
237 );
238 }
239
240 public function get_blocks_visibility() {
241 global $ablocks_blocks;
242 wp_send_json_success( $ablocks_blocks );
243 }
244
245 public function save_block_visibility( $payload ) {
246 $block_name = $payload['block_name'];
247 $status = $payload['status'];
248
249 $json_payload = Sanitizer::sanitize_payload([
250 'required_plugin' => 'json',
251 ], $payload);
252
253 $required_plugin = $json_payload['required_plugin'];
254
255 if ( empty( $block_name ) ) {
256 wp_send_json_error( __( 'Block Name missing', 'ablocks' ) );
257 }
258
259 if ( $status && $required_plugin ) {
260 if ( $required_plugin && is_array( $required_plugin ) ) {
261 foreach ( $required_plugin as $plugin ) {
262 if ( ! Helper::is_plugin_active( sanitize_text_field( $plugin['plugin_dir_path'] ) ) ) {
263 $error_message = sprintf( '%s Plugin is required to activate %s block.', $plugin['plugin_name'], $block_name );
264 wp_send_json_error( $error_message );
265 }
266 }
267 }
268 }
269
270 // Saved Data
271 $saved_blocks = (array) json_decode( get_option( ABLOCKS_BLOCKS_VISIBILITY_SETTINGS_NAME ), true );
272 $saved_blocks[ $block_name ] = $status;
273 update_option( ABLOCKS_BLOCKS_VISIBILITY_SETTINGS_NAME, wp_json_encode( $saved_blocks ) );
274 // Fire Addon Action
275 if ( $status ) {
276 do_action( "ablocks/block/activated_{$block_name}", $status );
277 } else {
278 do_action( "ablocks/block/deactivated_{$block_name}", $status );
279 }
280 wp_send_json_success( $saved_blocks );
281 }
282 public function save_bulk_block_visibility( $payload ) {
283 $blocks = wp_list_pluck( \json_decode( $payload['blocks'], true ), 'status', 'block_name' );
284 $saved_blocks = (array) json_decode( get_option( ABLOCKS_BLOCKS_VISIBILITY_SETTINGS_NAME ), true );
285 $updated_settings = wp_parse_args( $blocks, $saved_blocks );
286 update_option( ABLOCKS_BLOCKS_VISIBILITY_SETTINGS_NAME, wp_json_encode( $updated_settings ) );
287 wp_send_json_success( $updated_settings );
288 }
289 public function get_settings() {
290 $settings = BaseSettings::get_saved_data();
291 wp_send_json_success( $settings );
292 }
293
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
301 // phpcs:ignore WordPress.Security.NonceVerification.Missing
302 do_action( 'ablocks/before_save_settings', $payload, 'base' );
303 $json_payload = Sanitizer::sanitize_payload([
304 'selected_fonts' => 'json',
305 'perf_page_cache_query_args' => 'json',
306 'perf_page_cache_exclusions' => 'json',
307 'global_color' => 'json',
308 'global_typography' => 'json',
309 'global_body_typography' => 'json',
310 'global_body_paragraph_space' => 'json',
311 'global_link_typography' => 'json',
312 'global_link_hover_typography' => 'json',
313 'global_h1_typography' => 'json',
314 'global_h2_typography' => 'json',
315 'global_h3_typography' => 'json',
316 'global_h4_typography' => 'json',
317 'global_h5_typography' => 'json',
318 'global_h6_typography' => 'json',
319 'breakpoint_custom' => 'json',
320 ], $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
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
342 $default = BaseSettings::get_default_data();
343 $is_update = BaseSettings::save_settings( $breakpoints + [
344 'default_container_width' => $payload['default_container_width'] ?? $default['default_container_width'],
345 'container_padding' => $payload['container_padding'] ?? $default['container_padding'],
346 'container_element_gap' => $payload['container_element_gap'] ?? $default['container_element_gap'],
347 'enabled_assets_file_generation' => $payload['enabled_assets_file_generation'] ?? $default['enabled_assets_file_generation'],
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'],
352 'enabled_load_google_font_locally' => $payload['enabled_load_google_font_locally'] ?? $default['enabled_load_google_font_locally'],
353 'enabled_only_selected_fonts' => $payload['enabled_only_selected_fonts'] ?? $default['enabled_only_selected_fonts'],
354 'selected_fonts' => $json_payload['selected_fonts'] ?? $default['selected_fonts'],
355 'font_metric_fallback' => $payload['font_metric_fallback'] ?? $default['font_metric_fallback'],
356 // Performance Suite — platform optimizations.
357 'perf_disable_emojis' => $payload['perf_disable_emojis'] ?? $default['perf_disable_emojis'],
358 'perf_disable_embeds' => $payload['perf_disable_embeds'] ?? $default['perf_disable_embeds'],
359 'perf_disable_dashicons' => $payload['perf_disable_dashicons'] ?? $default['perf_disable_dashicons'],
360 'perf_disable_jquery_migrate' => $payload['perf_disable_jquery_migrate'] ?? $default['perf_disable_jquery_migrate'],
361 'perf_control_heartbeat' => $payload['perf_control_heartbeat'] ?? $default['perf_control_heartbeat'],
362 'perf_heartbeat_frequency' => $payload['perf_heartbeat_frequency'] ?? $default['perf_heartbeat_frequency'],
363 'perf_delay_js' => $payload['perf_delay_js'] ?? $default['perf_delay_js'],
364 'perf_delay_js_timeout' => $payload['perf_delay_js_timeout'] ?? $default['perf_delay_js_timeout'],
365 'perf_lazy_images' => $payload['perf_lazy_images'] ?? $default['perf_lazy_images'],
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'],
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'],
411 'enabled_coming_soon_page' => $payload['enabled_coming_soon_page'] ?? $default['enabled_coming_soon_page'],
412 'coming_soon_page' => $payload['coming_soon_page'] ?? $default['coming_soon_page'],
413 'enabled_maintenance_page' => $payload['enabled_maintenance_page'] ?? $default['enabled_maintenance_page'],
414 'maintenance_page' => $payload['maintenance_page'] ?? $default['maintenance_page'],
415 'frontend_dashboard_page' => $payload['frontend_dashboard_page'] ?? $default['frontend_dashboard_page'],
416 'login_page' => $payload['login_page'] ?? $default['login_page'],
417 'registration_page' => $payload['registration_page'] ?? $default['registration_page'],
418 'forget_password_page' => $payload['forget_password_page'] ?? $default['forget_password_page'],
419
420 'mailchimp_api_key' => $payload['mailchimp_api_key'] ?? '',
421 'drip_api_key' => $payload['drip_api_key'] ?? '',
422 'getresponse_api_key' => $payload['getresponse_api_key'] ?? '',
423 'convertkit_api_key' => $payload['convertkit_api_key'] ?? '',
424 'mailerlite_api_key' => $payload['mailerlite_api_key'] ?? '',
425 // Global Color & Typography
426 'global_color' => $json_payload['global_color'] ?? [],
427 'global_typography' => $json_payload['global_typography'] ?? [],
428 'global_font_family_fallback' => $payload['global_font_family_fallback'] ?? '',
429 'global_body_typography' => $json_payload['global_body_typography'] ?? [],
430 'global_body_paragraph_space' => $json_payload['global_body_paragraph_space'] ?? [],
431 'global_link_typography' => $json_payload['global_link_typography'] ?? [],
432 'global_link_hover_typography' => $json_payload['global_link_hover_typography'] ?? [],
433 'global_h1_typography' => $json_payload['global_h1_typography'] ?? [],
434 'global_h2_typography' => $json_payload['global_h2_typography'] ?? [],
435 'global_h3_typography' => $json_payload['global_h3_typography'] ?? [],
436 'global_h4_typography' => $json_payload['global_h4_typography'] ?? [],
437 'global_h5_typography' => $json_payload['global_h5_typography'] ?? [],
438 'global_h6_typography' => $json_payload['global_h6_typography'] ?? [],
439 'global_body_text_color' => $payload['global_body_text_color'] ?? '',
440 'global_link_color' => $payload['global_link_color'] ?? '',
441 'global_link_hover_color' => $payload['global_link_hover_color'] ?? '',
442 'global_h1_color' => $payload['global_h1_color'] ?? '',
443 'global_h2_color' => $payload['global_h2_color'] ?? '',
444 'global_h3_color' => $payload['global_h3_color'] ?? '',
445 'global_h4_color' => $payload['global_h4_color'] ?? '',
446 'global_h5_color' => $payload['global_h5_color'] ?? '',
447 'global_h6_color' => $payload['global_h6_color'] ?? '',
448 ]);
449 // phpcs:ignore WordPress.Security.NonceVerification.Missing
450 do_action( 'ablocks/after_save_settings', $is_update, 'base', $payload );
451 wp_send_json_success( $is_update );
452 }
453
454 public function fetch_posts( $payload ) {
455 $post_type = ( isset( $payload['postType'] ) ? $payload['postType'] : 'page' );
456 $postId = ( isset( $payload['postId'] ) ? $payload['postId'] : 0 );
457 $keyword = ( isset( $payload['keyword'] ) ? $payload['keyword'] : '' );
458
459 if ( $postId ) {
460 $args = array(
461 'post_type' => $post_type,
462 'p' => $postId,
463 );
464 } else {
465 $args = array(
466 'post_type' => $post_type,
467 'posts_per_page' => 10,
468 );
469 if ( ! empty( $keyword ) ) {
470 $args['s'] = $keyword;
471 }
472 // Anyone who cannot edit other people's posts only picks from their own.
473 if ( ! current_user_can( 'edit_others_posts' ) ) {
474 $args['author'] = get_current_user_id();
475 }
476 }
477 $results = array();
478 $posts = get_posts( $args );
479 if ( is_array( $posts ) ) {
480 foreach ( $posts as $post ) {
481 $results[] = array(
482 'label' => $post->post_title,
483 'value' => $post->ID,
484 );
485 }
486 }
487 wp_send_json_success( $results );
488 }
489
490 public function get_fronted_dashboard_pages() {
491 $settings = json_decode( get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ), true );
492 foreach ( $settings as &$item ) {
493 if ( isset( $item['parent_id'] ) ) {
494 $item['parent_id'] = 'null' === $item['parent_id'] ? null : $item['parent_id'];
495 }
496
497 $item['edit_link'] = (
498 'link' !== ( $item['type'] ?? '' ) &&
499 is_numeric( $item['page_id'] )
500 )
501 ? str_replace( '&amp;', '&', get_edit_post_link( $item['page_id'] ) )
502 : null;
503
504 if ( is_array( $item['children'] ?? null ) ) {
505 foreach ( $item['children'] as &$child_item ) {
506 if ( isset( $child_item['parent_id'] ) ) {
507 $child_item['parent_id'] = 'null' === $child_item['parent_id'] ? null : $child_item['parent_id'];
508
509 }
510
511 $child_item['edit_link'] = (
512 'link' !== ( $child_item['type'] ?? '' ) &&
513 is_numeric( $child_item['page_id'] )
514 )
515 ? str_replace( '&amp;', '&', get_edit_post_link( $child_item['page_id'] ) )
516 : null;
517 }
518 }
519 }//end foreach
520 wp_send_json_success( $settings );
521 }
522 public function create_fronted_dashboard_page( $payload ) {
523 global $wpdb;
524 // Step 1: Get Frontend Dashboard Page ID
525 $frontend_dashboard_id = (int) Helper::get_settings( 'frontend_dashboard_page' );
526 $settings = json_decode( get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ), true );
527 $root_page_id = 0;
528 // Step 2: Check if "root" page exists under frontend dashboard
529 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
530 $root_page = $wpdb->get_row( $wpdb->prepare(
531 "SELECT ID, post_parent FROM $wpdb->posts WHERE post_parent=%d AND post_name = %s AND post_type = 'page'",
532 $frontend_dashboard_id,
533 'root'
534 ) );
535
536 $post_parent = ! empty( $payload['parent_id'] ) ? $payload['parent_id'] : $frontend_dashboard_id;
537
538 if ( ! $root_page || (int) $root_page->post_parent !== $frontend_dashboard_id ) {
539 // Step 3: Create "root" page as child of frontend dashboard page
540 $root_page_id = wp_insert_post( [
541 'post_title' => 'Root',
542 'post_name' => 'root',
543 'post_status' => 'publish',
544 'post_type' => 'page',
545 'post_content' => '',
546 'post_parent' => $frontend_dashboard_id,
547 ] );
548
549 $settings[] = [
550 'page_id' => $root_page_id,
551 'label' => 'Root',
552 'slug' => 'root',
553 'icon' => '',
554 'class_name' => '',
555 'priority' => 0,
556 ];
557 }
558
559 $insert_page_id = wp_insert_post( [
560 'post_title' => $payload['label'],
561 'post_name' => $payload['slug'],
562 'post_content' => '',
563 'post_status' => 'publish',
564 'post_type' => 'page',
565 'post_parent' => $post_parent,
566 ] );
567
568 if ( $insert_page_id ) {
569 $payload['page_id'] = $insert_page_id;
570
571 if ( ! empty( $payload['parent_id'] ) ) {
572 foreach ( $settings as &$setting ) {
573 if ( $setting['page_id'] === $post_parent ) {
574 if ( ! isset( $setting['children'] ) ) {
575 $setting['children'] = [];
576 }
577 $setting['children'][] = $payload;
578 }
579 }
580 unset( $setting ); // important to break reference
581 } else {
582 $settings[] = $payload;
583 }
584
585 update_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, wp_json_encode( $settings ) );
586 flush_rewrite_rules();
587 }
588
589 wp_send_json_success( get_post( $insert_page_id ) );
590 }
591
592 public function create_fronted_dashboard_link( array $payload ) : void {
593 global $wpdb;
594
595 if ( empty( $payload['link'] ) || empty( $payload['label'] ) ) {
596 wp_send_json_error( __( 'Link/Label is required.', 'ablocks' ) );
597 }
598
599 $settings = json_decode(
600 get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ),
601 true
602 );
603
604 $payload['type'] = 'link';
605 $parent_id = $payload['parent_id'] = $payload['parent_id'] ?? 0;
606 $payload['page_id'] = 'link_' . time();
607 // print_r($payload);
608 // var_dump(( $parent_id ));
609 if ( empty( $parent_id ) || 'null' === $parent_id ) {
610 $settings[] = $payload;
611 } elseif ( ! is_null(
612 $index = array_search(
613 $parent_id,
614 array_column( $settings, 'page_id' )
615 )
616 )
617 ) {
618 $settings[ $index ]['children'][] = $payload;
619 } else {
620 wp_send_json_error( __( 'Invalid parent id.', 'ablocks' ) );
621 }
622
623 update_option(
624 ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME,
625 wp_json_encode( array_values( $settings ) )
626 );
627
628 wp_send_json_success( $payload );
629 }
630
631 public function edit_fronted_dashboard_link( array $payload ) : void {
632 global $wpdb;
633
634 if ( empty( $payload['page_id'] ) ||
635 empty( $payload['link'] ) ||
636 empty( $payload['label'] )
637 ) {
638 wp_send_json_error( __( 'Link/Label/ID is required.', 'ablocks' ) );
639 }
640
641 $settings = json_decode(
642 get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ),
643 true
644 );
645
646 $page_id = $payload['page_id'] = $payload['page_id'] ?? 0;
647
648 foreach ( $settings as &$items ) {
649 // echo $items['page_id'],"\n";
650 // var_dump($page_id , $items['page_id']);
651 if ( $page_id === $items['page_id'] ) {
652 $items['label'] = $payload['label'] ?: $items['label'];
653 $items['link'] = $payload['link'] ?: $items['link'];
654 $items['class_name'] = $payload['class_name'] ?: $items['class_name'];
655 $items['icon'] = $payload['icon'] ?: $items['icon'];
656 break;
657 } elseif ( ! empty( $items['children'] ) ) {
658 foreach ( $items['children'] as &$c_items ) {
659 if ( $page_id === $c_items['page_id'] ) {
660 $c_items['label'] = $payload['label'] ?: $c_items['label'];
661 $c_items['link'] = $payload['link'] ?: $c_items['link'];
662 $c_items['class_name'] = $payload['class_name'] ?: $c_items['class_name'];
663 $c_items['icon'] = $payload['icon'] ?: $c_items['icon'];
664 break 2;
665 }
666 }
667 }
668 }//end foreach
669
670 update_option(
671 ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME,
672 wp_json_encode( array_values( $settings ) )
673 );
674
675 wp_send_json_success( $payload );
676 }
677
678 public function delete_fronted_dashboard_link( array $payload ) : void {
679 global $wpdb;
680 // print_r($payload);
681 if ( empty( $payload['page_id'] )
682 ) {
683 wp_send_json_error( __( 'ID is required.', 'ablocks' ) );
684 }
685
686 $settings = json_decode(
687 get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ),
688 true
689 );
690
691 $page_id = $payload['page_id'] = $payload['page_id'] ?? 0;
692
693 foreach ( $settings as &$items ) {
694 // echo $items['page_id'],"\n";
695 // var_dump($page_id , $items['page_id']);
696 if ( $page_id === $items['page_id'] ) {
697 $items = null;
698 break;
699 } elseif ( ! empty( $items['children'] ) ) {
700 foreach ( $items['children'] as &$c_items ) {
701 if ( $page_id === $c_items['page_id'] ) {
702 $c_items = null;
703 $items['children'] = array_filter( $items['children'] );
704 break 2;
705 }
706 }
707 }
708 }
709
710 update_option(
711 ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME,
712 wp_json_encode( array_filter( $settings ) )
713 );
714
715 wp_send_json_success( $payload );
716 }
717
718 public function edit_fronted_dashboard_page( $payload ) {
719 if ( empty( $payload['page_id'] ) ) {
720 wp_send_json_error( 'Page ID is required for updating.' );
721 }
722
723 wp_update_post( [
724 'ID' => $payload['page_id'],
725 'post_title' => $payload['label'],
726 'post_slug' => $payload['slug'],
727 'priority' => $payload['priority'],
728 'post_parent' => ! empty( $payload['parent_id'] ) ? (int) $payload['parent_id'] : 0,
729 ], true );
730
731 $settings = json_decode( get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ), true );
732
733 $update_settings_recursive = null; // initialize first
734 $update_settings_recursive = function ( &$settings ) use ( &$update_settings_recursive, $payload ) {
735 foreach ( $settings as &$setting ) {
736 if ( $setting['page_id'] === $payload['page_id'] ) {
737 $setting['label'] = $payload['label'] ?? $setting['label'];
738 $setting['slug'] = $payload['slug'] ?? $setting['slug'];
739 $setting['icon'] = $payload['icon'] ?? $setting['icon'];
740 $setting['class_name'] = $payload['class_name'] ?? $setting['class_name'];
741 $setting['priority'] = $payload['priority'] ?? ( $setting['priority'] ?? 0 );
742 if ( isset( $payload['slug'] ) ||
743 isset( $payload['label'] )
744 ) {
745 wp_update_post( [
746 'ID' => $payload['page_id'],
747 'post_title' => $payload['label'] ?? $setting['label'],
748 'post_name' => $payload['slug'] ?? $setting['slug'],
749 ] );
750 }
751 if ( isset( $payload['children'] ) ) {
752 $setting['children'] = $payload['children'];
753 }
754 return true;
755 }//end if
756
757 if ( ! empty( $setting['children'] ) ) {
758 if ( $update_settings_recursive( $setting['children'] ) ) {
759 return true;
760 }
761 }
762 }//end foreach
763 return false;
764 };
765
766 $update_settings_recursive( $settings );
767 update_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, wp_json_encode( $settings ) );
768
769 flush_rewrite_rules();
770 // Step 4: Return updated page
771 wp_send_json_success( get_post( $payload['page_id'] ) );
772 }
773
774 public function delete_fronted_dashboard_page( $payload ) {
775 // Load existing frontend dashboard sub-pages settings
776 $settings = json_decode( get_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}' ), true );
777 if ( ! is_array( $settings ) ) {
778 $settings = [];
779 }
780
781 $remove_id = $payload['page_id'] ?? null;
782 $remove_slug = $payload['slug'] ?? null;
783
784 if ( ! $remove_id && ! $remove_slug ) {
785 wp_send_json_error( 'Page ID or slug is required to delete.' );
786 }
787
788 // Step 1: Delete the post if ID is provided
789 if ( $remove_id ) {
790 wp_delete_post( (int) $remove_id, true );
791 } elseif ( $remove_slug ) {
792 // If only slug is provided, try to find the page
793 $page = get_page_by_path( $remove_slug, OBJECT, 'page' );
794 if ( $page ) {
795 $remove_id = $page->ID;
796 wp_delete_post( $remove_id, true );
797 }
798 }
799
800 // Step 2: Recursively remove from settings
801 $remove_from_settings = function ( &$settings ) use ( &$remove_from_settings, $remove_id, $remove_slug ) {
802 $settings = array_values(array_filter($settings, function ( $item ) use ( $remove_id, $remove_slug ) {
803 $match_id = isset( $item['page_id'] ) && $remove_id && $item['page_id'] == $remove_id;
804 $match_slug = isset( $item['slug'] ) && $remove_slug && $item['slug'] == $remove_slug;
805 return ! $match_id && ! $match_slug;
806 }));
807
808 // Recurse into children
809 foreach ( $settings as &$item ) {
810 if ( ! empty( $item['children'] ) ) {
811 $remove_from_settings( $item['children'] );
812 }
813 }
814 unset( $item );
815 };
816
817 $remove_from_settings( $settings );
818
819 // Step 3: Save updated settings
820 update_option( ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, wp_json_encode( $settings ) );
821
822 wp_send_json_success( $remove_id ?? $remove_slug );
823 }
824
825 public function move_fronted_dashboard_page( array $payload ) : void {
826 $reordered_settings = json_decode( $payload['reordered_items'] ?? '{}', true );
827 $settings = json_decode(
828 get_option(
829 ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME, '{}'
830 ),
831 true
832 );
833
834 if ( is_array( $reordered_settings ) &&
835 count( $reordered_settings ) === count( $settings )
836 ) {
837 update_option(
838 ABLOCKS_FRONTEND_DASHBOARD_SUB_PAGES_SETTINGS_NAME,
839 $payload['reordered_items'] ?? '{}'
840 );
841 wp_send_json_success( __( 'Success!', 'ablocks' ) );
842 }
843 wp_send_json_error( __( 'Invalid data', 'ablocks' ), 400 );
844 }
845 }
846