form_is_rendering = true;
$atts = shortcode_atts(
array(
'id' => 0,
),
$atts,
'affcf_form'
);
$form_id = absint( $atts['id'] );
// Check if loading a draft via URL parameter.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading GET parameter to load draft for display, no action performed
$draft_id = isset( $_GET['draft_id'] ) ? absint( wp_unslash( $_GET['draft_id'] ) ) : 0;
if ( $draft_id ) {
// Load draft from database.
global $wpdb;
$drafts_table = $wpdb->prefix . 'affcf_drafts';
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name from $wpdb->prefix, plugin-controlled
$draft = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM {$drafts_table} WHERE id = %d AND user_id = %d",
$draft_id,
get_current_user_id()
)
);
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
if ( ! $draft ) {
return '
' . esc_html__( 'Draft not found or you do not have permission to edit it.', 'airy-frontend-forms' ) . '
';
}
// Use form_id from draft (override shortcode parameter).
$form_id = absint( $draft->form_id );
}
if ( ! $form_id ) {
return '' . esc_html__( 'Form ID is required.', 'airy-frontend-forms' ) . '
';
}
// Get form from database.
$form_repo = new AFFCF_Form_Repository();
$form = $form_repo->get_by_id( $form_id );
if ( ! $form ) {
return '' . esc_html__( 'Form not found.', 'airy-frontend-forms' ) . '
';
}
// Check if form is active.
if ( 'active' !== $form->status ) {
return '' . esc_html__( 'This form is currently inactive.', 'airy-frontend-forms' ) . '
';
}
// Check if ACF/SCF is available.
if ( ! AFFCF_Plugin_Checker::has_field_plugin() ) {
return '' . esc_html__( 'Required field plugin (ACF or SCF) is not active.', 'airy-frontend-forms' ) . '
';
}
// Render the form (pass draft_id if available).
$renderer = new AFFCF_Form_Renderer( $form );
return $renderer->render( $draft_id );
}
/**
* Render dashboard shortcode.
*
* @param array $atts Shortcode attributes (unused but required by shortcode API).
* @return string Rendered dashboard HTML.
*/
public function render_dashboard_shortcode( $atts ) {
// Set flag that dashboard is rendering (for page builder compatibility).
$this->dashboard_is_rendering = true;
// Suppress unused parameter warning - required by WordPress shortcode API.
unset( $atts );
if ( ! is_user_logged_in() ) {
return '' . esc_html__( 'Please log in to view your dashboard.', 'airy-frontend-forms' ) . '
';
}
// Render user dashboard.
$dashboard = new AFFCF_User_Dashboard();
return $dashboard->render();
}
/**
* Render edit form shortcode.
*
* @param array $atts Shortcode attributes (unused but required by shortcode API).
* @return string Rendered edit form HTML.
*/
public function render_edit_form_shortcode( $atts ) {
// Set flag that edit form is rendering (for page builder compatibility).
$this->edit_form_is_rendering = true;
// Suppress unused parameter warning - required by WordPress shortcode API.
unset( $atts );
if ( ! is_user_logged_in() ) {
return '' . esc_html__( 'Please log in to edit posts.', 'airy-frontend-forms' ) . '
';
}
// Get post ID from URL parameter.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading GET parameter to load post for editing, nonce verified during form submission
$post_id = isset( $_GET['post_id'] ) ? absint( wp_unslash( $_GET['post_id'] ) ) : 0;
if ( ! $post_id ) {
return '' . esc_html__( 'No post specified for editing.', 'airy-frontend-forms' ) . '
';
}
// Get the post.
$post = get_post( $post_id );
if ( ! $post ) {
return '' . esc_html__( 'Post not found.', 'airy-frontend-forms' ) . '
';
}
// Verify ownership.
if ( get_current_user_id() !== (int) $post->post_author ) {
return '' . esc_html__( 'You do not have permission to edit this post.', 'airy-frontend-forms' ) . '
';
}
// Get the form ID that was used to create this post.
$form_id = get_post_meta( $post_id, '_affcf_form_id', true );
if ( ! $form_id ) {
return '' . esc_html__( 'This post was not created with Airy Frontend Forms.', 'airy-frontend-forms' ) . '
';
}
// Get the form.
$form_repo = new AFFCF_Form_Repository();
$form = $form_repo->get_by_id( $form_id );
if ( ! $form ) {
return '' . esc_html__( 'Form not found.', 'airy-frontend-forms' ) . '
';
}
// Check if form's post type matches the post.
if ( $form->post_type !== $post->post_type ) {
return '' . esc_html__( 'Form post type mismatch.', 'airy-frontend-forms' ) . '
';
}
// Check if ACF or SCF is active.
$field_manager = AFFCF_Field_Manager::get_instance();
if ( ! $field_manager->is_available() ) {
return '' . esc_html__( 'Required field plugin (ACF or SCF) is not active.', 'airy-frontend-forms' ) . '
';
}
// Render the form in EDIT MODE.
$renderer = new AFFCF_Form_Renderer( $form, $post_id );
return $renderer->render();
}
/**
* Enqueue frontend assets.
*
* @return void
*/
public function enqueue_assets() {
global $post;
// Check if any of our shortcodes are present.
$has_form = is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'affcf_form' );
$has_dashboard = is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'affcf_dashboard' );
$has_edit_form = is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'affcf_edit_form' );
if ( ! $has_form && ! $has_dashboard && ! $has_edit_form ) {
return;
}
// Enqueue form styles and scripts if form shortcode present.
if ( $has_form || $has_edit_form ) {
// Load WordPress Media Library for image/gallery fields.
wp_enqueue_media();
// CSS.
wp_enqueue_style( 'dashicons' );
wp_enqueue_style(
'affcf-frontend',
AFFCF_PLUGIN_URL . 'assets/css/frontend/form-styles.css',
array( 'dashicons' ),
AFFCF_VERSION
);
// JavaScript.
wp_enqueue_script(
'affcf-form-handler',
AFFCF_PLUGIN_URL . 'assets/js/frontend/form-handler.js',
array( 'jquery' ),
AFFCF_VERSION,
true
);
}
// ALWAYS load auto-save script if ANY shortcode is present (form, dashboard, or edit).
if ( $has_form || $has_edit_form || $has_dashboard ) {
wp_enqueue_script(
'affcf-auto-save',
AFFCF_PLUGIN_URL . 'assets/js/frontend/auto-save.js',
array( 'jquery' ),
AFFCF_VERSION,
true
);
}
// Load reCAPTCHA if needed.
if ( ( $has_form || $has_edit_form ) && AFFCF_Captcha::is_enabled() ) {
$site_key = AFFCF_Captcha::get_site_key();
wp_enqueue_script(
'google-recaptcha',
'https://www.google.com/recaptcha/api.js?render=' . $site_key,
array(),
null, // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- External Google reCAPTCHA script, version controlled by Google
true
);
}
// Enqueue dashboard styles and scripts if dashboard shortcode present.
if ( $has_dashboard ) {
wp_enqueue_style(
'affcf-dashboard',
AFFCF_PLUGIN_URL . 'assets/css/frontend/user-dashboard.css',
array(),
AFFCF_VERSION
);
wp_enqueue_script(
'affcf-dashboard',
AFFCF_PLUGIN_URL . 'assets/js/frontend/user-dashboard.js',
array( 'jquery' ),
AFFCF_VERSION,
true
);
}
// Get settings.
$settings = get_option( 'affcf_settings', array() );
// Localize script.
$localize_data = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'affcf_frontend_nonce' ),
'autoSaveEnabled' => true, // Force true for debugging.
'autoSaveInterval' => 10,
'strings' => array(
// Form submission strings.
'submitting' => __( 'Submitting...', 'airy-frontend-forms' ),
'success' => __( 'Form submitted successfully!', 'airy-frontend-forms' ),
'error' => __( 'An error occurred. Please try again.', 'airy-frontend-forms' ),
// Auto-save strings.
'saving' => __( 'Saving draft...', 'airy-frontend-forms' ),
'saved' => __( 'Draft saved', 'airy-frontend-forms' ),
'saveError' => __( 'Failed to save draft', 'airy-frontend-forms' ),
'autosave' => __( 'Auto-save', 'airy-frontend-forms' ),
'unsavedChanges' => __( 'You have unsaved changes. Are you sure you want to leave?', 'airy-frontend-forms' ),
'draftLoaded' => __( 'Draft loaded. Continue editing or submit when ready.', 'airy-frontend-forms' ),
// Dashboard strings.
'confirmDeleteDraft' => __( 'Are you sure you want to delete this draft?', 'airy-frontend-forms' ),
'deleting' => __( 'Deleting...', 'airy-frontend-forms' ),
'delete' => __( 'Delete', 'airy-frontend-forms' ),
),
);
// Suppress unused variable warning - $settings used for future expansion.
unset( $settings );
// Add reCAPTCHA config if enabled.
if ( AFFCF_Captcha::is_enabled() ) {
$localize_data['recaptcha'] = array(
'enabled' => true,
'siteKey' => AFFCF_Captcha::get_site_key(),
'action' => 'affcf_submit',
);
}
// ALWAYS localize auto-save if it's enqueued.
if ( wp_script_is( 'affcf-auto-save', 'enqueued' ) ) {
wp_localize_script( 'affcf-auto-save', 'affcfData', $localize_data );
}
// Localize for the appropriate script.
if ( $has_form || $has_edit_form ) {
wp_localize_script( 'affcf-form-handler', 'affcfData', $localize_data );
} elseif ( $has_dashboard ) {
wp_localize_script( 'affcf-dashboard', 'affcfData', $localize_data );
}
}
/**
* Process form submission.
*
* @return void
*/
public function process_form_submission() {
// phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verified in AFFCF_Form_Submission::handle_submission()
// Check if form is being submitted.
if ( ! isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
return;
}
// Check if this is a form submission.
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified below in AFFCF_Form_Submission::handle_submission()
if ( ! isset( $_POST['affcf_action'] ) || 'submit_form' !== sanitize_text_field( wp_unslash( $_POST['affcf_action'] ) ) ) {
return;
}
// Get form ID.
$form_id = isset( $_POST['affcf_form_id'] ) ? absint( wp_unslash( $_POST['affcf_form_id'] ) ) : 0;
if ( ! $form_id ) {
return;
}
// Handle the submission.
$submission = new AFFCF_Form_Submission();
$result = $submission->handle_submission();
// Handle result.
if ( is_wp_error( $result ) ) {
// Store error in transient for display.
$error_message = $result->get_error_message();
set_transient( 'affcf_submission_error_' . get_current_user_id(), $error_message, 300 );
// Redirect back to form.
wp_safe_redirect( wp_get_referer() );
exit;
}
// Success - store success message.
$post_id = $result['post_id'];
$success_message = $result['message'];
set_transient( 'affcf_submission_success_' . get_current_user_id(), $success_message, 300 );
set_transient( 'affcf_submission_post_id_' . get_current_user_id(), $post_id, 300 );
// Redirect to success page or back to form.
$pages = get_option( 'affcf_default_pages', array() );
$dashboard_page_id = ! empty( $pages['custom_dashboard_page_id'] )
? $pages['custom_dashboard_page_id']
: $pages['dashboard_page_id'];
if ( $dashboard_page_id ) {
$redirect_url = get_permalink( $dashboard_page_id );
} else {
$redirect_url = add_query_arg( 'submission', 'success', wp_get_referer() );
}
wp_safe_redirect( $redirect_url );
exit;
// phpcs:enable
}
/**
* Handle AJAX form submission.
*
* @return void
*/
public function ajax_submit_form() {
// phpcs:disable WordPress.Security.NonceVerification.Missing, WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler -- Nonce verified in AFFCF_Form_Submission::handle_submission(), error handler needed for AJAX stability
// Emergency error handler - catches errors even during class loading.
set_error_handler(
function ( $errno, $errstr, $errfile, $errline ) {
// Suppress unused parameters - required by set_error_handler signature.
unset( $errno, $errstr, $errfile, $errline );
}
);
// Wrap ENTIRE method to ensure we ALWAYS return JSON.
try {
// Verify nonce exists.
if ( ! isset( $_POST['affcf_nonce'] ) ) {
wp_send_json_error(
array(
'message' => __( 'Security check failed - nonce missing.', 'airy-frontend-forms' ),
'debug_step' => 'nonce_missing',
)
);
return;
}
// Verify form_id exists.
if ( ! isset( $_POST['affcf_form_id'] ) ) {
wp_send_json_error(
array(
'message' => __( 'Form ID is missing.', 'airy-frontend-forms' ),
'debug_step' => 'form_id_missing',
)
);
return;
}
// Check if class exists.
if ( ! class_exists( 'AFFCF_Form_Submission' ) ) {
wp_send_json_error(
array(
'message' => __( 'Form submission class not loaded. Please check plugin installation.', 'airy-frontend-forms' ),
'debug_step' => 'class_missing',
)
);
return;
}
// Handle the submission.
$submission = new AFFCF_Form_Submission();
$result = $submission->handle_submission();
// Handle result.
if ( is_wp_error( $result ) ) {
$error_message = $result->get_error_message();
$error_code = $result->get_error_code();
// Build error response.
$response = array(
'message' => $error_message,
);
wp_send_json_error( $response );
return;
}
// Success!
wp_send_json_success(
array(
'message' => $result['message'],
'post_id' => $result['post_id'],
'redirect_url' => $this->get_redirect_url(),
)
);
} catch ( Throwable $e ) {
// This catches EVERYTHING in PHP 8+: Error, Exception, TypeError, etc.
// Always return proper JSON error response.
$response = array(
'message' => __( 'An error occurred while processing your submission. Please try again.', 'airy-frontend-forms' ),
);
wp_send_json_error( $response );
} finally {
restore_error_handler();
}
}
/**
* Get redirect URL after successful submission.
*
* @return string Redirect URL.
*/
private function get_redirect_url() {
$pages = get_option( 'affcf_default_pages', array() );
$dashboard_page_id = ! empty( $pages['custom_dashboard_page_id'] )
? $pages['custom_dashboard_page_id']
: ( $pages['dashboard_page_id'] ?? 0 );
if ( $dashboard_page_id ) {
return get_permalink( $dashboard_page_id );
}
return home_url();
// phpcs:enable
}
/**
* Handle delete post action from dashboard.
*
* @return void
*/
public function handle_delete_post() {
// Check if user is logged in.
if ( ! is_user_logged_in() ) {
wp_die( esc_html__( 'You must be logged in to delete posts.', 'airy-frontend-forms' ) );
}
// Get and validate post ID first (needed for nonce verification).
$post_id = isset( $_GET['post_id'] ) ? absint( wp_unslash( $_GET['post_id'] ) ) : 0;
if ( ! $post_id ) {
wp_die( esc_html__( 'No post specified.', 'airy-frontend-forms' ) );
}
// Verify nonce immediately after getting the post_id it depends on.
if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'affcf_delete_post_' . $post_id ) ) {
wp_die( esc_html__( 'Security check failed.', 'airy-frontend-forms' ) );
}
// Verify user capability.
if ( ! current_user_can( 'delete_post', $post_id ) ) {
wp_die( esc_html__( 'You do not have permission to delete this post.', 'airy-frontend-forms' ) );
}
// Get post.
$post = get_post( $post_id );
if ( ! $post ) {
wp_die( esc_html__( 'Post not found.', 'airy-frontend-forms' ) );
}
// Verify ownership.
if ( get_current_user_id() !== (int) $post->post_author ) {
wp_die( esc_html__( 'You do not have permission to delete this post.', 'airy-frontend-forms' ) );
}
// Only allow deleting pending/draft posts (not published ones).
if ( ! in_array( $post->post_status, array( 'pending', 'draft' ), true ) ) {
wp_die( esc_html__( 'You can only delete pending or draft posts.', 'airy-frontend-forms' ) );
}
// Delete the post (true = force delete, bypass trash).
$result = wp_delete_post( $post_id, true );
if ( ! $result ) {
wp_die( esc_html__( 'Failed to delete post.', 'airy-frontend-forms' ) );
}
// Redirect back to dashboard with success message.
$redirect_url = add_query_arg( 'deleted', '1', $this->get_redirect_url() );
wp_safe_redirect( $redirect_url );
exit;
}
/**
* Handle AJAX image upload to media library.
*
* @return void
*/
public function ajax_upload_image() {
// Verify nonce.
check_ajax_referer( 'affcf_frontend_nonce', 'nonce' );
// Verify user is logged in and has upload capability.
if ( ! is_user_logged_in() || ! current_user_can( 'upload_files' ) ) {
wp_send_json_error(
array(
'message' => __( 'You do not have permission to upload files.', 'airy-frontend-forms' ),
)
);
return;
}
// Check if file was uploaded.
if ( empty( $_FILES['file'] ) ) {
wp_send_json_error(
array(
'message' => __( 'No file uploaded.', 'airy-frontend-forms' ),
)
);
return;
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- File upload, sanitized via wp_handle_upload
$file = isset( $_FILES['file'] ) ? $_FILES['file'] : array();
// Check for upload errors.
if ( UPLOAD_ERR_OK !== $file['error'] ) {
wp_send_json_error(
array(
'message' => __( 'File upload error.', 'airy-frontend-forms' ),
)
);
return;
}
// Validate file type using server-side check (don't trust client-provided MIME type).
$file_ext = strtolower( pathinfo( sanitize_file_name( $file['name'] ), PATHINFO_EXTENSION ) );
$allowed_extensions = array( 'jpg', 'jpeg', 'png', 'gif', 'webp' );
if ( ! in_array( $file_ext, $allowed_extensions, true ) ) {
wp_send_json_error(
array(
'message' => __( 'Invalid file type. Only images allowed.', 'airy-frontend-forms' ),
)
);
return;
}
// Double-check with WordPress MIME type verification.
$file_check = wp_check_filetype( sanitize_file_name( $file['name'] ) );
if ( ! $file_check['type'] || strpos( $file_check['type'], 'image/' ) !== 0 ) {
wp_send_json_error(
array(
'message' => __( 'Invalid file type. Only images allowed.', 'airy-frontend-forms' ),
)
);
return;
}
// Validate file size (2MB max).
$max_size = 2 * 1024 * 1024;
if ( $file['size'] > $max_size ) {
wp_send_json_error(
array(
'message' => __( 'File size exceeds 2MB limit.', 'airy-frontend-forms' ),
)
);
return;
}
// Include WordPress file handling functions.
require_once ABSPATH . 'wp-admin/includes/image.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
// Upload file to media library using media_handle_upload with custom settings.
$attachment_id = media_handle_upload(
'file',
0,
array(),
array(
'test_form' => false,
'action' => 'affcf_upload_image',
)
);
if ( is_wp_error( $attachment_id ) ) {
wp_send_json_error(
array(
'message' => $attachment_id->get_error_message(),
)
);
}
// Get attachment URL.
$image_url = wp_get_attachment_image_url( $attachment_id, 'medium' );
if ( ! $image_url ) {
$image_url = wp_get_attachment_url( $attachment_id );
}
// Return success with attachment ID and URL.
wp_send_json_success(
array(
'attachment_id' => $attachment_id,
'url' => $image_url,
'message' => __( 'Image uploaded successfully.', 'airy-frontend-forms' ),
)
);
}
/**
* Enqueue assets in footer if shortcode rendered but wasn't detected in post_content.
* This handles page builders like Breakdance, Elementor, etc.
*
* @return void
*/
public function enqueue_assets_footer() {
// If no shortcode rendered, do nothing.
if ( ! $this->form_is_rendering && ! $this->dashboard_is_rendering && ! $this->edit_form_is_rendering ) {
return;
}
// If form shortcode rendered, ensure scripts are enqueued.
if ( $this->form_is_rendering || $this->edit_form_is_rendering ) {
// Check if form handler already enqueued.
if ( ! wp_script_is( 'affcf-form-handler', 'enqueued' ) ) {
wp_enqueue_style(
'affcf-frontend',
AFFCF_PLUGIN_URL . 'assets/css/frontend/form-styles.css',
array(),
AFFCF_VERSION
);
wp_enqueue_script(
'affcf-form-handler',
AFFCF_PLUGIN_URL . 'assets/js/frontend/form-handler.js',
array( 'jquery' ),
AFFCF_VERSION,
true
);
}
// ALWAYS enqueue auto-save if not already enqueued.
if ( ! wp_script_is( 'affcf-auto-save', 'enqueued' ) ) {
$auto_save_url = AFFCF_PLUGIN_URL . 'assets/js/frontend/auto-save.js';
$auto_save_version = AFFCF_VERSION . '-footer-' . time();
wp_enqueue_script(
'affcf-auto-save',
$auto_save_url,
array( 'jquery' ),
$auto_save_version,
true
);
// Localize script.
$localize_data = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'affcf_frontend_nonce' ),
'autoSaveEnabled' => true,
'autoSaveInterval' => 10,
'strings' => array(
'submitting' => __( 'Submitting...', 'airy-frontend-forms' ),
'success' => __( 'Form submitted successfully!', 'airy-frontend-forms' ),
'error' => __( 'An error occurred. Please try again.', 'airy-frontend-forms' ),
'saving' => __( 'Saving draft...', 'airy-frontend-forms' ),
'saved' => __( 'Draft saved', 'airy-frontend-forms' ),
'saveError' => __( 'Failed to save draft', 'airy-frontend-forms' ),
'autosave' => __( 'Auto-save', 'airy-frontend-forms' ),
'unsavedChanges' => __( 'You have unsaved changes. Are you sure you want to leave?', 'airy-frontend-forms' ),
'draftLoaded' => __( 'Draft loaded. Continue editing or submit when ready.', 'airy-frontend-forms' ),
),
);
wp_localize_script( 'affcf-auto-save', 'affcfData', $localize_data );
wp_localize_script( 'affcf-form-handler', 'affcfData', $localize_data );
}
}
// If dashboard shortcode rendered, ensure dashboard scripts are enqueued.
if ( $this->dashboard_is_rendering ) {
if ( ! wp_script_is( 'affcf-dashboard', 'enqueued' ) ) {
wp_enqueue_style(
'affcf-dashboard',
AFFCF_PLUGIN_URL . 'assets/css/frontend/user-dashboard.css',
array(),
AFFCF_VERSION
);
wp_enqueue_script(
'affcf-dashboard',
AFFCF_PLUGIN_URL . 'assets/js/frontend/user-dashboard.js',
array( 'jquery' ),
AFFCF_VERSION,
true
);
$localize_data = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'affcf_frontend_nonce' ),
'autoSaveEnabled' => true,
'autoSaveInterval' => 10,
'strings' => array(
'confirmDeleteDraft' => __( 'Are you sure you want to delete this draft?', 'airy-frontend-forms' ),
'deleting' => __( 'Deleting...', 'airy-frontend-forms' ),
'delete' => __( 'Delete', 'airy-frontend-forms' ),
),
);
wp_localize_script( 'affcf-dashboard', 'affcfData', $localize_data );
}
// Also enqueue auto-save for dashboard.
if ( ! wp_script_is( 'affcf-auto-save', 'enqueued' ) ) {
wp_enqueue_script(
'affcf-auto-save',
AFFCF_PLUGIN_URL . 'assets/js/frontend/auto-save.js',
array( 'jquery' ),
AFFCF_VERSION . '-footer-' . time(),
true
);
}
}
}
}