PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 1.7.1
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v1.7.1
2.12.6 2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 0.0.2 0.0.3 All 96 releases
sureforms / inc / post-types.php

post-types.php in SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz 1.7.1, at inc/post-types.php

1,217 lines 37.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Post Types Class file.
4 *
5 * @package sureforms.
6 * @since 0.0.1
7 */
8
9 namespace SRFM\Inc;
10
11 use SRFM\Inc\Database\Tables\Entries;
12 use SRFM\Inc\Traits\Get_Instance;
13 use WP_Admin_Bar;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * Post Types Main Class.
21 *
22 * @since 0.0.1
23 */
24 class Post_Types {
25 use Get_Instance;
26
27 /**
28 * Constructor
29 *
30 * @since 0.0.1
31 */
32 public function __construct() {
33 $this->restrict_unwanted_insertions();
34 add_action( 'init', [ $this, 'register_post_types' ] );
35 add_action( 'init', [ $this, 'register_post_metas' ] );
36 add_filter( 'manage_sureforms_form_posts_columns', [ $this, 'custom_form_columns' ] );
37 add_action( 'manage_sureforms_form_posts_custom_column', [ $this, 'custom_form_column_data' ], 10, 2 );
38 add_shortcode( 'sureforms', [ $this, 'forms_shortcode' ] );
39 add_action( 'manage_posts_extra_tablenav', [ $this, 'maybe_render_blank_form_state' ] );
40 add_action( 'in_admin_header', [ $this, 'embed_page_header' ] );
41 add_filter( 'post_row_actions', [ $this, 'modify_entries_list_row_actions' ], 10, 2 );
42 add_filter( 'bulk_actions-edit-sureforms_form', [ $this, 'register_modify_bulk_actions' ], 99 );
43 add_action( 'admin_notices', [ $this, 'import_form_popup' ] );
44 add_action( 'admin_bar_menu', [ $this, 'remove_admin_bar_menu_item' ], 80, 1 );
45 add_action( 'template_redirect', [ $this, 'srfm_instant_form_redirect' ] );
46 add_action( 'template_redirect', [ $this, 'disable_sureforms_archive_page' ], 9 );
47 }
48
49 /**
50 * Add SureForms menu.
51 *
52 * @param string $title Parent slug.
53 * @param string $subtitle Parent slug.
54 * @param string $image Parent slug.
55 * @param string $button_text Parent slug.
56 * @param string $button_url Parent slug.
57 * @param string $after_button After button content.
58 * @return void
59 * @since 0.0.1
60 */
61 public function get_blank_page_markup( $title, $subtitle, $image, $button_text = '', $button_url = '', $after_button = '' ) {
62 echo '<div class="sureform-add-new-form">';
63
64 echo '<p class="sureform-blank-page-title">' . esc_html( $title ) . '</p>';
65
66 echo '<p class="sureform-blank-page-subtitle">' . esc_html( $subtitle ) . '</p>';
67
68 echo '<img src="' . esc_url( SRFM_URL . '/images/' . $image . '.svg' ) . '">';
69
70 if ( ! empty( $button_text ) && ! empty( $button_url ) ) {
71 echo '<div class="sureforms-add-new-form-container"><a class="sf-add-new-form-button" href="' . esc_url( $button_url ) . '"><div class="button-secondary">' . esc_html( $button_text ) . '</div></a>' . wp_kses_post( $after_button ) . '</div>';
72 }
73 echo '</div>';
74 }
75
76 /**
77 * Render blank state for add new form screen.
78 *
79 * @param string $post_type Post type.
80 * @return void
81 * @since 0.0.1
82 */
83 public function sureforms_render_blank_state( $post_type ) {
84
85 if ( SRFM_FORMS_POST_TYPE === $post_type ) {
86 $page_name = 'add-new-form';
87 $new_form_url = admin_url( 'admin.php?page=' . $page_name );
88 $import_button = '<button class="button button-secondary srfm-import-btn">' . __( 'Import Form', 'sureforms' ) . '</button>';
89
90 $this->get_blank_page_markup(
91 esc_html__( 'Let’s build your first form', 'sureforms' ),
92 esc_html__(
93 'Craft beautiful and functional forms in minutes',
94 'sureforms'
95 ),
96 'add-new-form',
97 esc_html__( 'Add New Form', 'sureforms' ),
98 $new_form_url,
99 $import_button
100 );
101 }
102
103 if ( SRFM_ENTRIES === $post_type ) {
104
105 $this->get_blank_page_markup(
106 esc_html__( 'No records found', 'sureforms' ),
107 esc_html__(
108 'This is where your form entries will appear',
109 'sureforms'
110 ),
111 'blank-entries'
112 );
113 }
114 }
115
116 /**
117 * Registers the forms and submissions post types.
118 *
119 * @return void
120 * @since 0.0.1
121 */
122 public function register_post_types() {
123 $form_labels = [
124 'name' => _x( 'Forms', 'post type general name', 'sureforms' ),
125 'singular_name' => _x( 'Form', 'post type singular name', 'sureforms' ),
126 'menu_name' => _x( 'Forms', 'admin menu', 'sureforms' ),
127 'add_new' => _x( 'Add New', 'form', 'sureforms' ),
128 'add_new_item' => __( 'Add New Form', 'sureforms' ),
129 'new_item' => __( 'New Form', 'sureforms' ),
130 'edit_item' => __( 'Edit Form', 'sureforms' ),
131 'view_item' => __( 'View Form', 'sureforms' ),
132 'view_items' => __( 'View Forms', 'sureforms' ),
133 'all_items' => __( 'Forms', 'sureforms' ),
134 'search_items' => __( 'Search Forms', 'sureforms' ),
135 'parent_item_colon' => __( 'Parent Forms:', 'sureforms' ),
136 'not_found' => __( 'No forms found.', 'sureforms' ),
137 'not_found_in_trash' => __( 'No forms found in Trash.', 'sureforms' ),
138 'item_published' => __( 'Form published.', 'sureforms' ),
139 'item_updated' => __( 'Form updated.', 'sureforms' ),
140 ];
141 register_post_type(
142 SRFM_FORMS_POST_TYPE,
143 [
144 'labels' => $form_labels,
145 'rewrite' => [ 'slug' => 'form' ],
146 'public' => true,
147 'show_in_rest' => true,
148 'has_archive' => true,
149 'show_ui' => true,
150 'supports' => [ 'title', 'author', 'editor', 'custom-fields' ],
151 'show_in_menu' => 'sureforms_menu',
152 'show_in_nav_menus' => true,
153 ]
154 );
155 // will be used later.
156 // register_post_status(
157 // 'unread',
158 // array(
159 // 'label' => _x( 'Unread', 'sureforms', 'sureforms' ),
160 // 'public' => true,
161 // 'exclude_from_search' => false,
162 // 'show_in_admin_all_list' => true,
163 // 'show_in_admin_status_list' => true,
164 // Translators: %s is the number of unread items.
165 // 'label_count' => _n_noop( 'Unread (%s)', 'Unread (%s)', 'sureforms' ),
166 // )
167 // );.
168 }
169
170 /**
171 * Redirects requests for SureForms archieve page to homeurl
172 *
173 * @since 1.4.0
174 * @return void
175 */
176 public function disable_sureforms_archive_page() {
177 if ( is_post_type_archive( SRFM_FORMS_POST_TYPE ) ) {
178 wp_safe_redirect( home_url(), 301 );
179 exit;
180 }
181 }
182
183 /**
184 * Remove add new form menu item.
185 *
186 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance.
187 *
188 * @return void
189 * @since 0.0.1
190 */
191 public function remove_admin_bar_menu_item( $wp_admin_bar ) {
192 $wp_admin_bar->remove_node( 'new-sureforms_form' );
193 }
194
195 /**
196 * Modify list row actions.
197 *
198 * @param array<mixed> $actions An array of row action links.
199 * @param \WP_Post $post The current WP_Post object.
200 *
201 * @return array<mixed> $actions Modified row action links.
202 * @since 0.0.1
203 */
204 public function modify_entries_list_row_actions( $actions, $post ) {
205 if ( 'sureforms_form' === $post->post_type ) {
206 $actions['export'] = '<a href="#" onclick="exportForm(' . $post->ID . ')">' . __( 'Export', 'sureforms' ) . '</a>';
207 }
208
209 return $actions;
210 }
211
212 /**
213 * Modify list bulk actions.
214 *
215 * @param array<mixed> $bulk_actions An array of bulk action links.
216 * @since 0.0.1
217 * @return array<mixed> $bulk_actions Modified action links.
218 */
219 public function register_modify_bulk_actions( $bulk_actions ) {
220
221 $white_listed_actions = [
222 'edit',
223 'trash',
224 'delete',
225 'untrash',
226 ];
227
228 // remove all actions except white listed actions.
229 $bulk_actions = array_intersect_key( $bulk_actions, array_flip( $white_listed_actions ) );
230
231 // Add export action only if edit and trash actions are present in bulk actions.
232 if ( isset( $bulk_actions['edit'] ) && isset( $bulk_actions['trash'] ) ) {
233 $bulk_actions['export'] = __( 'Export', 'sureforms' );
234 }
235
236 return $bulk_actions;
237 }
238
239 /**
240 * Show blank slate styles.
241 *
242 * @return void
243 * @since 0.0.1
244 */
245 public function get_blank_state_styles() {
246 echo '<style type="text/css">.sf-add-new-form-button:focus { box-shadow:none !important; outline:none !important; } #posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions, .wrap .subsubsub { display: none; } #posts-filter .tablenav.bottom { height: auto; } .sureform-add-new-form{ display: flex; flex-direction: column; gap: 8px; justify-content: center; align-items: center; padding: 24px 0 24px 0; } .sureform-blank-page-title { color: var(--dashboard-heading); font-family: Inter; font-size: 22px; font-style: normal; font-weight: 600; line-height: 28px; margin: 0; } .sureform-blank-page-subtitle { color: var(--dashboard-text); margin: 0; font-family: Inter; font-size: 14px; font-style: normal; font-weight: 400; line-height: 16px; }</style>';
247 }
248
249 /**
250 * Show blank slate.
251 *
252 * @param string $which String which tablenav is being shown.
253 * @return void
254 * @since 0.0.1
255 */
256 public function maybe_render_blank_form_state( $which ) {
257 $screen = get_current_screen();
258 $post_type = $screen ? $screen->post_type : '';
259
260 if ( SRFM_FORMS_POST_TYPE === $post_type && 'bottom' === $which ) {
261
262 $counts = (array) wp_count_posts( SRFM_FORMS_POST_TYPE );
263 unset( $counts['auto-draft'] );
264 $count = array_sum( $counts );
265
266 if ( 0 < $count ) {
267 return;
268 }
269
270 $this->sureforms_render_blank_state( $post_type );
271
272 $this->get_blank_state_styles();
273
274 }
275 }
276
277 /**
278 * Set up a div for the header to render into it.
279 *
280 * @return void
281 * @since 0.0.1
282 */
283 public static function embed_page_header() {
284 $screen = get_current_screen();
285 $screen_id = $screen ? $screen->id : '';
286
287 $is_screen_sureforms_entries = Helper::validate_request_context( SRFM_ENTRIES, 'page' );
288
289 if ( 'edit-' . SRFM_FORMS_POST_TYPE === $screen_id || $is_screen_sureforms_entries ) {
290 ?>
291 <style>
292 .srfm-page-header {
293 min-height: 56px;
294 @media screen and ( max-width: 600px ) {
295 padding-top: 46px;
296 }
297 }
298 </style>
299 <div id="srfm-page-header" class="srfm-page-header srfm-admin-wrapper">
300 <div class="srfm-page-pre-nav-content"></div>
301 </div>
302 <?php
303 }
304 }
305
306 /**
307 * Registers the sureforms metas.
308 *
309 * @return void
310 * @since 0.0.1
311 */
312 public function register_post_metas() {
313 $check_icon = 'data:image/svg+xml;base64,' . base64_encode( strval( file_get_contents( plugin_dir_path( SRFM_FILE ) . 'images/check-icon.svg' ) ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
314
315 $metas = apply_filters(
316 'srfm_register_post_meta',
317 [
318 // General tab metas.
319 '_srfm_use_label_as_placeholder' => 'boolean',
320 '_srfm_submit_button_text' => 'string',
321 '_srfm_is_inline_button' => 'boolean',
322 // Submit Button.
323 '_srfm_submit_width_backend' => 'string',
324 '_srfm_button_border_radius' => 'integer',
325 '_srfm_submit_alignment' => 'string',
326 '_srfm_submit_alignment_backend' => 'string',
327 '_srfm_submit_width' => 'string',
328 '_srfm_inherit_theme_button' => 'boolean',
329 // Additional Classes.
330 '_srfm_additional_classes' => 'string',
331
332 // Advanced tab metas.
333 // Success Message.
334 '_srfm_submit_type' => 'string',
335 // Security.
336 '_srfm_captcha_security_type' => 'string',
337 '_srfm_form_recaptcha' => 'string',
338 // post meta to store if the form is AI generated.
339 '_srfm_is_ai_generated' => 'boolean',
340 ]
341 );
342
343 // Form Custom CSS meta.
344 register_post_meta(
345 'sureforms_form',
346 '_srfm_form_custom_css',
347 [
348 'show_in_rest' => true,
349 'type' => 'string',
350 'single' => true,
351 'auth_callback' => static function() {
352 return current_user_can( 'edit_posts' );
353 },
354 'sanitize_callback' => static function( $meta_value ) {
355 return wp_kses_post( $meta_value );
356 },
357 ]
358 );
359
360 foreach ( $metas as $meta => $type ) {
361 register_meta(
362 'post',
363 $meta,
364 [
365 'object_subtype' => SRFM_FORMS_POST_TYPE,
366 'show_in_rest' => true,
367 'single' => true,
368 'type' => $type,
369 'sanitize_callback' => 'sanitize_text_field',
370 'auth_callback' => static function() {
371 return current_user_can( 'edit_posts' );
372 },
373 ]
374 );
375 }
376
377 // Registers meta to handle values associated with form styling.
378 register_post_meta(
379 SRFM_FORMS_POST_TYPE,
380 '_srfm_instant_form_settings',
381 [
382 'single' => true,
383 'type' => 'object',
384 'auth_callback' => '__return_true',
385 'show_in_rest' => [
386 'schema' => [
387 'type' => 'object',
388 'properties' => [
389 'site_logo' => [
390 'type' => 'string',
391 ],
392 'site_logo_id' => [
393 'type' => 'integer',
394 ],
395 // Form page banner settings.
396 'cover_type' => [
397 'type' => 'string',
398 ],
399 'cover_color' => [
400 'type' => 'string',
401 ],
402 'cover_image' => [
403 'type' => 'string',
404 ],
405 'cover_image_id' => [
406 'type' => 'integer',
407 ],
408 // Form page background settings.
409 'bg_type' => [
410 'type' => 'string',
411 ],
412 'bg_color' => [
413 'type' => 'string',
414 ],
415 'bg_image' => [
416 'type' => 'string',
417 ],
418 'bg_image_id' => [
419 'type' => 'integer',
420 ],
421 'enable_instant_form' => [
422 'type' => 'boolean',
423 ],
424 'form_container_width' => [
425 'type' => 'integer',
426 ],
427 'single_page_form_title' => [
428 'type' => 'boolean',
429 ],
430 'use_banner_as_page_background' => [
431 'type' => 'boolean',
432 ],
433 ],
434 ],
435 ],
436 'default' => [
437 'bg_type' => 'color',
438 'bg_color' => '#ffffff',
439 'bg_image' => '',
440 'site_logo' => '',
441 'cover_type' => 'color',
442 'cover_color' => '#111C44',
443 'cover_image' => '',
444 'enable_instant_form' => false,
445 'form_container_width' => 620,
446 'single_page_form_title' => true,
447 'use_banner_as_page_background' => false,
448 ],
449 ]
450 );
451
452 register_post_meta(
453 SRFM_FORMS_POST_TYPE,
454 '_srfm_forms_styling',
455 [
456 'single' => true,
457 'type' => 'object',
458 'auth_callback' => '__return_true',
459 'show_in_rest' => [
460 'schema' => [
461 'type' => 'object',
462 'properties' => [
463 'primary_color' => [
464 'type' => 'string',
465 ],
466 'text_color' => [
467 'type' => 'string',
468 ],
469 'text_color_on_primary' => [
470 'type' => 'string',
471 ],
472 'field_spacing' => [
473 'type' => 'string',
474 ],
475 'submit_button_alignment' => [
476 'type' => 'string',
477 ],
478 'bg_type' => [
479 'type' => 'string',
480 ],
481 'bg_color' => [
482 'type' => 'string',
483 ],
484 'bg_image' => [
485 'type' => 'string',
486 ],
487 'bg_image_id' => [
488 'type' => 'integer',
489 ],
490 // Image Properties.
491 'bg_image_position' => [
492 'type' => 'object',
493 'properties' => [
494 'x' => [
495 'type' => 'number',
496 'format' => 'float',
497 ],
498 'y' => [
499 'type' => 'number',
500 'format' => 'float',
501 ],
502 ],
503 ],
504 'bg_image_attachment' => [
505 'type' => 'string',
506 ],
507 'bg_image_repeat' => [
508 'type' => 'string',
509 ],
510 'bg_image_size' => [
511 'type' => 'string',
512 ],
513 'bg_image_size_custom' => [
514 'type' => 'integer',
515 ],
516 'bg_image_size_custom_unit' => [
517 'type' => 'string',
518 ],
519 // Gradient Properties.
520 'bg_gradient' => [
521 'type' => 'string',
522 ],
523 'gradient_type' => [
524 'type' => 'string',
525 ],
526 'bg_gradient_type' => [
527 'type' => 'string',
528 ],
529 'bg_gradient_color_1' => [
530 'type' => 'string',
531 ],
532 'bg_gradient_color_2' => [
533 'type' => 'string',
534 ],
535 'bg_gradient_angle' => [
536 'type' => 'integer',
537 ],
538 'bg_gradient_location_1' => [
539 'type' => 'integer',
540 ],
541 'bg_gradient_location_2' => [
542 'type' => 'integer',
543 ],
544 // Overlay Properties.
545 'bg_overlay_size' => [
546 'type' => 'string',
547 ],
548 'bg_gradient_overlay_type' => [
549 'type' => 'string',
550 ],
551 'bg_overlay_opacity' => [
552 'type' => 'number',
553 ],
554 'bg_overlay_image' => [
555 'type' => 'string',
556 ],
557 'bg_overlay_image_id' => [
558 'type' => 'integer',
559 ],
560 'bg_image_overlay_color' => [
561 'type' => 'string',
562 ],
563 'bg_overlay_custom_size_unit' => [
564 'type' => 'string',
565 ],
566 'bg_overlay_custom_size' => [
567 'type' => 'integer',
568 ],
569 'bg_overlay_blend_mode' => [
570 'type' => 'string',
571 ],
572 'bg_overlay_position' => [
573 'type' => 'object',
574 'properties' => [
575 'x' => [
576 'type' => 'number',
577 'format' => 'float',
578 ],
579 'y' => [
580 'type' => 'number',
581 'format' => 'float',
582 ],
583 ],
584 ],
585 'bg_overlay_attachment' => [
586 'type' => 'string',
587 ],
588 'bg_overlay_repeat' => [
589 'type' => 'string',
590 ],
591 // Gradient Overlay Properties.
592 'bg_overlay_gradient' => [
593 'type' => 'string',
594 ],
595 'overlay_gradient_type' => [
596 'type' => 'string',
597 ],
598 'bg_overlay_gradient_type' => [
599 'type' => 'string',
600 ],
601 'bg_overlay_gradient_color_1' => [
602 'type' => 'string',
603 ],
604 'bg_overlay_gradient_color_2' => [
605 'type' => 'string',
606 ],
607 'bg_overlay_gradient_angle' => [
608 'type' => 'integer',
609 ],
610 'bg_overlay_gradient_location_1' => [
611 'type' => 'integer',
612 ],
613 'bg_overlay_gradient_location_2' => [
614 'type' => 'integer',
615 ],
616 // Form Padding.
617 'form_padding_top' => [
618 'type' => 'number',
619 ],
620 'form_padding_right' => [
621 'type' => 'number',
622 ],
623 'form_padding_bottom' => [
624 'type' => 'number',
625 ],
626 'form_padding_left' => [
627 'type' => 'number',
628 ],
629 'form_padding_unit' => [
630 'type' => 'string',
631 ],
632 'form_padding_link' => [
633 'type' => 'boolean',
634 ],
635 // Border Radius.
636 'form_border_radius_top' => [
637 'type' => 'number',
638 ],
639 'form_border_radius_right' => [
640 'type' => 'number',
641 ],
642 'form_border_radius_bottom' => [
643 'type' => 'number',
644 ],
645 'form_border_radius_left' => [
646 'type' => 'number',
647 ],
648 'form_border_radius_unit' => [
649 'type' => 'string',
650 ],
651 'form_border_radius_link' => [
652 'type' => 'boolean',
653 ],
654 // Form Padding and Border Radius.
655 // Form Padding.
656 'instant_form_padding_top' => [
657 'type' => 'number',
658 ],
659 'instant_form_padding_right' => [
660 'type' => 'number',
661 ],
662 'instant_form_padding_bottom' => [
663 'type' => 'number',
664 ],
665 'instant_form_padding_left' => [
666 'type' => 'number',
667 ],
668 'instant_form_padding_unit' => [
669 'type' => 'string',
670 ],
671 'instant_form_padding_link' => [
672 'type' => 'boolean',
673 ],
674 // Border Radius.
675 'instant_form_border_radius_top' => [
676 'type' => 'number',
677 ],
678 'instant_form_border_radius_right' => [
679 'type' => 'number',
680 ],
681 'instant_form_border_radius_bottom' => [
682 'type' => 'number',
683 ],
684 'instant_form_border_radius_left' => [
685 'type' => 'number',
686 ],
687 'instant_form_border_radius_unit' => [
688 'type' => 'string',
689 ],
690 'instant_form_border_radius_link' => [
691 'type' => 'boolean',
692 ],
693 ],
694 ],
695 ],
696 'default' => [
697 'primary_color' => '#111C44',
698 'text_color' => '#1E1E1E',
699 'text_color_on_primary' => '#FFFFFF',
700 'field_spacing' => 'medium',
701 'submit_button_alignment' => 'left',
702 'bg_type' => 'color',
703 'bg_color' => '#ffffff',
704 'bg_image' => '',
705 'bg_image_position' => [
706 'x' => 0.5,
707 'y' => 0.5,
708 ],
709 'bg_image_attachment' => 'scroll',
710 'bg_image_repeat' => 'no-repeat',
711 'bg_image_size' => 'cover',
712 'bg_image_size_custom' => 100, // Image width when set to custom.
713 'bg_image_size_custom_unit' => '%',
714 'gradient_type' => 'basic',
715 'bg_gradient_type' => 'linear',
716 'bg_gradient_color_1' => '#FFC9B2',
717 'bg_gradient_color_2' => '#C7CBFF',
718 'bg_gradient_angle' => 90,
719 'bg_gradient_location_1' => 0,
720 'bg_gradient_location_2' => 100,
721 'bg_overlay_size' => 'cover',
722 'bg_gradient_overlay_type' => '',
723 'bg_overlay_opacity' => 1,
724 'bg_overlay_image' => '',
725 'bg_image_overlay_color' => '#FFFFFF75',
726 'bg_overlay_custom_size_unit' => '%',
727 'bg_overlay_custom_size' => 100,
728 'bg_overlay_position' => [
729 'x' => 0.5,
730 'y' => 0.5,
731 ],
732 'bg_overlay_attachment' => 'scroll',
733 'bg_overlay_repeat' => 'no-repeat',
734 'bg_overlay_blend_mode' => 'normal',
735 // Gradient Overlay Properties.
736 'overlay_gradient_type' => 'basic',
737 'bg_overlay_gradient_type' => 'linear',
738 'bg_overlay_gradient_color_1' => '#FFC9B2',
739 'bg_overlay_gradient_color_2' => '#C7CBFF',
740 'bg_overlay_gradient_angle' => 90,
741 'bg_overlay_gradient_location_1' => 0,
742 'bg_overlay_gradient_location_2' => 100,
743 // Form Properties.
744 // Padding.
745 'form_padding_top' => 0,
746 'form_padding_right' => 0,
747 'form_padding_bottom' => 0,
748 'form_padding_left' => 0,
749 'form_padding_unit' => 'px',
750 'form_padding_link' => true,
751 // Border Radius.
752 'form_border_radius_top' => 0,
753 'form_border_radius_right' => 0,
754 'form_border_radius_bottom' => 0,
755 'form_border_radius_left' => 0,
756 'form_border_radius_unit' => 'px',
757 'form_border_radius_link' => true,
758 // Form Properties.
759 // Padding.
760 'instant_form_padding_top' => 32,
761 'instant_form_padding_right' => 32,
762 'instant_form_padding_bottom' => 32,
763 'instant_form_padding_left' => 32,
764 'instant_form_padding_unit' => 'px',
765 'instant_form_padding_link' => true,
766 // Border Radius.
767 'instant_form_border_radius_top' => 12,
768 'instant_form_border_radius_right' => 12,
769 'instant_form_border_radius_bottom' => 12,
770 'instant_form_border_radius_left' => 12,
771 'instant_form_border_radius_unit' => 'px',
772 'instant_form_border_radius_link' => true,
773 ],
774 ]
775 );
776
777 // Email notification Metas.
778 register_post_meta(
779 'sureforms_form',
780 '_srfm_email_notification',
781 [
782 'single' => true,
783 'type' => 'array',
784 'auth_callback' => '__return_true',
785 'show_in_rest' => [
786 'schema' => [
787 'type' => 'array',
788 'items' => [
789 'type' => 'object',
790 'properties' => [
791 'id' => [
792 'type' => 'integer',
793 ],
794 'status' => [
795 'type' => 'boolean',
796 ],
797 'is_raw_format' => [
798 'type' => 'boolean',
799 ],
800 'name' => [
801 'type' => 'string',
802 ],
803 'email_to' => [
804 'type' => 'string',
805 ],
806 'email_reply_to' => [
807 'type' => 'string',
808 ],
809 'from_name' => [
810 'type' => 'string',
811 ],
812 'from_email' => [
813 'type' => 'string',
814 ],
815 'email_cc' => [
816 'type' => 'string',
817 ],
818 'email_bcc' => [
819 'type' => 'string',
820 ],
821 'subject' => [
822 'type' => 'string',
823 ],
824 'email_body' => [
825 'type' => 'string',
826 ],
827 ],
828 ],
829 ],
830 ],
831 'default' => [
832 [
833 'id' => 1,
834 'status' => true,
835 'is_raw_format' => false,
836 'name' => __( 'Admin Notification Email', 'sureforms' ),
837 'email_to' => '{admin_email}',
838 'email_reply_to' => '{admin_email}',
839 'from_name' => '{site_title}',
840 'from_email' => '{admin_email}',
841 'email_cc' => '{admin_email}',
842 'email_bcc' => '{admin_email}',
843 'subject' => sprintf( /* translators: %s: Form title smart tag */ __( 'New Form Submission - %s', 'sureforms' ), '{form_title}' ),
844 'email_body' => '{all_data}',
845 ],
846 ],
847 ]
848 );
849
850 // Compliance Settings metas.
851 register_post_meta(
852 'sureforms_form',
853 '_srfm_compliance',
854 [
855 'single' => true,
856 'type' => 'array',
857 'auth_callback' => '__return_true',
858 'show_in_rest' => [
859 'schema' => [
860 'type' => 'array',
861 'items' => [
862 'type' => 'object',
863 'properties' => [
864 'id' => [
865 'type' => 'string',
866 ],
867 'gdpr' => [
868 'type' => 'boolean',
869 ],
870 'do_not_store_entries' => [
871 'type' => 'boolean',
872 ],
873 'auto_delete_entries' => [
874 'type' => 'boolean',
875 ],
876 'auto_delete_days' => [
877 'type' => 'string',
878 ],
879 ],
880 ],
881 ],
882 ],
883 'default' => [
884 [
885 'id' => 'gdpr',
886 'gdpr' => false,
887 'do_not_store_entries' => false,
888 'auto_delete_entries' => false,
889 'auto_delete_days' => '',
890 ],
891 ],
892 ]
893 );
894
895 // form confirmation.
896 register_post_meta(
897 'sureforms_form',
898 '_srfm_form_confirmation',
899 [
900 'single' => true,
901 'type' => 'array',
902 'auth_callback' => static function() {
903 return current_user_can( 'manage_options' );
904 },
905 'sanitize_callback' => static function( $meta_value ) {
906 if ( ! is_array( $meta_value ) ) {
907 return [];
908 }
909 $sanitized = [];
910 foreach ( $meta_value as $item ) {
911 if ( ! is_array( $item ) ) {
912 continue;
913 }
914 $sanitized[] = [
915 'id' => isset( $item['id'] ) ? intval( $item['id'] ) : 0,
916 'confirmation_type' => isset( $item['confirmation_type'] ) ? sanitize_text_field( $item['confirmation_type'] ) : '',
917 'page_url' => isset( $item['page_url'] ) ? esc_url_raw( $item['page_url'] ) : '',
918 'custom_url' => isset( $item['custom_url'] ) ? esc_url_raw( $item['custom_url'] ) : '',
919 'message' => isset( $item['message'] ) ? Helper::strip_js_attributes( $item['message'] ) : '',
920 'submission_action' => isset( $item['submission_action'] ) ? sanitize_text_field( $item['submission_action'] ) : '',
921 'enable_query_params' => isset( $item['enable_query_params'] ) ? filter_var( $item['enable_query_params'], FILTER_VALIDATE_BOOLEAN ) : false,
922 'query_params' => isset( $item['query_params'] ) ? array_map( 'sanitize_text_field', (array) $item['query_params'] ) : [],
923 ];
924 }
925 return $sanitized;
926 },
927 'show_in_rest' => [
928 'schema' => [
929 'type' => 'array',
930 'items' => [
931 'type' => 'object',
932 'properties' => [
933 'id' => [
934 'type' => 'integer',
935 ],
936 'confirmation_type' => [
937 'type' => 'string',
938 ],
939 'page_url' => [
940 'type' => 'string',
941 ],
942 'custom_url' => [
943 'type' => 'string',
944 ],
945 'message' => [
946 'type' => 'string',
947 ],
948 'submission_action' => [
949 'type' => 'string',
950 ],
951 'enable_query_params' => [
952 'type' => 'boolean',
953 ],
954 'query_params' => [
955 'type' => 'array',
956 ],
957 ],
958 ],
959 ],
960 ],
961 'default' => [
962 [
963 'id' => 1,
964 'confirmation_type' => 'same page',
965 'page_url' => '',
966 'custom_url' => '',
967 'message' => '<p style="text-align: center;"><img src="' . esc_attr( $check_icon ) . '" alt="" aria-hidden="true"></img></p><h2 style="text-align: center;">' . esc_html__( 'Thank you', 'sureforms' ) . '</h2>',
968 'submission_action' => 'hide form',
969 ],
970 ],
971 ]
972 );
973
974 // conditional logic.
975 do_action( 'srfm_register_conditional_logic_post_meta' );
976 /**
977 * Hook for registering additional Post Meta
978 */
979 do_action( 'srfm_register_additional_post_meta' );
980 }
981
982 /**
983 * Custom Shortcode.
984 *
985 * @param array<mixed> $atts Attributes.
986 * @return string|false. $content Post Content.
987 * @since 0.0.1
988 */
989 public function forms_shortcode( array $atts ) {
990 $atts = shortcode_atts(
991 [
992 'id' => '',
993 'show_title' => true,
994 ],
995 $atts
996 );
997
998 $id = intval( $atts['id'] );
999 $post = get_post( $id );
1000
1001 if ( ! empty( $id ) && $post ) {
1002 return Generate_Form_Markup::get_form_markup( $id, ! filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN ), '', 'post', true );
1003 }
1004
1005 return '';
1006 }
1007
1008 /**
1009 * Add custom column header.
1010 *
1011 * @param array<mixed> $columns Attributes.
1012 * @return array<mixed> $columns Post Content.
1013 * @since 0.0.1
1014 */
1015 public function custom_form_columns( $columns ) {
1016 return [
1017 'cb' => $columns['cb'],
1018 'title' => $columns['title'],
1019 'sureforms' => __( 'Shortcode', 'sureforms' ),
1020 'entries' => __( 'Entries', 'sureforms' ),
1021 'author' => $columns['author'],
1022 'date' => $columns['date'],
1023 ];
1024 }
1025
1026 /**
1027 * Populate custom column with data.
1028 *
1029 * @param string $column Attributes.
1030 * @param int $post_id Attributes.
1031 * @return void
1032 * @since 0.0.1
1033 */
1034 public function custom_form_column_data( $column, $post_id ) {
1035 if ( 'sureforms' === $column ) {
1036 ob_start();
1037 ?>
1038 <div class="srfm-shortcode-container">
1039 <input id="srfm-shortcode-input-<?php echo esc_attr( Helper::get_string_value( $post_id ) ); ?>" class="srfm-shortcode-input" type="text" readonly value="[sureforms id='<?php echo esc_attr( Helper::get_string_value( $post_id ) ); ?>']" />
1040 <button type="button" class="components-button components-clipboard-button has-icon srfm-shortcode" onclick="handleFormShortcode(this)">
1041 <span id="srfm-copy-icon" class="dashicon dashicons dashicons-admin-page"></span>
1042 </button>
1043 </div>
1044 <?php
1045 ob_end_flush();
1046 }
1047 if ( 'entries' === $column ) {
1048 // Entries URL to redirect user based on the form ID.
1049 $entries_url = wp_nonce_url(
1050 add_query_arg(
1051 [
1052 'form_filter' => $post_id,
1053 ],
1054 admin_url( 'admin.php?page=sureforms_entries' )
1055 ),
1056 'srfm_entries_action'
1057 );
1058
1059 // Get the entry count for the form.
1060 $entries_count = Entries::get_total_entries_by_status( 'all', $post_id );
1061
1062 ob_start();
1063 ?>
1064 <p class="srfm-entries-number"><a href="<?php echo esc_url( $entries_url ); ?>"><?php echo esc_html( Helper::get_string_value( $entries_count ) ); ?></a></p>
1065 <?php
1066 ob_end_flush();
1067 }
1068 }
1069
1070 /**
1071 * Show the import form popup
1072 *
1073 * @since 0.0.1
1074 * @return void
1075 */
1076 public function import_form_popup() {
1077 $screen = get_current_screen();
1078 $id = $screen ? $screen->id : '';
1079 if ( 'edit-sureforms_form' === $id ) {
1080 ?>
1081 <div class="srfm-import-plugin-wrap">
1082 <div class="srfm-import-wrap">
1083 <p class="srfm-import-help"><?php echo esc_html__( 'Please choose the SureForms export file (.json) that you wish to import.', 'sureforms' ); ?></p>
1084 <form method="post" enctype="multipart/form-data" class="srfm-import-form">
1085 <input type="file" id="srfm-import-file" onchange="handleFileChange(event)" name="import form" accept=".json">
1086 <input type="submit" name="import-form-submit" id="import-form-submit" class="srfm-import-button" value="<?php esc_attr_e( 'Import Now', 'sureforms' ); ?>" disabled>
1087 </form>
1088 <p id="srfm-import-error"><?php echo esc_html__( 'There is some error in json file, please export the SureForms Forms again.', 'sureforms' ); ?></p>
1089 </div>
1090 </div>
1091 <?php
1092 }
1093 }
1094
1095 /**
1096 * Redirect to home page if instant form is not enabled.
1097 *
1098 * @since 0.0.1
1099 * @return void
1100 */
1101 public function srfm_instant_form_redirect() {
1102
1103 $form_id = Helper::get_integer_value( get_the_ID() );
1104
1105 $instant_form_settings = Helper::get_array_value( Helper::get_post_meta( $form_id, '_srfm_instant_form_settings' ) );
1106 $enable_instant_form = ! empty( $instant_form_settings['enable_instant_form'] ) ? boolval( $instant_form_settings['enable_instant_form'] ) : false;
1107
1108 if ( $enable_instant_form ) {
1109 return;
1110 }
1111
1112 $form_preview = '';
1113
1114 $form_preview_attr = isset( $_GET['preview'] ) ? sanitize_text_field( wp_unslash( $_GET['preview'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not needed here.
1115
1116 if ( $form_preview_attr ) {
1117 $form_preview = filter_var( $form_preview_attr, FILTER_VALIDATE_BOOLEAN );
1118 }
1119
1120 if ( is_singular( 'sureforms_form' ) && ! $form_preview && ! current_user_can( 'manage_options' ) ) {
1121 wp_safe_redirect( home_url() );
1122 return;
1123 }
1124 }
1125
1126 /**
1127 * Restrict RankMath meta boxes in edit page.
1128 *
1129 * @since 0.0.5
1130 * @return void
1131 */
1132 public function restrict_data() {
1133 add_filter( 'rank_math/excluded_post_types', [ $this, 'unset_sureforms_post_type' ] );
1134 }
1135
1136 /**
1137 * Remove SureForms post type from RankMath and Yoast.
1138 *
1139 * @param array<mixed> $post_types Post types.
1140 * @since 0.0.5
1141 * @return array<mixed> $post_types Modified post types.
1142 */
1143 public function unset_sureforms_post_type( $post_types ) {
1144 return array_filter(
1145 $post_types,
1146 static function( $post_type ) {
1147 if ( is_array( $post_type ) && isset( $post_type['name'] ) ) {
1148 return SRFM_FORMS_POST_TYPE !== $post_type['name'];
1149 }
1150 return SRFM_FORMS_POST_TYPE !== $post_type;
1151 }
1152 );
1153 }
1154
1155 /**
1156 * Restrict unwanted insertions from the AIOSEO plugin.
1157 *
1158 * This method ensures that the SureForms post type is excluded from AIOSEO's
1159 * public post types unless the current page is related to AIOSEO settings.
1160 *
1161 * @return void
1162 * @since 1.6.0
1163 */
1164 public function restrict_in_aioseo_plugin() {
1165 /**
1166 * Checks if the AIOSEO plugin is installed and excludes the SureForms post type from AIOSEO's public post types.
1167 *
1168 * - Verifies the presence of the AIOSEO_DIR constant to ensure AIOSEO is installed.
1169 * - Allows AIOSEO functionality on its own settings pages by checking the `REQUEST_URI` and `page` query parameter.
1170 * - Excludes the SureForms post type from AIOSEO's public post types using the `aioseo_public_post_types` filter.
1171 *
1172 * Security Note:
1173 * - Nonce verification is intentionally skipped (`phpcs:ignore WordPress.Security.NonceVerification.Recommended`)
1174 * because this code is only performing a read operation to check the current request URI and query parameters.
1175 * It does not modify or process sensitive data, making nonce verification unnecessary in this context.
1176 */
1177 // Check if AIOSEO is installed by verifying the AIOSEO_DIR constant.
1178 if ( ! defined( 'AIOSEO_DIR' ) ) {
1179 return;
1180 }
1181
1182 // Allow AIOSEO functionality on its own settings pages.
1183 if ( isset( $_SERVER['REQUEST_URI'] ) ) {
1184 $request_uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
1185 if ( strpos( $request_uri, 'admin.php' ) !== false ) {
1186 if ( isset( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here because Safe here as we're only reading the `page` parameter.
1187 $page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here because only we are reading the `page` parameter.
1188 if ( strpos( $page, 'aioseo' ) !== false ) {
1189 return;
1190 }
1191 }
1192 }
1193 }
1194
1195 // Exclude the SureForms post type from AIOSEO's public post types.
1196 add_filter( 'aioseo_public_post_types', [ $this, 'unset_sureforms_post_type' ] );
1197 }
1198
1199 /**
1200 * Restrict interference of other plugins with SureForms.
1201 *
1202 * @since 0.0.5
1203 * @return void
1204 */
1205 private function restrict_unwanted_insertions() {
1206 // Restrict RankMath metaboxes in edit page.
1207 add_action( 'cmb2_admin_init', [ $this, 'restrict_data' ] );
1208
1209 // Restrict Yoast columns.
1210 add_filter( 'wpseo_accessible_post_types', [ $this, 'unset_sureforms_post_type' ] );
1211 add_filter( 'wpseo_metabox_prio', '__return_false' );
1212
1213 // Restrict AIOSEO columns.
1214 $this->restrict_in_aioseo_plugin();
1215 }
1216 }
1217