<?php

if ( ! defined( 'ABSPATH' ) ) {
	die( 'You are not allowed to call this page directly.' );
}

class FrmProForm {

	/**
	 * Modifies form options when updating or creating.
	 *
	 * @since 5.4 Added the third param.
	 *
	 * @param array $options Form options.
	 * @param array $values  Form data.
	 * @param bool  $update  Is form updating or creating. It's `true` if is updating.
	 *
	 * @return array
	 */
	public static function update_options( $options, $values, $update = false ) {
		self::fill_option_defaults( $options, $values );

		if ( isset( $values['id'] ) ) {
			self::setup_file_protection(
				array(
					'new'     => $options['protect_files'],
					'form_id' => $values['id'],
				)
			);
		}

		if ( isset( $options['draft_label'] ) ) {
			$options['draft_label'] = sanitize_text_field( $options['draft_label'] );
		}

		if ( isset( $options['edit_value'] ) ) {
			$options['edit_value'] = sanitize_text_field( $options['edit_value'] );
		}

		$options = FrmAppHelper::maybe_filter_array( $options, array( 'edit_msg', 'draft_msg' ) );

		$options['single_entry'] = $values['options']['single_entry'] ?? 0;

		if ( $options['single_entry'] ) {
			$options['single_entry_type'] = $values['options']['single_entry_type'] ?? array();
		}

		if ( is_multisite() ) {
			$options['copy'] = $values['options']['copy'] ?? 0;
		}

		// In the latest Lite version, start over isn't saved in form options anymore.
		if ( $update && ! FrmProSubmitHelper::is_available() ) {
			self::maybe_add_start_over_shortcode( $options );
		}

		return $options;
	}

	/**
	 * Maybe add start over button shortcode to the Submit button setting if it's missing.
	 *
	 * @since 5.4
	 *
	 * @param array $options Form options.
	 */
	private static function maybe_add_start_over_shortcode( &$options ) {
		// If using an old Lite version, we need to check the start_over value in the form options.
		if ( ! FrmProSubmitHelper::is_available() && empty( $options['start_over'] ) ) {
			return;
		}

		if ( str_contains( $options['submit_html'], '[if start_over]' ) ) {
			return;
		}

		$start_over_shortcode   = FrmFormsHelper::get_start_over_shortcode();
		$options['submit_html'] = preg_replace( '~\<\/div\>(?!.*\<\/div\>)~', $start_over_shortcode . "\r\n</div>", $options['submit_html'] );
	}

	/**
	 * @since 2.02
	 *
	 * @param array $options
	 * @param array $values
	 *
	 * @return void
	 */
	private static function fill_option_defaults( &$options, $values ) {
		$defaults = FrmProFormsHelper::get_default_opts();
		unset( $defaults['logged_in'], $defaults['editable'] );

		foreach ( $defaults as $opt => $default ) {
			$options[ $opt ] = $values['options'][ $opt ] ?? $default;

			unset( $opt, $default );
		}
	}

	/**
	 * Turn on and off file protection for this form folder
	 *
	 * @since 2.02
	 *
	 * @param array $atts
	 */
	private static function setup_file_protection( $atts ) {
		if ( ! self::file_protection_setting_was_updated( $atts ) ) {
			return;
		}

		$form_id          = absint( $atts['form_id'] );
		$file_ids         = self::get_all_file_ids_for_form( $form_id );
		$file_folders     = self::get_all_file_folders_for_form( $file_ids );
		$htaccess_folders = self::get_file_folders_for_form_that_should_have_htaccess( $file_ids );
		$upload_dir       = trailingslashit( wp_upload_dir()['basedir'] );

		foreach ( $file_folders as $folder ) {
			if ( in_array( $folder, $htaccess_folders, true ) ) {
				$folder_name = str_replace( $upload_dir, '', $folder );
				self::maybe_update_htaccess_file( $folder_name, $atts['new'] );
			}

			$args = array(
				'form_id'   => $form_id,
				'file_ids'  => $file_ids,
				'dir'       => $folder,
				'protected' => $atts['new'],
			);
			FrmProFileField::maybe_set_chmod( $args );
		}
	}

	/**
	 * @param array $atts
	 *
	 * @return bool
	 */
	private static function file_protection_setting_was_updated( $atts ) {
		$previous_val = FrmProFileField::get_option( $atts['form_id'], 'protect_files', 0 );
		return $previous_val != $atts['new'];
	}

	/**
	 * @param array $file_ids
	 */
	private static function get_file_folders_for_form_that_should_have_htaccess( $file_ids ) {
		return array_filter( self::get_all_file_folders_for_form( $file_ids ), self::class . '::file_folder_should_have_htaccess' );
	}

	/**
	 * @param string $file_folder
	 *
	 * @return bool
	 */
	private static function file_folder_should_have_htaccess( $file_folder ) {
		$formidable_uploads_dir = FrmProFileField::default_formidable_uploads_dir();
		$dir_length             = strlen( $formidable_uploads_dir );

		if ( strlen( $file_folder ) < $dir_length ) {
			return false;
		}

		return $formidable_uploads_dir === substr( $file_folder, 0, $dir_length );
	}

	/**
	 * @param array<int> $file_ids
	 *
	 * @return array<string>
	 */
	private static function get_all_file_folders_for_form( $file_ids ) {
		$file_folders = array();

		foreach ( $file_ids as $file_id ) {
			$path                 = get_attached_file( $file_id );
			$dir                  = dirname( $path );
			$file_folders[ $dir ] = $dir;
		}

		return array_values( $file_folders );
	}

	/**
	 * @param int $form_id
	 *
	 * @return array
	 */
	private static function get_all_file_ids_for_form( $form_id ) {
		$child_form_ids = self::get_child_form_ids( $form_id );
		$all_form_ids   = array_merge( array( $form_id ), $child_form_ids );
		$file_field_ids = FrmDb::get_col(
			'frm_fields',
			array(
				'form_id' => $all_form_ids,
				'type'    => 'file',
			)
		);

		if ( ! $file_field_ids ) {
			return array();
		}

		$file_data = FrmDb::get_col( 'frm_item_metas', array( 'field_id' => $file_field_ids ), 'meta_value' );
		$file_ids  = array();

		foreach ( $file_data as $meta_value ) {
			FrmAppHelper::unserialize_or_decode( $meta_value );
			$file_ids = array_merge( $file_ids, (array) $meta_value );
		}

		return $file_ids;
	}

	/**
	 * @param string $folder_name
	 * @param bool $deny
	 */
	private static function maybe_update_htaccess_file( $folder_name, $deny ) {
		if ( ! FrmProFileField::server_supports_htaccess() ) {
			return;
		}

		self::create_folder_if_it_does_not_already_exist( $folder_name );

		$content     = $deny ? "Deny from all\r\n" : "\r\n";
		$create_file = new FrmCreateFile(
			array(
				'folder_name'   => $folder_name,
				'file_name'     => '.htaccess',
				'error_message' => sprintf( __( 'Unable to write to %s to protect your uploads.', 'formidable-pro' ), $folder_name . '/.htaccess' ),
			)
		);
		$create_file->create_file( $content );
	}

	/**
	 * @param string $folder_name
	 *
	 * @return void
	 */
	private static function create_folder_if_it_does_not_already_exist( $folder_name ) {
		new FrmCreateFile(
			array(
				'folder_name' => $folder_name,
				'file_name'   => '',
			)
		);
	}

	/**
	 * Generate the content for an htaccess file to block any direct file access to a protected form's folder
	 * This is only called on Apache servers as an extra layer of security to prevent file access
	 * Without this file, the chmod code will set prevent access to the files
	 *
	 * @since 2.02
	 *
	 * @param string $content
	 */
	public static function get_htaccess_content( &$content ) {
		$url = home_url();
		$url = str_replace( array( 'http://', 'https://' ), '', $url );

		$content .= 'RewriteEngine on' . "\r\n";
		$content .= 'RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?' . $url . '/.*$ [NC]' . "\r\n";
		$content .= 'RewriteRule \.*$ - [F]' . "\r\n";
	}

	/**
	 * @param array $settings
	 * @param array $action
	 *
	 * @return array
	 */
	public static function save_wppost_actions( $settings, $action ) {
		$form_id = $action['menu_order'];

		if ( isset( $settings['post_custom_fields'] ) ) {
			foreach ( $settings['post_custom_fields'] as $cf_key => $n ) {
				if ( ! isset( $n['custom_meta_name'] ) ) {
					continue;
				}

				if ( $n['meta_name'] == '' && $n['custom_meta_name'] != '' ) {
					$settings['post_custom_fields'][ $cf_key ]['meta_name'] = $n['custom_meta_name'];
				}

				unset( $settings['post_custom_fields'][ $cf_key ]['custom_meta_name'] );

				unset( $cf_key, $n );
			}
		}

		self::create_post_category_field( $settings, $form_id );
		self::create_post_status_field( $settings, $form_id );
		return $settings;
	}

	/**
	 * @param array      $settings
	 * @param int|string $form_id
	 *
	 * @return void
	 */
	private static function create_post_category_field( array &$settings, $form_id ) {
		if ( empty( $settings['post_category'] ) ) {
			return;
		}

		foreach ( $settings['post_category'] as $k => $field_name ) {
			if ( $field_name['field_id'] !== 'checkbox' ) {
				continue;
			}

			// Create a new field
			$new_values                                 = apply_filters( 'frm_before_field_created', FrmFieldsHelper::setup_new_vars( 'checkbox', $form_id ) );
			$new_values['field_options']['taxonomy']    = $field_name['meta_name'] ?? 'category';
			$new_values['name']                         = ucwords( str_replace( '_', ' ', $new_values['field_options']['taxonomy'] ) );
			$new_values['field_options']['post_field']  = 'post_category';
			$new_values['field_options']['exclude_cat'] = $field_name['exclude_cat'] ?? 0;

			$settings['post_category'][ $k ]['field_id'] = FrmField::create( $new_values );

			unset( $new_values, $k, $field_name );
		}
	}

	/**
	 * @param array $settings
	 */
	private static function create_post_status_field( array &$settings, $form_id ) {
		if ( ! isset( $settings['post_status'] ) || 'dropdown' !== $settings['post_status'] ) {
			return;
		}

		// Create a new field
		$new_values                                    = apply_filters( 'frm_before_field_created', FrmFieldsHelper::setup_new_vars( 'select', $form_id ) );
		$new_values['name']                            = __( 'Status', 'formidable' );
		$new_values['field_options']['post_field']     = 'post_status';
		$new_values['field_options']['separate_value'] = 1;
		$new_values['options']                         = FrmProFieldsHelper::get_initial_post_status_options();
		$settings['post_status']                       = FrmField::create( $new_values );
	}

	/**
	 * @param array $field_options
	 */
	public static function update_form_field_options( $field_options, $field ) {
		$field_options['post_field']   = '';
		$field_options['custom_field'] = '';
		$field_options['taxonomy']     = 'category';
		$field_options['exclude_cat']  = 0;

		$action_name = apply_filters( 'frm_save_post_name', 'wppost', $field );
		$post_action = FrmFormAction::get_action_for_form( $field->form_id, $action_name, 1 );

		if ( ! $post_action ) {
			return $field_options;
		}

		$post_fields = array(
			'post_content',
			'post_excerpt',
			'post_title',
			'post_name',
			'post_date',
			'post_status',
			'post_password',
		);

		$this_post_field = array_search( $field->id, $post_action->post_content );

		if ( in_array( $this_post_field, $post_fields ) ) {
			$field_options['post_field'] = $this_post_field;
		}

		if ( $this_post_field === 'post_status' ) {
			$field_options['separate_value'] = 1;
		}
		unset( $this_post_field );

		// Set post categories
		foreach ( (array) $post_action->post_content['post_category'] as $field_name ) {
			if ( ! isset( $field_name['field_id'] ) || $field_name['field_id'] != $field->id ) {
				continue;
			}

			$field_options['post_field']  = 'post_category';
			$field_options['taxonomy']    = $field_name['meta_name'] ?? 'category';
			$field_options['exclude_cat'] = $field_name['exclude_cat'] ?? 0;
		}

		// Set post custom fields
		foreach ( (array) $post_action->post_content['post_custom_fields'] as $field_name ) {
			if ( ! isset( $field_name['field_id'] ) || $field_name['field_id'] != $field->id ) {
				continue;
			}

			$field_options['post_field']   = 'post_custom';
			$field_options['custom_field'] = $field_name['meta_name'] == '' && isset( $field_name['custom_meta_name'] ) && $field_name['custom_meta_name'] != '' ? $field_name['custom_meta_name'] : $field_name['meta_name'];
		}

		return $field_options;
	}

	/**
	 * @param int|string $id
	 * @param array      $values
	 *
	 * @return void
	 */
	public static function update( $id, $values ) {
		global $wpdb;

		$action         = FrmAppHelper::get_param( 'frm_action', '', 'post', 'sanitize_text_field' );
		$saving_builder = FrmAppHelper::is_admin_page() || FrmAppHelper::doing_ajax() && ! empty( $values['frm_save_form'] );

		if ( 'update' === $action && $saving_builder ) {
			$updated = self::update_builder_page( $id );
		} elseif ( isset( $values['options'] ) && 'update_settings' === $action ) {
			$logged_in = $values['logged_in'] ?? 0;
			$editable  = $values['editable'] ?? 0;
			$updated   = $wpdb->update(
				$wpdb->prefix . 'frm_forms',
				array(
					'logged_in' => $logged_in,
					'editable'  => $editable,
				),
				array( 'id' => $id )
			);
		}

		if ( empty( $updated ) ) {
			return;
		}

		FrmForm::clear_form_cache();
		unset( $updated );
	}

	/**
	 * Updates form on the builder page.
	 *
	 * @since 6.9
	 *
	 * @param  int $id Form ID.
	 *
	 * @return bool    Return `true` if updated.
	 */
	private static function update_builder_page( $id ) {
		$options = self::get_form_options_from_builder_data();

		if ( ! $options ) {
			return false;
		}

		global $wpdb;
		$form = FrmForm::getOne( $id );

		if ( ! empty( $options['should_add_start_over_shortcode'] ) ) {
			self::maybe_add_start_over_shortcode( $form->options );
			unset( $options['should_add_start_over_shortcode'] );
		}

		$options += $form->options;

		// Use custom query instead of FrmForm::update() to prevent duplicate code runs.
		return $wpdb->update(
			$wpdb->prefix . 'frm_forms',
			array( 'options' => serialize( $options ) ),
			array( 'id' => $id )
		);
	}

	/**
	 * Modifies form values before saving.
	 *
	 * @since 6.9
	 *
	 * @return array|false Return new form options, or `false` if shouldn't update.
	 */
	public static function get_form_options_from_builder_data() {
		// Only do if there are changed fields.
		$fields_submitted = FrmAppHelper::get_post_param( 'frm_fields_submitted', array() );

		if ( ! $fields_submitted || ! is_array( $fields_submitted ) ) {
			return false;
		}

		$options        = array();
		$posted_options = FrmAppHelper::get_post_param( 'field_options', array() );

		// Save page transition.
		if ( is_array( $posted_options ) ) {
			foreach ( $posted_options as $key => $value ) {
				if ( self::is_posted_field_option( 'transition', $key, $fields_submitted ) ) {
					$options['transition'] = $value;
					continue;
				}

				if ( self::is_posted_field_option( 'start_over', $key, $fields_submitted ) && $value && ! FrmAppHelper::get_post_param( 'old_start_over_value' ) ) {
					$options['should_add_start_over_shortcode'] = true;
				}
			}
		}

		FrmProRootlineController::save_rootline_to_form_options( $options );

		return $options;
	}

	/**
	 * Checks if the posted data is a field option.
	 *
	 * @since 6.11.2
	 *
	 * @param string $option_key Key of the option you want to check.
	 * @param string $posted_key Key of the posted data.
	 * @param array  $fields_submitted IDs of submitted fields.
	 *
	 * @return bool
	 */
	private static function is_posted_field_option( $option_key, $posted_key, $fields_submitted ) {
		preg_match_all( '/' . $option_key . '_(\d+)/i', $posted_key, $matches, PREG_SET_ORDER );
		return $matches && in_array( $matches[0][1], $fields_submitted, true );
	}

	/**
	 * @param array $new_opts
	 * @param int   $form_id
	 *
	 * @return array
	 */
	public static function after_duplicate( $new_opts, $form_id = 0 ) {
		self::maybe_switch_submit_condition_field_ids( $new_opts );

		if ( isset( $new_opts['success_url'] ) ) {
			$new_opts['success_url'] = FrmFieldsHelper::switch_field_ids( $new_opts['success_url'] );
		}

		if ( isset( $new_opts['rootline_titles'] ) ) {
			$new_opts['rootline_titles'] = self::switch_rootline_field_id_keys( $new_opts['rootline_titles'] );
		}

		if ( $form_id ) {
			self::maybe_fix_conditional_logic_after_duplicate( $form_id );
		}

		return $new_opts;
	}

	/**
	 * @param array $new_opts
	 *
	 * @return void
	 */
	private static function maybe_switch_submit_condition_field_ids( &$new_opts ) {
		if ( empty( $new_opts['submit_conditions']['hide_field'] ) ) {
			return;
		}

		global $frm_duplicate_ids;

		foreach ( $new_opts['submit_conditions']['hide_field'] as $key => $val ) {
			if ( isset( $frm_duplicate_ids[ $val ] ) ) {
				$new_opts['submit_conditions']['hide_field'][ $key ] = $frm_duplicate_ids[ $val ];
			}
		}
	}

	/**
	 * Update the conditional logic for fields that depend on other fields that were not already duplicated.
	 *
	 * @param int $form_id the new duplicated form id.
	 */
	private static function maybe_fix_conditional_logic_after_duplicate( $form_id ) {
		global $frm_duplicate_ids;
		global $frm_unprocessed_duplicate_field_keys;

		if ( ! $frm_unprocessed_duplicate_field_keys ) {
			return;
		}

		$where  = array(
			'fi.field_key' => $frm_unprocessed_duplicate_field_keys,
			'fi.form_id'   => $form_id,
		);
		$fields = FrmField::getAll( $where, 'field_order' );

		foreach ( $fields as $field ) {
			if ( empty( $field->field_options['hide_field'] ) ) {
				continue;
			}

			$updated = false;

			foreach ( $field->field_options['hide_field'] as $key => $field_id ) {
				if ( isset( $frm_duplicate_ids[ $field_id ] ) ) {
					$field->field_options['hide_field'][ $key ] = $frm_duplicate_ids[ $field_id ];
					$updated                                    = true;
				}
			}

			if ( $updated ) {
				FrmField::update( $field->id, array( 'field_options' => $field->field_options ) );
			}
		}

		$frm_unprocessed_duplicate_field_keys = array();
	}

	/**
	 * @param array $original_titles
	 *
	 * @return array updated titles, indexed by the new duplicated page break field ids.
	 */
	private static function switch_rootline_field_id_keys( $original_titles ) {
		global $frm_duplicate_ids;
		$duplicate_ids  = (array) $frm_duplicate_ids;
		$updated_titles = array();

		foreach ( $original_titles as $key => $value ) {
			$use_key                    = $duplicate_ids[ $key ] ?? $key;
			$updated_titles[ $use_key ] = $value;
		}

		return $updated_titles;
	}

	public static function has_fields_with_conditional_logic( $form ) {
		$has_no_logic = '"hide_field";a:0:{}';
		$sub_fields   = FrmDb::get_var(
			'frm_fields',
			array(
				'field_options not like' => $has_no_logic,
				'form_id'                => $form->id,
			)
		);
		return ! empty( $sub_fields );
	}

	/**
	 * Check if the "Submit this form with AJAX" setting is toggled on.
	 *
	 * @param stdClass $form
	 *
	 * @return int
	 */
	public static function is_ajax_on( $form ) {
		return $form->options['ajax_submit'] ?? 0;
	}

	/**
	 * @since 3.04
	 *
	 * @param object $form
	 *
	 * @return bool
	 */
	public static function is_open( $form ) {
		$options = $form->options;

		if ( empty( $options['open_status'] ) ) {
			return true;
		}

		if ( $options['open_status'] === 'closed' ) {
			return false;
		}

		if ( str_contains( $options['open_status'], 'schedule' ) ) {
			$is_started = self::has_time_passed( $options['open_date'], true );
			$is_ended   = self::has_time_passed( $options['close_date'], false );
			$is_open    = $is_started && ! $is_ended;

			if ( ! $is_open ) {
				return false;
			}
		}

		if ( str_contains( $options['open_status'], 'limit' ) && ! empty( $options['max_entries'] ) ) {
			$count = FrmEntry::getRecordCount( $form->id );
			return (int) $count < (int) $options['max_entries'];
		}

		return true;
	}

	/**
	 * @since 3.04
	 *
	 * @param string $time
	 * @param bool $if_blank - If no time is set, should it default to passed?
	 *
	 * @return bool
	 */
	private static function has_time_passed( $time, $if_blank ) {
		return $time ? ( current_time( 'timestamp' ) > strtotime( $time ) ) : $if_blank;
	}

	/**
	 * @param array $values
	 */
	public static function validate( $errors, $values ) {
		// Add a user id field if the form requires one
		$requires_user_id = isset( $values['logged_in'] )
			|| isset( $values['editable'] )
			|| ( isset( $values['options'] ) && FrmProFormsHelper::check_single_entry_type( $values['options'], 'user' ) )
			|| ( isset( $values['options']['save_draft'] ) && $values['options']['save_draft'] == 1 );

		if ( ! $requires_user_id ) {
			return $errors;
		}

		$form_id    = $values['id'];
		$user_field = FrmField::get_all_types_in_form( $form_id, 'user_id', 1 );

		if ( $user_field ) {
			return $errors;
		}

		$new_values         = FrmFieldsHelper::setup_new_vars( 'user_id', $form_id );
		$new_values['name'] = __( 'User ID', 'formidable' );
		FrmField::create( $new_values );

		return $errors;
	}

	/**
	 * @param int $form_id
	 *
	 * @return array
	 */
	public static function get_child_form_ids( $form_id ) {
		$form_ids       = array();
		$child_form_ids = FrmDb::get_col( 'frm_forms', array( 'parent_form_id' => $form_id ) );

		if ( $child_form_ids ) {
			$form_ids = $child_form_ids;
		}

		return array_filter( $form_ids, 'is_numeric' );
	}

	/**
	 * @param int $id form id
	 * @param array $map associative array mapped like $previous_value => $new_value
	 */
	private static function maybe_fix_submit_button_conditions( $id, $map ) {
		$form = FrmForm::getOne( $id );

		if ( empty( $form->options['submit_conditions'] ) ) {
			return;
		}

		// Refactor submit condition logic so it is easier to work with
		$submit_conditions = array();

		if ( isset( $form->options['submit_conditions']['hide_field'] ) ) {
			foreach ( $form->options['submit_conditions']['hide_field'] as $index => $field_id ) {
				if ( ! isset( $submit_conditions[ $field_id ] ) ) {
					$submit_conditions[ $field_id ] = array();
				}

				$submit_conditions[ $field_id ][] = array(
					'cond' => $form->options['submit_conditions']['hide_field_cond'][ $index ],
					'opt'  => $form->options['submit_conditions']['hide_opt'][ $index ],
				);
			}
		}

		$updated = false;

		foreach ( $map as $field_id => $values ) {
			if ( ! isset( $submit_conditions[ $field_id ] ) ) {
				continue;
			}

			foreach ( $submit_conditions[ $field_id ] as $index => $condition ) {
				if ( isset( $values[ $condition['opt'] ] ) ) {
					$form->options['submit_conditions']['hide_opt'][ $index ] = $values[ $condition['opt'] ];
					$updated = true;
				}
			}
		}

		if ( $updated ) {
			FrmForm::update( $id, array( 'options' => $form->options ) );
		}
	}

	/**
	 * @param int $id form id
	 * @param array $map associative array mapped like $field_id => array( $previous_value => $new_value )
	 */
	private static function maybe_fix_action_conditions( $id, $map ) {
		$actions = FrmFormAction::get_action_for_form( $id );

		foreach ( $actions as $action ) {
			if ( empty( $action->post_content['conditions'] ) ) {
				continue;
			}

			$updated = false;

			foreach ( $action->post_content['conditions'] as $index => $condition ) {
				if ( ! is_array( $condition ) ) {
					// skip data like [send_stop] => send or [any_all] => any
					continue;
				}

				if ( ! isset( $map[ $condition['hide_field'] ] ) ) {
					// Condition is not for any updated fields
					continue;
				}

				if ( ! isset( $map[ $condition['hide_field'] ][ $condition['hide_opt'] ] ) ) {
					continue;
				}

				$action->post_content['conditions'][ $index ]['hide_opt'] = $map[ $condition['hide_field'] ][ $condition['hide_opt'] ];
				$updated = true;
			}

			if ( ! $updated ) {
				continue;
			}

			global $wpdb;
			$wpdb->update( $wpdb->posts, array( 'post_content' => wp_json_encode( $action->post_content ) ), array( 'ID' => $action->ID ) );
		}
	}

	/**
	 * Conditional Logic sometimes relies on specifies radio / checkbox answers that can change
	 * Try to change the Conditional Logic that might have broken
	 *
	 * @param int $id form id
	 * @param array $map associative array mapped like $field_id => array( $previous_value => $new_value )
	 */
	public static function maybe_fix_conditions( $id, $map ) {
		$field_ids = array_keys( $map );

		// Filter the map to exclude anything that hasn't changed
		$map = array_reduce(
			$field_ids,
			function ( $total, $field_id ) use ( $map ) {
				$current = $map[ $field_id ];
				$current = array_filter(
					$current,
					function ( $value, $key ) {
						return $value !== $key;
					},
					ARRAY_FILTER_USE_BOTH
				);

				if ( $current ) {
					$total[ $field_id ] = $current;
				}

				return $total;
			},
			array()
		);

		if ( ! $map ) {
			return;
		}

		self::maybe_fix_submit_button_conditions( $id, $map );
		self::maybe_fix_action_conditions( $id, $map );
	}
}
