PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.13.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.13.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 1.1.1 1.1.2 All 80 releases
← All changes | includes/ajax/settings.php +823 -0 2.7.62.13.0 View file →
@@ -1,0 +1,823 @@
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 +}