PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 1.6.2
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v1.6.2
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
1,086 lines 32.3 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: 65px;
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">
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 ],
617 ],
618 ],
619 'default' => [
620 'primary_color' => '#111C44',
621 'text_color' => '#1E1E1E',
622 'text_color_on_primary' => '#FFFFFF',
623 'field_spacing' => 'medium',
624 'submit_button_alignment' => 'left',
625 'bg_type' => 'color',
626 'bg_color' => '#ffffff',
627 'bg_image' => '',
628 'bg_image_position' => [
629 'x' => 0.5,
630 'y' => 0.5,
631 ],
632 'bg_image_attachment' => 'scroll',
633 'bg_image_repeat' => 'no-repeat',
634 'bg_image_size' => 'cover',
635 'bg_image_size_custom' => 100, // Image width when set to custom.
636 'bg_image_size_custom_unit' => '%',
637 'gradient_type' => 'basic',
638 'bg_gradient_type' => 'linear',
639 'bg_gradient_color_1' => '#FFC9B2',
640 'bg_gradient_color_2' => '#C7CBFF',
641 'bg_gradient_angle' => 90,
642 'bg_gradient_location_1' => 0,
643 'bg_gradient_location_2' => 100,
644 'bg_overlay_size' => 'cover',
645 'bg_gradient_overlay_type' => '',
646 'bg_overlay_opacity' => 1,
647 'bg_overlay_image' => '',
648 'bg_image_overlay_color' => '#FFFFFF75',
649 'bg_overlay_custom_size_unit' => '%',
650 'bg_overlay_custom_size' => 100,
651 'bg_overlay_position' => [
652 'x' => 0.5,
653 'y' => 0.5,
654 ],
655 'bg_overlay_attachment' => 'scroll',
656 'bg_overlay_repeat' => 'no-repeat',
657 'bg_overlay_blend_mode' => 'normal',
658 // Gradient Overlay Properties.
659 'overlay_gradient_type' => 'basic',
660 'bg_overlay_gradient_type' => 'linear',
661 'bg_overlay_gradient_color_1' => '#FFC9B2',
662 'bg_overlay_gradient_color_2' => '#C7CBFF',
663 'bg_overlay_gradient_angle' => 90,
664 'bg_overlay_gradient_location_1' => 0,
665 'bg_overlay_gradient_location_2' => 100,
666 ],
667 ]
668 );
669
670 // Email notification Metas.
671 register_post_meta(
672 'sureforms_form',
673 '_srfm_email_notification',
674 [
675 'single' => true,
676 'type' => 'array',
677 'auth_callback' => '__return_true',
678 'show_in_rest' => [
679 'schema' => [
680 'type' => 'array',
681 'items' => [
682 'type' => 'object',
683 'properties' => [
684 'id' => [
685 'type' => 'integer',
686 ],
687 'status' => [
688 'type' => 'boolean',
689 ],
690 'is_raw_format' => [
691 'type' => 'boolean',
692 ],
693 'name' => [
694 'type' => 'string',
695 ],
696 'email_to' => [
697 'type' => 'string',
698 ],
699 'email_reply_to' => [
700 'type' => 'string',
701 ],
702 'from_name' => [
703 'type' => 'string',
704 ],
705 'from_email' => [
706 'type' => 'string',
707 ],
708 'email_cc' => [
709 'type' => 'string',
710 ],
711 'email_bcc' => [
712 'type' => 'string',
713 ],
714 'subject' => [
715 'type' => 'string',
716 ],
717 'email_body' => [
718 'type' => 'string',
719 ],
720 ],
721 ],
722 ],
723 ],
724 'default' => [
725 [
726 'id' => 1,
727 'status' => true,
728 'is_raw_format' => false,
729 'name' => __( 'Admin Notification Email', 'sureforms' ),
730 'email_to' => '{admin_email}',
731 'email_reply_to' => '{admin_email}',
732 'from_name' => '{site_title}',
733 'from_email' => '{admin_email}',
734 'email_cc' => '{admin_email}',
735 'email_bcc' => '{admin_email}',
736 'subject' => sprintf( /* translators: %s: Form title smart tag */ __( 'New Form Submission - %s', 'sureforms' ), '{form_title}' ),
737 'email_body' => '{all_data}',
738 ],
739 ],
740 ]
741 );
742
743 // Compliance Settings metas.
744 register_post_meta(
745 'sureforms_form',
746 '_srfm_compliance',
747 [
748 'single' => true,
749 'type' => 'array',
750 'auth_callback' => '__return_true',
751 'show_in_rest' => [
752 'schema' => [
753 'type' => 'array',
754 'items' => [
755 'type' => 'object',
756 'properties' => [
757 'id' => [
758 'type' => 'string',
759 ],
760 'gdpr' => [
761 'type' => 'boolean',
762 ],
763 'do_not_store_entries' => [
764 'type' => 'boolean',
765 ],
766 'auto_delete_entries' => [
767 'type' => 'boolean',
768 ],
769 'auto_delete_days' => [
770 'type' => 'string',
771 ],
772 ],
773 ],
774 ],
775 ],
776 'default' => [
777 [
778 'id' => 'gdpr',
779 'gdpr' => false,
780 'do_not_store_entries' => false,
781 'auto_delete_entries' => false,
782 'auto_delete_days' => '',
783 ],
784 ],
785 ]
786 );
787
788 // form confirmation.
789 register_post_meta(
790 'sureforms_form',
791 '_srfm_form_confirmation',
792 [
793 'single' => true,
794 'type' => 'array',
795 'auth_callback' => '__return_true',
796 'show_in_rest' => [
797 'schema' => [
798 'type' => 'array',
799 'items' => [
800 'type' => 'object',
801 'properties' => [
802 'id' => [
803 'type' => 'integer',
804 ],
805 'confirmation_type' => [
806 'type' => 'string',
807 ],
808 'page_url' => [
809 'type' => 'string',
810 ],
811 'custom_url' => [
812 'type' => 'string',
813 ],
814 'message' => [
815 'type' => 'string',
816 ],
817 'submission_action' => [
818 'type' => 'string',
819 ],
820 'enable_query_params' => [
821 'type' => 'boolean',
822 ],
823 'query_params' => [
824 'type' => 'array',
825 ],
826 ],
827 ],
828 ],
829 ],
830 'default' => [
831 [
832 'id' => 1,
833 'confirmation_type' => 'same page',
834 'page_url' => '',
835 'custom_url' => '',
836 '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>',
837 'submission_action' => 'hide form',
838 ],
839 ],
840 ]
841 );
842
843 // conditional logic.
844 do_action( 'srfm_register_conditional_logic_post_meta' );
845 /**
846 * Hook for registering additional Post Meta
847 */
848 do_action( 'srfm_register_additional_post_meta' );
849 }
850
851 /**
852 * Custom Shortcode.
853 *
854 * @param array<mixed> $atts Attributes.
855 * @return string|false. $content Post Content.
856 * @since 0.0.1
857 */
858 public function forms_shortcode( array $atts ) {
859 $atts = shortcode_atts(
860 [
861 'id' => '',
862 'show_title' => true,
863 ],
864 $atts
865 );
866
867 $id = intval( $atts['id'] );
868 $post = get_post( $id );
869
870 if ( ! empty( $id ) && $post ) {
871 return Generate_Form_Markup::get_form_markup( $id, ! filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN ), '', 'post', true );
872 }
873
874 return '';
875 }
876
877 /**
878 * Add custom column header.
879 *
880 * @param array<mixed> $columns Attributes.
881 * @return array<mixed> $columns Post Content.
882 * @since 0.0.1
883 */
884 public function custom_form_columns( $columns ) {
885 return [
886 'cb' => $columns['cb'],
887 'title' => $columns['title'],
888 'sureforms' => __( 'Shortcode', 'sureforms' ),
889 'entries' => __( 'Entries', 'sureforms' ),
890 'author' => $columns['author'],
891 'date' => $columns['date'],
892 ];
893 }
894
895 /**
896 * Populate custom column with data.
897 *
898 * @param string $column Attributes.
899 * @param int $post_id Attributes.
900 * @return void
901 * @since 0.0.1
902 */
903 public function custom_form_column_data( $column, $post_id ) {
904 if ( 'sureforms' === $column ) {
905 ob_start();
906 ?>
907 <div class="srfm-shortcode-container">
908 <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 ) ); ?>']" />
909 <button type="button" class="components-button components-clipboard-button has-icon srfm-shortcode" onclick="handleFormShortcode(this)">
910 <span id="srfm-copy-icon" class="dashicon dashicons dashicons-admin-page"></span>
911 </button>
912 </div>
913 <?php
914 ob_end_flush();
915 }
916 if ( 'entries' === $column ) {
917 // Entries URL to redirect user based on the form ID.
918 $entries_url = wp_nonce_url(
919 add_query_arg(
920 [
921 'form_filter' => $post_id,
922 ],
923 admin_url( 'admin.php?page=sureforms_entries' )
924 ),
925 'srfm_entries_action'
926 );
927
928 // Get the entry count for the form.
929 $entries_count = Entries::get_total_entries_by_status( 'all', $post_id );
930
931 ob_start();
932 ?>
933 <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>
934 <?php
935 ob_end_flush();
936 }
937 }
938
939 /**
940 * Show the import form popup
941 *
942 * @since 0.0.1
943 * @return void
944 */
945 public function import_form_popup() {
946 $screen = get_current_screen();
947 $id = $screen ? $screen->id : '';
948 if ( 'edit-sureforms_form' === $id ) {
949 ?>
950 <div class="srfm-import-plugin-wrap">
951 <div class="srfm-import-wrap">
952 <p class="srfm-import-help"><?php echo esc_html__( 'Please choose the SureForms export file (.json) that you wish to import.', 'sureforms' ); ?></p>
953 <form method="post" enctype="multipart/form-data" class="srfm-import-form">
954 <input type="file" id="srfm-import-file" onchange="handleFileChange(event)" name="import form" accept=".json">
955 <input type="submit" name="import-form-submit" id="import-form-submit" class="srfm-import-button" value="<?php esc_attr_e( 'Import Now', 'sureforms' ); ?>" disabled>
956 </form>
957 <p id="srfm-import-error"><?php echo esc_html__( 'There is some error in json file, please export the SureForms Forms again.', 'sureforms' ); ?></p>
958 </div>
959 </div>
960 <?php
961 }
962 }
963
964 /**
965 * Redirect to home page if instant form is not enabled.
966 *
967 * @since 0.0.1
968 * @return void
969 */
970 public function srfm_instant_form_redirect() {
971
972 $form_id = Helper::get_integer_value( get_the_ID() );
973
974 $instant_form_settings = Helper::get_array_value( Helper::get_post_meta( $form_id, '_srfm_instant_form_settings' ) );
975 $enable_instant_form = ! empty( $instant_form_settings['enable_instant_form'] ) ? boolval( $instant_form_settings['enable_instant_form'] ) : false;
976
977 if ( $enable_instant_form ) {
978 return;
979 }
980
981 $form_preview = '';
982
983 $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.
984
985 if ( $form_preview_attr ) {
986 $form_preview = filter_var( $form_preview_attr, FILTER_VALIDATE_BOOLEAN );
987 }
988
989 if ( is_singular( 'sureforms_form' ) && ! $form_preview && ! current_user_can( 'manage_options' ) ) {
990 wp_safe_redirect( home_url() );
991 return;
992 }
993 }
994
995 /**
996 * Restrict RankMath meta boxes in edit page.
997 *
998 * @since 0.0.5
999 * @return void
1000 */
1001 public function restrict_data() {
1002 add_filter( 'rank_math/excluded_post_types', [ $this, 'unset_sureforms_post_type' ] );
1003 }
1004
1005 /**
1006 * Remove SureForms post type from RankMath and Yoast.
1007 *
1008 * @param array<mixed> $post_types Post types.
1009 * @since 0.0.5
1010 * @return array<mixed> $post_types Modified post types.
1011 */
1012 public function unset_sureforms_post_type( $post_types ) {
1013 return array_filter(
1014 $post_types,
1015 static function( $post_type ) {
1016 if ( is_array( $post_type ) && isset( $post_type['name'] ) ) {
1017 return SRFM_FORMS_POST_TYPE !== $post_type['name'];
1018 }
1019 return SRFM_FORMS_POST_TYPE !== $post_type;
1020 }
1021 );
1022 }
1023
1024 /**
1025 * Restrict unwanted insertions from the AIOSEO plugin.
1026 *
1027 * This method ensures that the SureForms post type is excluded from AIOSEO's
1028 * public post types unless the current page is related to AIOSEO settings.
1029 *
1030 * @return void
1031 * @since 1.6.0
1032 */
1033 public function restrict_in_aioseo_plugin() {
1034 /**
1035 * Checks if the AIOSEO plugin is installed and excludes the SureForms post type from AIOSEO's public post types.
1036 *
1037 * - Verifies the presence of the AIOSEO_DIR constant to ensure AIOSEO is installed.
1038 * - Allows AIOSEO functionality on its own settings pages by checking the `REQUEST_URI` and `page` query parameter.
1039 * - Excludes the SureForms post type from AIOSEO's public post types using the `aioseo_public_post_types` filter.
1040 *
1041 * Security Note:
1042 * - Nonce verification is intentionally skipped (`phpcs:ignore WordPress.Security.NonceVerification.Recommended`)
1043 * because this code is only performing a read operation to check the current request URI and query parameters.
1044 * It does not modify or process sensitive data, making nonce verification unnecessary in this context.
1045 */
1046 // Check if AIOSEO is installed by verifying the AIOSEO_DIR constant.
1047 if ( ! defined( 'AIOSEO_DIR' ) ) {
1048 return;
1049 }
1050
1051 // Allow AIOSEO functionality on its own settings pages.
1052 if ( isset( $_SERVER['REQUEST_URI'] ) ) {
1053 $request_uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) );
1054 if ( strpos( $request_uri, 'admin.php' ) !== false ) {
1055 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.
1056 $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.
1057 if ( strpos( $page, 'aioseo' ) !== false ) {
1058 return;
1059 }
1060 }
1061 }
1062 }
1063
1064 // Exclude the SureForms post type from AIOSEO's public post types.
1065 add_filter( 'aioseo_public_post_types', [ $this, 'unset_sureforms_post_type' ] );
1066 }
1067
1068 /**
1069 * Restrict interference of other plugins with SureForms.
1070 *
1071 * @since 0.0.5
1072 * @return void
1073 */
1074 private function restrict_unwanted_insertions() {
1075 // Restrict RankMath metaboxes in edit page.
1076 add_action( 'cmb2_admin_init', [ $this, 'restrict_data' ] );
1077
1078 // Restrict Yoast columns.
1079 add_filter( 'wpseo_accessible_post_types', [ $this, 'unset_sureforms_post_type' ] );
1080 add_filter( 'wpseo_metabox_prio', '__return_false' );
1081
1082 // Restrict AIOSEO columns.
1083 $this->restrict_in_aioseo_plugin();
1084 }
1085 }
1086