__( 'Permission denied.', 'pc-form-builder-xyz123' ) ) ); } $field_type = isset( $_POST['field_type'] ) ? sanitize_text_field( $_POST['field_type'] ) : ''; $field_index = isset( $_POST['field_index'] ) ? intval( $_POST['field_index'] ) : 0; if ( empty( $field_type ) ) { wp_send_json_error( array( 'message' => __( 'Field type is required.', 'pc-form-builder-xyz123' ) ) ); } require_once PCFB_PLUGIN_DIR . 'admin/class-admin-helper.php'; $helper = PCFB_Admin_Helper::get_instance(); ob_start(); $helper->render_new_field_item( $field_type, $field_index ); $html = ob_get_clean(); wp_send_json_success( array( 'html' => $html ) ); } public function shortcode_form( $atts ) { $atts = shortcode_atts( array( 'id' => 0, ), $atts ); if ( empty( $atts['id'] ) ) { return '
' . esc_html__( 'Form ID is required.', 'pc-form-builder-xyz123' ) . '
'; } $form = $this->get_form( intval( $atts['id'] ) ); if ( ! $form ) { return '' . esc_html__( 'Form not found.', 'pc-form-builder-xyz123' ) . '
'; } if ( 'active' !== $form->status ) { return '' . esc_html__( 'This form is not currently active.', 'pc-form-builder-xyz123' ) . '
'; } $fields = $this->get_form_fields( $form->id ); $settings = maybe_unserialize( $form->settings ); ob_start(); include PCFB_PLUGIN_DIR . 'public/templates/form-display.php'; return ob_get_clean(); } private function get_form( $form_id ) { global $wpdb; $table_name = $wpdb->prefix . 'pcfb_forms'; return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d", $form_id ) ); } private function get_form_fields( $form_id ) { global $wpdb; $table_name = $wpdb->prefix . 'pcfb_fields'; return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE form_id = %d ORDER BY sort_order ASC", $form_id ) ); } public function handle_form_submission() { check_ajax_referer( 'pcfb_public_nonce', 'nonce' ); $form_id = isset( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : 0; $form_data = isset( $_POST['form_data'] ) ? $_POST['form_data'] : array(); if ( empty( $form_id ) ) { wp_send_json_error( array( 'message' => __( 'Invalid form ID.', 'pc-form-builder-xyz123' ) ) ); } $form = $this->get_form( $form_id ); if ( ! $form ) { wp_send_json_error( array( 'message' => __( 'Form not found.', 'pc-form-builder-xyz123' ) ) ); } $fields = $this->get_form_fields( $form_id ); $errors = array(); $clean_data = array(); foreach ( $fields as $field ) { $value = isset( $form_data[ $field->field_name ] ) ? trim( $form_data[ $field->field_name ] ) : ''; $validation_rules = maybe_unserialize( $field->validation_rules ); if ( ! empty( $validation_rules['required'] ) && empty( $value ) ) { $errors[ $field->field_name ] = sprintf( __( '%s is required.', 'pc-form-builder-xyz123' ), $field->field_label ); } if ( ! empty( $value ) && 'email' === $field->field_type ) { if ( ! is_email( $value ) ) { $errors[ $field->field_name ] = __( 'Please enter a valid email address.', 'pc-form-builder-xyz123' ); } } $clean_data[ $field->id ] = sanitize_text_field( $value ); } if ( ! empty( $errors ) ) { wp_send_json_error( array( 'message' => __( 'Please fix the errors below.', 'pc-form-builder-xyz123' ), 'errors' => $errors ) ); } $response_id = $this->save_response( $form_id, $clean_data ); if ( $response_id ) { $success_message = ! empty( $settings['success_message'] ) ? $settings['success_message'] : __( 'Thank you! Your response has been submitted.', 'pc-form-builder-xyz123' ); wp_send_json_success( array( 'message' => $success_message, 'response_id' => $response_id ) ); } else { wp_send_json_error( array( 'message' => __( 'Failed to save your response. Please try again.', 'pc-form-builder-xyz123' ) ) ); } } private function save_response( $form_id, $field_data ) { global $wpdb; $responses_table = $wpdb->prefix . 'pcfb_responses'; $response_data_table = $wpdb->prefix . 'pcfb_response_data'; $user_ip = $_SERVER['REMOTE_ADDR'] ?? ''; $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $wpdb->insert( $responses_table, array( 'form_id' => $form_id, 'user_ip' => $user_ip, 'user_agent'=> $user_agent, 'status' => 'new', ) ); if ( ! $wpdb->insert_id ) { return false; } $response_id = $wpdb->insert_id; foreach ( $field_data as $field_id => $value ) { $wpdb->insert( $response_data_table, array( 'response_id' => $response_id, 'field_id' => $field_id, 'field_value' => $value, ) ); } return $response_id; } public static function get_forms( $args = array() ) { global $wpdb; $defaults = array( 'status' => 'active', 'orderby' => 'created_at', 'order' => 'DESC', 'limit' => -1, ); $args = wp_parse_args( $args, $defaults ); $table_name = $wpdb->prefix . 'pcfb_forms'; $sql = "SELECT * FROM {$table_name}"; if ( ! empty( $args['status'] ) ) { $sql .= $wpdb->prepare( " WHERE status = %s", $args['status'] ); } $sql .= " ORDER BY {$args['orderby']} {$args['order']}"; if ( $args['limit'] > 0 ) { $sql .= $wpdb->prepare( " LIMIT %d", $args['limit'] ); } return $wpdb->get_results( $sql ); } public static function get_form_by_id( $form_id ) { global $wpdb; $table_name = $wpdb->prefix . 'pcfb_forms'; return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d", $form_id ) ); } public static function get_form_count( $status = 'active' ) { global $wpdb; $table_name = $wpdb->prefix . 'pcfb_forms'; return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE status = %s", $status ) ); } public static function get_form_response_count( $form_id ) { global $wpdb; $table_name = $wpdb->prefix . 'pcfb_responses'; return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE form_id = %d", $form_id ) ); } public static function get_form_responses( $form_id, $args = array() ) { global $wpdb; $defaults = array( 'limit' => 20, 'offset' => 0, 'orderby' => 'created_at', 'order' => 'DESC', ); $args = wp_parse_args( $args, $defaults ); $responses_table = $wpdb->prefix . 'pcfb_responses'; $response_data_table = $wpdb->prefix . 'pcfb_response_data'; $fields_table = $wpdb->prefix . 'pcfb_fields'; $sql = $wpdb->prepare( "SELECT r.* FROM {$responses_table} r WHERE r.form_id = %d ORDER BY r.{$args['orderby']} {$args['order']} LIMIT %d OFFSET %d", $form_id, $args['limit'], $args['offset'] ); return $wpdb->get_results( $sql ); } public static function get_response_data( $response_id ) { global $wpdb; $response_data_table = $wpdb->prefix . 'pcfb_response_data'; $fields_table = $wpdb->prefix . 'pcfb_fields'; return $wpdb->get_results( $wpdb->prepare( "SELECT rd.*, f.field_name, f.field_label, f.field_type FROM {$response_data_table} rd JOIN {$fields_table} f ON rd.field_id = f.id WHERE rd.response_id = %d", $response_id ) ); } public static function delete_form( $form_id ) { global $wpdb; $forms_table = $wpdb->prefix . 'pcfb_forms'; $fields_table = $wpdb->prefix . 'pcfb_fields'; $responses_table = $wpdb->prefix . 'pcfb_responses'; $response_data_table = $wpdb->prefix . 'pcfb_response_data'; $response_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$responses_table} WHERE form_id = %d", $form_id ) ); if ( ! empty( $response_ids ) ) { $response_ids_placeholder = implode( ',', array_map( 'intval', $response_ids ) ); $wpdb->query( "DELETE FROM {$response_data_table} WHERE response_id IN ({$response_ids_placeholder})" ); $wpdb->query( "DELETE FROM {$responses_table} WHERE form_id = {$form_id}" ); } $wpdb->query( "DELETE FROM {$fields_table} WHERE form_id = {$form_id}" ); return $wpdb->delete( $forms_table, array( 'id' => $form_id ) ); } public function save_form( $data, $fields = array() ) { global $wpdb; $forms_table = $wpdb->prefix . 'pcfb_forms'; $fields_table = $wpdb->prefix . 'pcfb_fields'; $form_data = array( 'name' => sanitize_text_field( $data['name'] ), 'description' => sanitize_text_field( $data['description'] ), 'settings' => maybe_serialize( isset( $data['settings'] ) ? $data['settings'] : array() ), 'status' => isset( $data['status'] ) ? sanitize_text_field( $data['status'] ) : 'active', ); if ( ! empty( $data['id'] ) ) { $form_id = intval( $data['id'] ); $wpdb->update( $forms_table, $form_data, array( 'id' => $form_id ) ); $existing_fields = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$fields_table} WHERE form_id = %d", $form_id ) ); $existing_field_ids = ! empty( $existing_fields ) ? array_map( 'intval', $existing_fields ) : array(); $submitted_field_ids = array(); $sort_order = 0; if ( ! empty( $fields ) && is_array( $fields ) ) { foreach ( $fields as $field ) { $field_data = array( 'form_id' => $form_id, 'field_type' => sanitize_text_field( $field['field_type'] ), 'field_label' => sanitize_text_field( $field['field_label'] ), 'field_name' => $this->generate_field_name( $field['field_label'], $form_id, isset( $field['id'] ) ? $field['id'] : 0 ), 'placeholder' => isset( $field['placeholder'] ) ? sanitize_text_field( $field['placeholder'] ) : '', 'options' => isset( $field['options'] ) ? maybe_serialize( $field['options'] ) : '', 'validation_rules' => isset( $field['validation_rules'] ) ? maybe_serialize( $field['validation_rules'] ) : '', 'sort_order' => $sort_order++, ); if ( ! empty( $field['id'] ) ) { $submitted_field_ids[] = intval( $field['id'] ); $wpdb->update( $fields_table, $field_data, array( 'id' => intval( $field['id'] ) ) ); } else { $wpdb->insert( $fields_table, $field_data ); $submitted_field_ids[] = $wpdb->insert_id; } } } foreach ( $existing_field_ids as $field_id ) { if ( ! in_array( $field_id, $submitted_field_ids ) ) { $wpdb->delete( $fields_table, array( 'id' => $field_id ) ); } } return $form_id; } else { $wpdb->insert( $forms_table, $form_data ); $form_id = $wpdb->insert_id; if ( $form_id && ! empty( $fields ) && is_array( $fields ) ) { $sort_order = 0; foreach ( $fields as $field ) { $field_data = array( 'form_id' => $form_id, 'field_type' => sanitize_text_field( $field['field_type'] ), 'field_label' => sanitize_text_field( $field['field_label'] ), 'field_name' => $this->generate_field_name( $field['field_label'], $form_id ), 'placeholder' => isset( $field['placeholder'] ) ? sanitize_text_field( $field['placeholder'] ) : '', 'options' => isset( $field['options'] ) ? maybe_serialize( $field['options'] ) : '', 'validation_rules' => isset( $field['validation_rules'] ) ? maybe_serialize( $field['validation_rules'] ) : '', 'sort_order' => $sort_order++, ); $wpdb->insert( $fields_table, $field_data ); } } return $form_id; } } private function generate_field_name( $label, $form_id, $existing_id = 0 ) { $base_name = sanitize_title( $label ); $base_name = preg_replace( '/[^a-z0-9_]/', '', strtolower( $base_name ) ); if ( empty( $base_name ) ) { $base_name = 'field_' . time(); } global $wpdb; $fields_table = $wpdb->prefix . 'pcfb_fields'; $query = $wpdb->prepare( "SELECT COUNT(*) FROM {$fields_table} WHERE form_id = %d AND field_name LIKE %s", $form_id, $base_name . '%' ); $count = $wpdb->get_var( $query ); if ( $count > 0 ) { return $base_name . '_' . ( $count + 1 ); } return $base_name; } }