PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.13.1
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.13.1
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 1.1.1 1.1.2 All 80 releases
ablocks / includes / ajax / settings.php

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

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