PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 0.0.9
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v0.0.9
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,320 lines 38.6 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 WP_Query;
12 use WP_Admin_Bar;
13 use SRFM\Inc\Traits\Get_Instance;
14 use SRFM\Inc\Generate_Form_Markup;
15 use SRFM\Inc\Helper;
16
17 if ( ! defined( 'ABSPATH' ) ) {
18 exit; // Exit if accessed directly.
19 }
20
21 /**
22 * Post Types Main Class.
23 *
24 * @since 0.0.1
25 */
26 class Post_Types {
27 use Get_Instance;
28
29 /**
30 * Constructor
31 *
32 * @since 0.0.1
33 */
34 public function __construct() {
35 $this->restrict_unwanted_insertions();
36 add_action( 'init', [ $this, 'register_post_types' ] );
37 add_action( 'init', [ $this, 'register_post_metas' ] );
38 add_filter( 'manage_sureforms_form_posts_columns', [ $this, 'custom_form_columns' ] );
39 add_action( 'manage_sureforms_form_posts_custom_column', [ $this, 'custom_form_column_data' ], 10, 2 );
40 add_filter( 'manage_sureforms_entry_posts_columns', [ $this, 'custom_entry_columns' ] );
41 add_action( 'manage_sureforms_entry_posts_custom_column', [ $this, 'custom_entry_column_data' ], 10, 2 );
42 add_shortcode( 'sureforms', [ $this, 'forms_shortcode' ] );
43 add_action( 'add_meta_boxes', [ $this, 'entries_meta_box' ] );
44 add_action( 'restrict_manage_posts', [ $this, 'add_tax_filter' ] );
45 add_action( 'manage_posts_extra_tablenav', [ $this, 'maybe_render_blank_form_state' ] );
46 add_action( 'in_admin_header', [ $this, 'embed_page_header' ] );
47 add_action( 'admin_head', [ $this, 'remove_entries_publishing_actions' ] );
48 add_filter( 'post_row_actions', [ $this, 'modify_entries_list_row_actions' ], 10, 2 );
49 add_filter( 'post_updated_messages', [ $this, 'entries_updated_message' ] );
50 add_filter( 'bulk_actions-edit-sureforms_form', [ $this, 'register_modify_bulk_actions' ], 99 );
51 add_action( 'admin_notices', [ $this, 'import_form_popup' ] );
52 add_action( 'admin_bar_menu', [ $this, 'remove_admin_bar_menu_item' ], 80, 1 );
53 add_action( 'template_redirect', [ $this, 'srfm_instant_form_redirect' ] );}
54
55 /**
56 * Add SureForms menu.
57 *
58 * @param string $title Parent slug.
59 * @param string $subtitle Parent slug.
60 * @param string $image Parent slug.
61 * @param string $button_text Parent slug.
62 * @param string $button_url Parent slug.
63 * @return void
64 * @since 0.0.1
65 */
66 public function get_blank_page_markup( $title, $subtitle, $image, $button_text = '', $button_url = '' ) {
67 echo '<div class="sureform-add-new-form">';
68
69 echo '<p class="sureform-blank-page-title">' . esc_html( $title ) . '</p>';
70
71 echo '<p class="sureform-blank-page-subtitle">' . esc_html( $subtitle ) . '</p>';
72
73 echo '<img src="' . esc_url( SRFM_URL . '/images/' . $image . '.svg' ) . '">';
74
75 if ( ! empty( $button_text ) && ! empty( $button_url ) ) {
76 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></div>';
77 }
78
79 echo '</div>';
80 }
81
82 /**
83 * Render blank state for add new form screen.
84 *
85 * @param string $post_type Post type.
86 * @return void
87 * @since 0.0.1
88 */
89 public function sureforms_render_blank_state( $post_type ) {
90
91 if ( SRFM_FORMS_POST_TYPE === $post_type ) {
92 $page_name = 'add-new-form';
93 $new_form_url = admin_url( 'admin.php?page=' . $page_name );
94
95 $this->get_blank_page_markup(
96 esc_html__( 'Let’s build your first form', 'sureforms' ),
97 esc_html__(
98 'Craft beautiful and functional forms in minutes',
99 'sureforms'
100 ),
101 'add-new-form',
102 esc_html__( 'Add New Form', 'sureforms' ),
103 $new_form_url
104 );
105 }
106
107 if ( SRFM_ENTRIES_POST_TYPE === $post_type ) {
108
109 $this->get_blank_page_markup(
110 esc_html__( 'No records found', 'sureforms' ),
111 esc_html__(
112 'This is where your form entries will appear',
113 'sureforms'
114 ),
115 'blank-entries'
116 );
117 }
118 }
119
120 /**
121 * Registers the forms and submissions post types.
122 *
123 * @return void
124 * @since 0.0.1
125 */
126 public function register_post_types() {
127 $form_labels = [
128 'name' => _x( 'Forms', 'post type general name', 'sureforms' ),
129 'singular_name' => _x( 'Form', 'post type singular name', 'sureforms' ),
130 'menu_name' => _x( 'Forms', 'admin menu', 'sureforms' ),
131 'add_new' => _x( 'Add New', 'form', 'sureforms' ),
132 'add_new_item' => __( 'Add New Form', 'sureforms' ),
133 'new_item' => __( 'New Form', 'sureforms' ),
134 'edit_item' => __( 'Edit Form', 'sureforms' ),
135 'view_item' => __( 'View Form', 'sureforms' ),
136 'view_items' => __( 'View Forms', 'sureforms' ),
137 'all_items' => __( 'Forms', 'sureforms' ),
138 'search_items' => __( 'Search Forms', 'sureforms' ),
139 'parent_item_colon' => __( 'Parent Forms:', 'sureforms' ),
140 'not_found' => __( 'No forms found.', 'sureforms' ),
141 'not_found_in_trash' => __( 'No forms found in Trash.', 'sureforms' ),
142 'item_published' => __( 'Form published.', 'sureforms' ),
143 'item_updated' => __( 'Form updated.', 'sureforms' ),
144 ];
145 register_post_type(
146 SRFM_FORMS_POST_TYPE,
147 [
148 'labels' => $form_labels,
149 'rewrite' => [ 'slug' => 'form' ],
150 'public' => true,
151 'show_in_rest' => true,
152 'has_archive' => false,
153 'show_ui' => true,
154 'supports' => [ 'title', 'author', 'editor', 'custom-fields' ],
155 'show_in_menu' => 'sureforms_menu',
156 'show_in_nav_menus' => true,
157 ]
158 );
159
160 $result_labels = [
161 'name' => _x( 'Entries', 'post type general name', 'sureforms' ),
162 'singular_name' => _x( 'Entry', 'post type singular name', 'sureforms' ),
163 'menu_name' => _x( 'Entries', 'admin menu', 'sureforms' ),
164 'name_admin_bar' => _x( 'Entry', 'add new on admin bar', 'sureforms' ),
165 'add_new' => _x( 'Add New', 'Entry', 'sureforms' ),
166 'add_new_item' => __( 'Add New Entry', 'sureforms' ),
167 'new_item' => __( 'New Entry', 'sureforms' ),
168 'edit_item' => __( 'View Entry', 'sureforms' ),
169 'view_item' => __( 'View Entry', 'sureforms' ),
170 'all_items' => __( 'Entries', 'sureforms' ),
171 'search_items' => __( 'Search Entries', 'sureforms' ),
172 'parent_item_colon' => __( 'Parent Entries:', 'sureforms' ),
173 'not_found' => __( 'No results found.', 'sureforms' ),
174 'not_found_in_trash' => __( 'No results found in Trash.', 'sureforms' ),
175 ];
176 register_post_type(
177 SRFM_ENTRIES_POST_TYPE,
178 [
179 'labels' => $result_labels,
180 'supports' => [ 'title' ],
181 'public' => false,
182 'show_in_rest' => true,
183 'exclude_from_search' => true,
184 'publicly_queryable' => false,
185 'has_archive' => true,
186 'capability_type' => 'post',
187 'capabilities' => [
188 'create_posts' => 'do_not_allow',
189 ],
190 'map_meta_cap' => true,
191 'show_ui' => true,
192 'show_in_menu' => 'sureforms_menu',
193 ]
194 );
195 register_taxonomy(
196 'sureforms_tax',
197 'sureforms_entry',
198 [
199 'label' => __( 'Form ID', 'sureforms' ),
200 'hierarchical' => true,
201 'capabilities' => [
202 'assign_terms' => 'god',
203 'edit_terms' => 'god',
204 'manage_terms' => 'god',
205 ],
206 'public' => false,
207 'show_in_rest' => true,
208 'show_admin_column' => false,
209 'show_in_nav_menus' => false,
210 'show_ui' => false,
211 ]
212 );
213 // will be used later.
214 // register_post_status(
215 // 'unread',
216 // array(
217 // 'label' => _x( 'Unread', 'sureforms', 'sureforms' ),
218 // 'public' => true,
219 // 'exclude_from_search' => false,
220 // 'show_in_admin_all_list' => true,
221 // 'show_in_admin_status_list' => true,
222 // Translators: %s is the number of unread items.
223 // 'label_count' => _n_noop( 'Unread (%s)', 'Unread (%s)', 'sureforms' ),
224 // )
225 // );.
226 }
227
228 /**
229 * Remove add new form menu item.
230 *
231 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance.
232 *
233 * @return void
234 * @since 0.0.1
235 */
236 public function remove_admin_bar_menu_item( $wp_admin_bar ) {
237 $wp_admin_bar->remove_node( 'new-sureforms_form' );
238 }
239
240 /**
241 * Modify post update message for Entry post type.
242 *
243 * @param string $messages Post type.
244 * @return string
245 * @since 0.0.1
246 */
247 public function entries_updated_message( $messages ) {
248 global $post_ID;
249
250 $post_type = get_post_type( $post_ID );
251
252 if ( SRFM_ENTRIES_POST_TYPE === $post_type ) {
253 // @phpstan-ignore-next-line -- False positive
254 $messages['post'][1] = __( 'Entry updated.', 'sureforms' );
255 }
256
257 return $messages;
258 }
259
260 /**
261 * Remove publishing actions from single entries page.
262 *
263 * @return void
264 * @since 0.0.1
265 */
266 public function remove_entries_publishing_actions() {
267 global $typenow;
268 if ( 'sureforms_entry' === $typenow ) { ?>
269 <style>
270 .misc-pub-post-status {
271 display: none !important;
272 }
273 .misc-pub-visibility {
274 display: none !important;
275 }
276 </style>
277 <?php
278 }
279 }
280
281 /**
282 * Modify list row actions.
283 *
284 * @param array<mixed> $actions An array of row action links.
285 * @param \WP_Post $post The current WP_Post object.
286 *
287 * @return array<mixed> $actions Modified row action links.
288 * @since 0.0.1
289 */
290 public function modify_entries_list_row_actions( $actions, $post ) {
291 if ( 'sureforms_entry' === $post->post_type ) {
292 $actions['edit'] = '<a href="' . get_edit_post_link( $post->ID ) . '">View</a>';
293 }
294 if ( 'sureforms_form' === $post->post_type ) {
295 $actions['export'] = '<a href="#" onclick="exportForm(' . $post->ID . ')">Export</a>';
296 }
297
298 return $actions;
299 }
300
301 /**
302 * Modify list bulk actions.
303 *
304 * @param array<mixed> $bulk_actions An array of bulk action links.
305 * @since 0.0.1
306 * @return array<mixed> $bulk_actions Modified action links.
307 */
308 public function register_modify_bulk_actions( $bulk_actions ) {
309
310 $white_listed_actions = [
311 'edit',
312 'trash',
313 'delete',
314 'untrash',
315 ];
316
317 // remove all actions except white listed actions.
318 $bulk_actions = array_intersect_key( $bulk_actions, array_flip( $white_listed_actions ) );
319
320 // Add export action only if edit and trash actions are present in bulk actions.
321 if ( isset( $bulk_actions['edit'] ) && isset( $bulk_actions['trash'] ) ) {
322 $bulk_actions['export'] = __( 'Export', 'sureforms' );
323 }
324
325 return $bulk_actions;
326 }
327
328 /**
329 * Show blank slate styles.
330 *
331 * @return void
332 * @since 0.0.1
333 */
334 public function get_blank_state_styles() {
335 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>';
336 }
337
338 /**
339 * Show blank slate.
340 *
341 * @param string $which String which tablenav is being shown.
342 * @return void
343 * @since 0.0.1
344 */
345 public function maybe_render_blank_form_state( $which ) {
346 $screen = get_current_screen();
347 $post_type = $screen ? $screen->post_type : '';
348
349 if ( SRFM_FORMS_POST_TYPE === $post_type && 'bottom' === $which ) {
350
351 $counts = (array) wp_count_posts( SRFM_FORMS_POST_TYPE );
352 unset( $counts['auto-draft'] );
353 $count = array_sum( $counts );
354
355 if ( 0 < $count ) {
356 return;
357 }
358
359 $this->sureforms_render_blank_state( $post_type );
360
361 $this->get_blank_state_styles();
362
363 }
364
365 if ( SRFM_ENTRIES_POST_TYPE === $post_type && 'bottom' === $which ) {
366
367 $counts = (array) wp_count_posts( SRFM_ENTRIES_POST_TYPE );
368 unset( $counts['auto-draft'] );
369 $count = array_sum( $counts );
370
371 if ( 0 < $count ) {
372 return;
373 }
374
375 $this->sureforms_render_blank_state( $post_type );
376
377 $this->get_blank_state_styles();
378
379 }
380 }
381
382 /**
383 * Set up a div for the header to render into it.
384 *
385 * @return void
386 * @since 0.0.1
387 */
388 public static function embed_page_header() {
389 $screen = get_current_screen();
390 $screen_id = $screen ? $screen->id : '';
391
392 if ( 'edit-' . SRFM_FORMS_POST_TYPE === $screen_id || 'edit-' . SRFM_ENTRIES_POST_TYPE === $screen_id ) {
393 ?>
394 <style>
395 .srfm-page-header {
396 @media screen and ( max-width: 600px ) {
397 padding-top: 46px;
398 }
399 }
400 </style>
401 <div id="srfm-page-header" class="srfm-page-header"></div>
402 <?php
403 }
404 }
405
406 /**
407 * Registers the sureforms metas.
408 *
409 * @return void
410 * @since 0.0.1
411 */
412 public function register_post_metas() {
413 $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
414
415 $metas = apply_filters(
416 'srfm_register_post_meta',
417 [
418 // General tab metas.
419 '_srfm_use_label_as_placeholder' => 'boolean',
420 '_srfm_submit_button_text' => 'string',
421 '_srfm_is_inline_button' => 'boolean',
422 // Submit Button.
423 '_srfm_submit_width_backend' => 'string',
424 '_srfm_button_border_radius' => 'integer',
425 '_srfm_submit_alignment' => 'string',
426 '_srfm_submit_alignment_backend' => 'string',
427 '_srfm_submit_width' => 'string',
428 '_srfm_inherit_theme_button' => 'boolean',
429 // Additional Classes.
430 '_srfm_additional_classes' => 'string',
431
432 // Advanced tab metas.
433 // Success Message.
434 '_srfm_submit_type' => 'string',
435 '_srfm_thankyou_message_title' => 'string',
436 '_srfm_thankyou_message' => 'string',
437 '_srfm_submit_url' => 'string',
438 // Security.
439 '_srfm_captcha_security_type' => 'string',
440 '_srfm_form_recaptcha' => 'string',
441 ]
442 );
443
444 // Form Custom CSS meta.
445 register_post_meta(
446 'sureforms_form',
447 '_srfm_form_custom_css',
448 [
449 'show_in_rest' => true,
450 'type' => 'string',
451 'single' => true,
452 'auth_callback' => function() {
453 return current_user_can( 'edit_posts' );
454 },
455 'sanitize_callback' => function( $meta_value ) {
456 return wp_kses_post( $meta_value );
457 },
458 ]
459 );
460
461 foreach ( $metas as $meta => $type ) {
462 register_meta(
463 'post',
464 $meta,
465 [
466 'object_subtype' => SRFM_FORMS_POST_TYPE,
467 'show_in_rest' => true,
468 'single' => true,
469 'type' => $type,
470 'sanitize_callback' => 'sanitize_text_field',
471 'auth_callback' => function() {
472 return current_user_can( 'edit_posts' );
473 },
474 ]
475 );
476 }
477
478 // Registers meta to handle values associated with form styling.
479 register_post_meta(
480 SRFM_FORMS_POST_TYPE,
481 '_srfm_instant_form_settings',
482 [
483 'single' => true,
484 'type' => 'object',
485 'auth_callback' => '__return_true',
486 'show_in_rest' => [
487 'schema' => [
488 'type' => 'object',
489 'properties' => [
490 'site_logo' => [
491 'type' => 'string',
492 ],
493 'site_logo_id' => [
494 'type' => 'integer',
495 ],
496 // Form page banner settings.
497 'cover_type' => [
498 'type' => 'string',
499 ],
500 'cover_color' => [
501 'type' => 'string',
502 ],
503 'cover_image' => [
504 'type' => 'string',
505 ],
506 'cover_image_id' => [
507 'type' => 'integer',
508 ],
509 // Form page background settings.
510 'bg_type' => [
511 'type' => 'string',
512 ],
513 'bg_color' => [
514 'type' => 'string',
515 ],
516 'bg_image' => [
517 'type' => 'string',
518 ],
519 'bg_image_id' => [
520 'type' => 'integer',
521 ],
522 'enable_instant_form' => [
523 'type' => 'boolean',
524 ],
525 'form_container_width' => [
526 'type' => 'integer',
527 ],
528 'single_page_form_title' => [
529 'type' => 'boolean',
530 ],
531 'use_banner_as_page_background' => [
532 'type' => 'boolean',
533 ],
534 ],
535 ],
536 ],
537 'default' => [
538 'bg_type' => 'color',
539 'bg_color' => '#ffffff',
540 'bg_image' => '',
541 'site_logo' => '',
542 'cover_type' => 'color',
543 'cover_color' => '#0C78FB',
544 'cover_image' => '',
545 'enable_instant_form' => false,
546 'form_container_width' => 560,
547 'single_page_form_title' => true,
548 'use_banner_as_page_background' => false,
549 ],
550 ]
551 );
552
553 register_post_meta(
554 SRFM_FORMS_POST_TYPE,
555 '_srfm_forms_styling',
556 [
557 'single' => true,
558 'type' => 'object',
559 'auth_callback' => '__return_true',
560 'show_in_rest' => [
561 'schema' => [
562 'type' => 'object',
563 'properties' => [
564 'primary_color' => [
565 'type' => 'string',
566 ],
567 'text_color' => [
568 'type' => 'string',
569 ],
570 'text_color_on_primary' => [
571 'type' => 'string',
572 ],
573 'field_spacing' => [
574 'type' => 'string',
575 ],
576 'submit_button_alignment' => [
577 'type' => 'string',
578 ],
579 ],
580 ],
581 ],
582 'default' => [
583 'primary_color' => '#0C78FB',
584 'text_color' => '#1E1E1E',
585 'text_color_on_primary' => '#FFFFFF',
586 'field_spacing' => 'medium',
587 'submit_button_alignment' => 'left',
588 ],
589 ]
590 );
591
592 // Email notification Metas.
593 register_post_meta(
594 'sureforms_form',
595 '_srfm_email_notification',
596 [
597 'single' => true,
598 'type' => 'array',
599 'auth_callback' => '__return_true',
600 'show_in_rest' => [
601 'schema' => [
602 'type' => 'array',
603 'items' => [
604 'type' => 'object',
605 'properties' => [
606 'id' => [
607 'type' => 'integer',
608 ],
609 'status' => [
610 'type' => 'boolean',
611 ],
612 'is_raw_format' => [
613 'type' => 'boolean',
614 ],
615 'name' => [
616 'type' => 'string',
617 ],
618 'email_to' => [
619 'type' => 'string',
620 ],
621 'email_reply_to' => [
622 'type' => 'string',
623 ],
624 'email_cc' => [
625 'type' => 'string',
626 ],
627 'email_bcc' => [
628 'type' => 'string',
629 ],
630 'subject' => [
631 'type' => 'string',
632 ],
633 'email_body' => [
634 'type' => 'string',
635 ],
636 ],
637 ],
638 ],
639 ],
640 'default' => [
641 [
642 'id' => 1,
643 'status' => true,
644 'is_raw_format' => false,
645 'name' => 'Admin Notification Email',
646 'email_to' => '{admin_email}',
647 'email_reply_to' => '{admin_email}',
648 'email_cc' => '{admin_email}',
649 'email_bcc' => '{admin_email}',
650 'subject' => 'New Form Submission',
651 'email_body' => '{all_data}',
652 ],
653 ],
654 ]
655 );
656
657 // Compliance Settings metas.
658 register_post_meta(
659 'sureforms_form',
660 '_srfm_compliance',
661 [
662 'single' => true,
663 'type' => 'array',
664 'auth_callback' => '__return_true',
665 'show_in_rest' => [
666 'schema' => [
667 'type' => 'array',
668 'items' => [
669 'type' => 'object',
670 'properties' => [
671 'id' => [
672 'type' => 'string',
673 ],
674 'gdpr' => [
675 'type' => 'boolean',
676 ],
677 'do_not_store_entries' => [
678 'type' => 'boolean',
679 ],
680 'auto_delete_entries' => [
681 'type' => 'boolean',
682 ],
683 'auto_delete_days' => [
684 'type' => 'string',
685 ],
686 ],
687 ],
688 ],
689 ],
690 'default' => [
691 [
692 'id' => 'gdpr',
693 'gdpr' => false,
694 'do_not_store_entries' => false,
695 'auto_delete_entries' => false,
696 'auto_delete_days' => '',
697 ],
698 ],
699 ]
700 );
701
702 // form confirmation.
703 register_post_meta(
704 'sureforms_form',
705 '_srfm_form_confirmation',
706 [
707 'single' => true,
708 'type' => 'array',
709 'auth_callback' => '__return_true',
710 'show_in_rest' => [
711 'schema' => [
712 'type' => 'array',
713 'items' => [
714 'type' => 'object',
715 'properties' => [
716 'id' => [
717 'type' => 'integer',
718 ],
719 'confirmation_type' => [
720 'type' => 'string',
721 ],
722 'page_url' => [
723 'type' => 'string',
724 ],
725 'custom_url' => [
726 'type' => 'string',
727 ],
728 'message' => [
729 'type' => 'string',
730 ],
731 'submission_action' => [
732 'type' => 'string',
733 ],
734 ],
735 ],
736 ],
737 ],
738 'default' => [
739 [
740 'id' => 1,
741 'confirmation_type' => 'same page',
742 'page_url' => '',
743 'custom_url' => '',
744 'message' => '<p style="text-align: center;"><img src="' . esc_attr( $check_icon ) . '"></img></p><h2 style="text-align: center;">Thank you</h2><p style="text-align: center;">We have received your email. You\'ll hear from us as soon as possible.</p><p style="text-align: center;">Please be sure to whitelist our {admin_email} email address to ensure our replies reach your inbox safely.</p>',
745 'submission_action' => 'hide form',
746 ],
747 ],
748 ]
749 );
750
751 // Sureforms entry metas.
752 register_post_meta(
753 'sureforms_entry',
754 '_srfm_submission_info',
755 [
756 'single' => true,
757 'type' => 'array',
758 'auth_callback' => '__return_true',
759 'show_in_rest' => [
760 'schema' => [
761 'type' => 'array',
762 'items' => [
763 'type' => 'object',
764 'properties' => [
765 'user_ip' => [
766 'type' => 'string',
767 ],
768 'browser_name' => [
769 'type' => 'string',
770 ],
771 'device_name' => [
772 'type' => 'string',
773 ],
774 ],
775 ],
776 ],
777 ],
778 ]
779 );
780
781 // store form id in entry.
782 register_post_meta(
783 'sureforms_entry',
784 '_srfm_entry_form_id',
785 [
786 'single' => true,
787 'type' => 'integer',
788 'auth_callback' => '__return_true',
789 'show_in_rest' => true,
790 ]
791 );
792
793 // conditional logic.
794 do_action( 'srfm_register_conditional_logic_post_meta' );
795 /**
796 * Hook for registering additional Post Meta
797 */
798 do_action( 'srfm_register_additional_post_meta' );
799
800 }
801
802 /**
803 * Sureforms entries meta box callback.
804 *
805 * @param \WP_Post $post Template.
806 * @return void
807 * @since 0.0.1
808 */
809 public function sureforms_meta_box_callback( \WP_Post $post ) {
810 $meta_data = get_post_meta( $post->ID, 'srfm_entry_meta', true );
811 if ( ! is_array( $meta_data ) ) {
812 return;
813 }
814 $excluded_fields = [ 'srfm-honeypot-field', 'g-recaptcha-response', 'srfm-sender-email-field' ];
815
816 ?>
817 <table class="widefat striped">
818 <tbody>
819 <tr><th><b><?php esc_html_e( 'Fields', 'sureforms' ); ?></b></th><th><b><?php esc_html_e( 'Values', 'sureforms' ); ?></b></th></tr>
820 <?php
821 foreach ( $meta_data as $field_name => $value ) :
822 if ( in_array( $field_name, $excluded_fields, true ) ) {
823 continue;
824 }
825
826 if ( false === str_contains( $field_name, '-lbl-' ) ) {
827 continue;
828 }
829
830 $label = explode( '-lbl-', $field_name )[1];
831 // Getting the encrypted label. we are removing the block slug here.
832 $label = explode( '-', $label )[0];
833
834 ?>
835 <tr>
836 <td><b><?php echo $label ? esc_html( Helper::decrypt( $label ) ) : ''; ?><b></td>
837 <?php if ( strpos( $field_name, 'srfm-upload' ) !== false ) : ?>
838 <style>
839 .file-cards-container {
840 display: flex;
841 flex-wrap: wrap;
842 gap: 10px;
843 }
844
845 .file-card {
846 border: 1px solid #ddd;
847 border-radius: 4px;
848 padding: 10px;
849 width: 100px; /* Reduced width */
850 text-align: center;
851 background: #f9f9f9;
852 font-size: 12px; /* Reduced font size for smaller cards */
853 }
854
855 .file-card-image img {
856 max-width: 80px; /* Reduced max width */
857 max-height: 80px; /* Reduced max height */
858 object-fit: cover;
859 }
860
861 .file-card-icon {
862 font-size: 24px; /* Reduced icon size */
863 margin-bottom: 5px;
864 }
865
866 .file-card-details {
867 margin-bottom: 5px;
868 font-weight: bold;
869 }
870
871 .file-card-url a {
872 color: #007bff;
873 text-decoration: none;
874 font-size: 12px; /* Reduced font size */
875 }
876
877 .file-card-url a:hover {
878 text-decoration: underline;
879 }
880 </style>
881 <td>
882 <div class="file-cards-container">
883 <?php
884 $upload_values = $value;
885 if ( ! empty( $upload_values ) && is_array( $upload_values ) ) {
886 foreach ( $upload_values as $value ) {
887 $value = Helper::get_string_value( $value );
888 if ( ! empty( $value ) ) {
889 $file_type = pathinfo( $value, PATHINFO_EXTENSION );
890 $is_image = in_array( $file_type, [ 'gif', 'png', 'bmp', 'jpg', 'jpeg', 'svg' ], true );
891 ?>
892 <div class="file-card">
893 <?php if ( $is_image ) : ?>
894 <div class="file-card-image">
895 <a target="_blank" href="<?php echo esc_attr( urldecode( $value ) ); ?>">
896 <img src="<?php echo esc_attr( urldecode( $value ) ); ?>" alt="img" />
897 </a>
898 </div>
899 <?php else : ?>
900 <div class="file-card-icon">
901 <?php echo '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16.333V4.667a1.333 1.333 0 011.333-1.333h13.334a1.333 1.333 0 011.333 1.333v11.666a1.333 1.333 0 01-1.333 1.333H5.333A1.333 1.333 0 014 16.333zm8-8h2v6h-2v-6zm-2 8h6v2H10v-2zm-6-6h4v6H4v-6zm0-4h16v2H4V6z"/></svg>'; ?>
902 </div>
903 <div class="file-card-details">
904 <span><?php echo esc_html( strtoupper( $file_type ) ); ?></span>
905 </div>
906 <?php endif; ?>
907 <div class="file-card-url">
908 <a target="_blank" href="<?php echo esc_attr( urldecode( $value ) ); ?>"><?php echo esc_html__( 'Open', 'sureforms' ); ?></a>
909 </div>
910 </div>
911 <?php
912 }
913 }
914 }
915 ?>
916 </div>
917 </td>
918 <?php elseif ( strpos( $field_name, 'srfm-url' ) !== false ) : ?>
919 <?php if ( ! $value ) : ?>
920 <td><?php echo ''; ?></td>
921 <?php else : ?>
922 <?php
923 if (
924 substr( $value, 0, 7 ) !== 'http://' &&
925 substr( $value, 0, 8 ) !== 'https://'
926 ) {
927 $value = 'https://' . $value;
928 }
929 ?>
930 <td><a target="_blank" href="<?php echo esc_url( $value ); ?>"><?php echo esc_url( $value ); ?></a></td>
931 <?php endif; ?>
932 <?php else : ?>
933 <td><?php echo false !== strpos( $value, PHP_EOL ) ? wp_kses_post( wpautop( $value ) ) : wp_kses_post( $value ); ?></td>
934 <?php endif; ?>
935 </tr>
936 <?php endforeach; ?>
937 </tbody>
938 </table>
939 <?php
940 }
941
942
943 /**
944 * Add Sureforms entries meta box.
945 *
946 * @return void
947 * @since 0.0.1
948 */
949 public function entries_meta_box() {
950 add_meta_box(
951 'sureform_entry_meta',
952 'Form Data',
953 [ $this, 'sureforms_meta_box_callback' ],
954 'sureforms_entry',
955 'normal',
956 'high'
957 );
958 add_meta_box(
959 'sureform_form_name_meta',
960 'Submission Info',
961 [ $this, 'sureforms_form_name_meta_callback' ],
962 'sureforms_entry',
963 'side',
964 'low'
965 );
966 }
967
968 /**
969 * Sureforms box Form Name meta box callback.
970 *
971 * @param \WP_Post $post Template.
972 * @return void
973 * @since 0.0.1
974 */
975 public function sureforms_form_name_meta_callback( \WP_Post $post ) {
976 $post_id = $post->ID;
977 $taxonomy = 'sureforms_tax';
978 $terms = wp_get_post_terms( $post_id, $taxonomy );
979 if ( is_array( $terms ) && count( $terms ) > 0 ) {
980 $form_id = intval( $terms[0]->slug );
981 $form_name = ! empty( get_the_title( $form_id ) ) ? get_the_title( $form_id ) : 'SureForms Form';
982 $submission_info = get_post_meta( $post_id, '_srfm_submission_info', true );
983 if ( is_array( $submission_info ) && count( $submission_info ) > 0 ) {
984 $user_ip = $submission_info[0]['user_ip'] ? $submission_info[0]['user_ip'] : '';
985 $browser_name = $submission_info[0]['browser_name'] ? $submission_info[0]['browser_name'] : '';
986 $device_name = $submission_info[0]['device_name'] ? $submission_info[0]['device_name'] : '';
987 $entry_form_id = Helper::get_string_value( get_post_meta( $post_id, '_srfm_entry_form_id', true ) );
988 } else {
989 $user_ip = '';
990 $browser_name = '';
991 $device_name = '';
992 $entry_form_id = '';
993 }
994 ?>
995 <table style="border-collapse: separate; border-spacing: 5px 5px;">
996 <tr style="margin-bottom: 10px;">
997 <td><b><?php echo esc_html( __( 'Form Name:', 'sureforms' ) ); ?></b></td>
998 <td><?php echo esc_html( $form_name ); ?></td>
999 </tr>
1000 <tr style="margin-bottom: 10px;">
1001 <td><b><?php echo esc_html( __( 'Form ID:', 'sureforms' ) ); ?></b></td>
1002 <td><?php echo esc_html( $entry_form_id ); ?></td>
1003 </tr>
1004 <tr style="margin-bottom: 10px;">
1005 <td><b><?php echo esc_html( __( 'User IP:', 'sureforms' ) ); ?></b></td>
1006 <td><a target="_blank" rel="noopener" href="https://ipinfo.io/<?php echo esc_html( $user_ip ); ?>"><?php echo esc_html( $user_ip ); ?></a></td>
1007 </tr>
1008 <tr style="margin-bottom: 10px;">
1009 <td><b><?php echo esc_html( __( 'Browser:', 'sureforms' ) ); ?></b></td>
1010 <td><?php echo esc_html( $browser_name ); ?></td>
1011 </tr>
1012 <tr style="margin-bottom: 10px;">
1013 <td><b><?php echo esc_html( __( 'Device:', 'sureforms' ) ); ?></b></td>
1014 <td><?php echo esc_html( $device_name ); ?></td>
1015 </tr>
1016 </table>
1017 <?php
1018 } else {
1019 ?>
1020 <p><?php echo esc_html__( 'SureForms Form', 'sureforms' ); ?></p>
1021 <?php
1022 }
1023 }
1024
1025 /**
1026 * Custom Shortcode.
1027 *
1028 * @param array<mixed> $atts Attributes.
1029 * @return string|false. $content Post Content.
1030 * @since 0.0.1
1031 */
1032 public function forms_shortcode( array $atts ) {
1033 $atts = shortcode_atts(
1034 [
1035 'id' => '',
1036 'show_title' => true,
1037 ],
1038 $atts
1039 );
1040
1041 $id = intval( $atts['id'] );
1042 $post = get_post( $id );
1043
1044 if ( ! empty( $id ) && $post ) {
1045 $content = Generate_Form_Markup::get_form_markup( $id, ! filter_var( $atts['show_title'], FILTER_VALIDATE_BOOLEAN ), '', 'post', true );
1046 return $content;
1047 }
1048
1049 return '';
1050 }
1051
1052 /**
1053 * Add custom column header.
1054 *
1055 * @param array<mixed> $columns Attributes.
1056 * @return array<mixed> $columns Post Content.
1057 * @since 0.0.1
1058 */
1059 public function custom_form_columns( $columns ) {
1060 $columns = [
1061 'cb' => $columns['cb'],
1062 'title' => $columns['title'],
1063 'sureforms' => __( 'Shortcode', 'sureforms' ),
1064 'entries' => __( 'Entries', 'sureforms' ),
1065 'author' => $columns['author'],
1066 'date' => $columns['date'],
1067 ];
1068 return $columns;
1069 }
1070
1071 /**
1072 * Populate custom column with data.
1073 *
1074 * @param string $column Attributes.
1075 * @param integer $post_id Attributes.
1076 * @return void
1077 * @since 0.0.1
1078 */
1079 public function custom_form_column_data( $column, $post_id ) {
1080 $post_id_formatted = strval( $post_id );
1081 if ( 'sureforms' === $column ) {
1082 ob_start();
1083 ?>
1084 <div class="srfm-shortcode-container">
1085 <input id="srfm-shortcode-input-<?php echo esc_attr( strval( $post_id ) ); ?>" class="srfm-shortcode-input" type="text" readonly value="[sureforms id='<?php echo esc_attr( $post_id_formatted ); ?>']" />
1086 <button type="button" class="components-button components-clipboard-button has-icon srfm-shortcode" onclick="handleFormShortcode(this)">
1087 <span id="srfm-copy-icon" class="dashicon dashicons dashicons-admin-page"></span>
1088 </button>
1089 </div>
1090 <?php
1091 ob_end_flush();
1092 }
1093 if ( 'entries' === $column ) {
1094 $entries_url = admin_url( 'edit.php?post_status=all&post_type=' . SRFM_ENTRIES_POST_TYPE . '&sureforms_tax=' . $post_id_formatted . '&filter_action=Filter&paged=1' );
1095
1096 $taxonomy = 'sureforms_tax';
1097
1098 $args = [
1099 'post_type' => SRFM_ENTRIES_POST_TYPE,
1100 'tax_query' // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query. -- We require tax_query for this function to work.
1101 => [
1102 [
1103 'taxonomy' => $taxonomy,
1104 'field' => 'slug',
1105 'terms' => $post_id_formatted,
1106 ],
1107 ],
1108 ];
1109
1110 $key = 'sureforms_entries_count_' . $post_id_formatted;
1111 $query = wp_cache_get( $key );
1112
1113 if ( ! $query ) {
1114 $query = new WP_Query( $args );
1115 wp_cache_set( $key, $query, '', 3600 );
1116 }
1117
1118 if ( $query instanceof WP_Query ) {
1119 $post_count = $query->post_count;
1120
1121 $post_count = strval( $post_count );
1122
1123 ob_start();
1124 ?>
1125 <p class="srfm-entries-number"><a href="<?php echo esc_url( $entries_url ); ?>"><?php echo esc_html( $post_count ); ?></a></p>
1126 <?php
1127 ob_end_flush();
1128 }
1129 }
1130 }
1131
1132 /**
1133 * Add custom column header.
1134 *
1135 * @param array<mixed> $columns Attributes.
1136 * @return array<mixed> $columns Post Content.
1137 * @since 0.0.1
1138 */
1139 public function custom_entry_columns( $columns ) {
1140 $columns = [
1141 'cb' => $columns['cb'],
1142 'title' => __( 'First Field', 'sureforms' ),
1143 'form_name' => __( 'Form Name', 'sureforms' ),
1144 'entry_id' => __( 'ID', 'sureforms' ),
1145 'date' => __( 'Submitted On', 'sureforms' ),
1146 ];
1147 return $columns;
1148 }
1149
1150 /**
1151 * Populate custom column with data.
1152 *
1153 * @param string $column Attributes.
1154 * @param integer $post_id Attributes.
1155 * @return void
1156 * @since 0.0.1
1157 */
1158 public function custom_entry_column_data( $column, $post_id ) {
1159 if ( 'entry_id' === $column ) {
1160 $entry_id = strval( $post_id );
1161 echo '<p>#' . esc_html( $entry_id ) . '</p>';
1162 }
1163 if ( 'form_name' === $column ) {
1164 $taxonomy = 'sureforms_tax';
1165 $terms = wp_get_post_terms( $post_id, $taxonomy );
1166
1167 if ( is_array( $terms ) && count( $terms ) > 0 ) {
1168 $form_id = intval( $terms[0]->slug );
1169 $form_name = ! empty( get_the_title( $form_id ) ) ? get_the_title( $form_id ) : 'SureForms Form';
1170 echo '<p>' . esc_html( $form_name . ' #' . $form_id ) . '</p>';
1171 } else {
1172 ?>
1173 <p><?php echo esc_html__( 'SureForms Form', 'sureforms' ); ?></p>
1174 <?php
1175 }
1176 }
1177 }
1178
1179 /**
1180 * Add SureForms taxonomy filter.
1181 *
1182 * @return void
1183 * @since 0.0.1
1184 */
1185 public function add_tax_filter() {
1186 $screen = get_current_screen();
1187
1188 if ( ! is_null( $screen ) && 'edit-sureforms_entry' === $screen->id ) {
1189 $forms = get_posts(
1190 [
1191 'post_type' => SRFM_FORMS_POST_TYPE,
1192 'posts_per_page' => -1,
1193 'orderby' => 'title',
1194 'order' => 'ASC',
1195 ]
1196 );
1197
1198 if ( ! empty( $forms ) ) {
1199 $selected = isset( $_GET['sureforms_tax'] ) ? sanitize_key( wp_unslash( $_GET['sureforms_tax'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce Verification is not needed in this case. We are not getting the nonce value.
1200 echo '<select name="sureforms_tax" id="srfm-tax-filter">';
1201 echo '<option value="">' . esc_html__( ' All Form Entries', 'sureforms' ) . '</option>';
1202
1203 foreach ( $forms as $form ) {
1204 $selected_attr = selected( $selected, $form->ID, false );
1205 echo '<option value="' . esc_attr( strval( $form->ID ) ) . '" ' . esc_attr( $selected_attr ) . '>' . esc_html( $form->post_title ) . '</option>';
1206 }
1207
1208 echo '</select>';
1209
1210 }
1211 }
1212 }
1213
1214 /**
1215 * Show the import form popup
1216 *
1217 * @since 0.0.1
1218 * @return void
1219 */
1220 public function import_form_popup() {
1221 $screen = get_current_screen();
1222 $id = $screen ? $screen->id : '';
1223 if ( 'edit-sureforms_form' === $id ) {
1224 ?>
1225 <div class="srfm-import-plugin-wrap">
1226 <div class="srfm-import-wrap">
1227 <p class="srfm-import-help"><?php echo esc_html__( 'Please choose the SureForms export file (.json) that you wish to import.', 'sureforms' ); ?></p>
1228 <form method="post" enctype="multipart/form-data" class="srfm-import-form">
1229 <input type="file" id="srfm-import-file" onchange="handleFileChange(event)" name="import form" accept=".json">
1230 <input type="submit" name="import-form-submit" id="import-form-submit" class="srfm-import-button" value="Import Now" disabled>
1231 </form>
1232 <p id="srfm-import-error"><?php echo esc_html__( 'There is some error in json file, please export the SureForms Forms again.', 'sureforms' ); ?></p>
1233 </div>
1234 </div>
1235 <?php
1236 }
1237 }
1238
1239 /**
1240 * Redirect to home page if instant form is not enabled.
1241 *
1242 * @since 0.0.1
1243 * @return void
1244 */
1245 public function srfm_instant_form_redirect() {
1246
1247 $form_id = Helper::get_integer_value( get_the_ID() );
1248
1249 $instant_form_settings = Helper::get_array_value( Helper::get_post_meta( $form_id, '_srfm_instant_form_settings' ) );
1250 $enable_instant_form = ! empty( $instant_form_settings['enable_instant_form'] ) ? boolval( $instant_form_settings['enable_instant_form'] ) : false;
1251
1252 if ( $enable_instant_form ) {
1253 return;
1254 }
1255
1256 $form_preview = '';
1257
1258 $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.
1259
1260 if ( $form_preview_attr ) {
1261 $form_preview = filter_var( $form_preview_attr, FILTER_VALIDATE_BOOLEAN );
1262 }
1263
1264 if ( is_singular( 'sureforms_form' ) && ! $form_preview && ! current_user_can( 'manage_options' ) ) {
1265 wp_safe_redirect( home_url() );
1266 return;
1267 }
1268 }
1269
1270 /**
1271 * Restrict interference of other plugins with SureForms.
1272 *
1273 * @since 0.0.5
1274 * @return void
1275 */
1276 private function restrict_unwanted_insertions() {
1277 // Restrict RankMath metaboxes in edit page.
1278 add_action( 'cmb2_admin_init', [ $this, 'restrict_data' ] );
1279
1280 // Restrict Yoast columns.
1281 add_filter( 'wpseo_accessible_post_types', [ $this, 'unset_sureforms_post_type' ] );
1282 add_filter( 'wpseo_metabox_prio', '__return_false' );
1283
1284 // Restrict AIOSEO columns.
1285 add_filter( 'aioseo_public_post_types', [ $this, 'unset_sureforms_post_type' ] );
1286 }
1287
1288 /**
1289 * Restrict RankMath meta boxes in edit page.
1290 *
1291 * @since 0.0.5
1292 * @return void
1293 */
1294 public function restrict_data() {
1295 add_filter( 'rank_math/excluded_post_types', [ $this, 'unset_sureforms_post_type' ] );
1296 }
1297
1298 /**
1299 * Remove SureForms post type from RankMath and Yoast.
1300 *
1301 * @param array<mixed> $post_types Post types.
1302 * @since 0.0.5
1303 * @return array<mixed> $post_types Modified post types.
1304 */
1305 public function unset_sureforms_post_type( $post_types ) {
1306 $filtered_post_types = array_filter(
1307 $post_types,
1308 function( $post_type ) {
1309 if ( is_array( $post_type ) && isset( $post_type['name'] ) ) {
1310 return SRFM_FORMS_POST_TYPE !== $post_type['name'];
1311 } else {
1312 return SRFM_FORMS_POST_TYPE !== $post_type;
1313 }
1314 }
1315 );
1316
1317 return $filtered_post_types;
1318 }
1319 }
1320