Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191
This commit is contained in:
204
chat/templates/Form Builder/admin/admin-menu.php
Normal file
204
chat/templates/Form Builder/admin/admin-menu.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Menu Class
|
||||
*
|
||||
* Handles admin menu registration and page routing.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
class PCFB_Admin_Menu {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function __construct() {
|
||||
add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
|
||||
add_action( 'admin_init', array( $this, 'handle_form_actions' ) );
|
||||
add_action( 'wp_ajax_pcfb_add_field', array( $this, 'ajax_add_field' ) );
|
||||
}
|
||||
|
||||
public function add_admin_menu() {
|
||||
add_menu_page(
|
||||
__( 'Form Builder', 'pc-form-builder-xyz123' ),
|
||||
__( 'Form Builder', 'pc-form-builder-xyz123' ),
|
||||
'manage_options',
|
||||
'pcfb-form-builder',
|
||||
array( $this, 'render_form_builder_page' ),
|
||||
'dashicons-feedback',
|
||||
30
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'pcfb-form-builder',
|
||||
__( 'Form Builder', 'pc-form-builder-xyz123' ),
|
||||
__( 'Form Builder', 'pc-form-builder-xyz123' ),
|
||||
'manage_options',
|
||||
'pcfb-form-builder',
|
||||
array( $this, 'render_form_builder_page' )
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'pcfb-form-builder',
|
||||
__( 'All Forms', 'pc-form-builder-xyz123' ),
|
||||
__( 'All Forms', 'pc-form-builder-xyz123' ),
|
||||
'manage_options',
|
||||
'pcfb-all-forms',
|
||||
array( $this, 'render_all_forms_page' )
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'pcfb-form-builder',
|
||||
__( 'Responses', 'pc-form-builder-xyz123' ),
|
||||
__( 'Responses', 'pc-form-builder-xyz123' ),
|
||||
'manage_options',
|
||||
'pcfb-responses',
|
||||
array( $this, 'render_responses_page' )
|
||||
);
|
||||
}
|
||||
|
||||
public function render_form_builder_page() {
|
||||
require_once PCFB_PLUGIN_DIR . 'admin/class-admin-helper.php';
|
||||
$helper = PCFB_Admin_Helper::get_instance();
|
||||
|
||||
$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;
|
||||
|
||||
if ( $form_id > 0 ) {
|
||||
include PCFB_PLUGIN_DIR . 'admin/page-form-builder.php';
|
||||
} else {
|
||||
include PCFB_PLUGIN_DIR . 'admin/page-form-builder.php';
|
||||
}
|
||||
}
|
||||
|
||||
public function render_all_forms_page() {
|
||||
include PCFB_PLUGIN_DIR . 'admin/page-all-forms.php';
|
||||
}
|
||||
|
||||
public function render_responses_page() {
|
||||
$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;
|
||||
$response_id = isset( $_GET['response_id'] ) ? intval( $_GET['response_id'] ) : 0;
|
||||
|
||||
if ( $response_id > 0 ) {
|
||||
include PCFB_PLUGIN_DIR . 'admin/page-response-detail.php';
|
||||
} elseif ( $form_id > 0 ) {
|
||||
include PCFB_PLUGIN_DIR . 'admin/page-form-responses.php';
|
||||
} else {
|
||||
include PCFB_PLUGIN_DIR . 'admin/page-responses.php';
|
||||
}
|
||||
}
|
||||
|
||||
public function handle_form_actions() {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST['pcfb_action'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'pcfb_admin_action' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = sanitize_text_field( $_POST['pcfb_action'] );
|
||||
|
||||
switch ( $action ) {
|
||||
case 'save_form':
|
||||
$this->handle_save_form();
|
||||
break;
|
||||
case 'delete_form':
|
||||
$this->handle_delete_form();
|
||||
break;
|
||||
case 'toggle_status':
|
||||
$this->handle_toggle_status();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handle_save_form() {
|
||||
$form_data = isset( $_POST['form'] ) ? $_POST['form'] : array();
|
||||
$fields = isset( $_POST['fields'] ) ? $_POST['fields'] : array();
|
||||
|
||||
$handler = PC_Form_Handler::get_instance();
|
||||
$form_id = $handler->save_form( $form_data, $fields );
|
||||
|
||||
if ( $form_id ) {
|
||||
$edit_url = admin_url( 'admin.php?page=pcfb-form-builder&form_id=' . $form_id );
|
||||
$shortcode = '[pcfb-form id="' . $form_id . '"]';
|
||||
|
||||
add_action( 'admin_notices', function() use ( $edit_url, $shortcode ) {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>';
|
||||
echo sprintf( __( 'Form saved successfully!', 'pc-form-builder-xyz123' ) );
|
||||
echo '</p><p><strong>' . esc_html__( 'Shortcode:', 'pc-form-builder-xyz123' ) . '</strong> <code onclick="this.select(); document.execCommand(\'copy\');" style="background: #f0f0f1; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 14px;">' . esc_html( $shortcode ) . '</code></p>';
|
||||
echo '<p><a href="' . esc_url( $edit_url ) . '" class="button button-primary" style="margin-top: 10px;">' . esc_html__( 'Go to Form Builder', 'pc-form-builder-xyz123' ) . '</a></p></div>';
|
||||
} );
|
||||
|
||||
wp_redirect( admin_url( 'admin.php?page=pcfb-form-builder&form_id=' . $form_id ) );
|
||||
exit;
|
||||
} else {
|
||||
add_action( 'admin_notices', function() {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>';
|
||||
echo esc_html__( 'Failed to save form. Please try again.', 'pc-form-builder-xyz123' );
|
||||
echo '</p></div>';
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private function handle_delete_form() {
|
||||
$form_id = isset( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : 0;
|
||||
|
||||
if ( $form_id > 0 && PC_Form_Handler::delete_form( $form_id ) ) {
|
||||
add_action( 'admin_notices', function() {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>';
|
||||
echo esc_html__( 'Form deleted successfully.', 'pc-form-builder-xyz123' );
|
||||
echo '</p></div>';
|
||||
} );
|
||||
} else {
|
||||
add_action( 'admin_notices', function() {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>';
|
||||
echo esc_html__( 'Failed to delete form. Please try again.', 'pc-form-builder-xyz123' );
|
||||
echo '</p></div>';
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private function handle_toggle_status() {
|
||||
global $wpdb;
|
||||
$form_id = isset( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : 0;
|
||||
|
||||
if ( $form_id > 0 ) {
|
||||
$form = PC_Form_Handler::get_form_by_id( $form_id );
|
||||
if ( $form ) {
|
||||
$new_status = 'active' === $form->status ? 'inactive' : 'active';
|
||||
$table_name = $wpdb->prefix . 'pcfb_forms';
|
||||
$wpdb->update( $table_name, array( 'status' => $new_status ), array( 'id' => $form_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_add_field() {
|
||||
check_ajax_referer( 'pcfb_admin_nonce', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error( array( 'message' => __( 'Permission denied.', 'pc-form-builder-xyz123' ) ) );
|
||||
}
|
||||
|
||||
$field_type = isset( $_POST['field_type'] ) ? sanitize_text_field( $_POST['field_type'] ) : 'text';
|
||||
$field_index = isset( $_POST['field_index'] ) ? intval( $_POST['field_index'] ) : 0;
|
||||
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
181
chat/templates/Form Builder/admin/class-admin-helper.php
Normal file
181
chat/templates/Form Builder/admin/class-admin-helper.php
Normal file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Helper Class
|
||||
*
|
||||
* Provides helper methods for admin pages.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
class PCFB_Admin_Helper {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function get_field_types() {
|
||||
return array(
|
||||
'text' => __( 'Text Input', 'pc-form-builder-xyz123' ),
|
||||
'email' => __( 'Email', 'pc-form-builder-xyz123' ),
|
||||
'name' => __( 'Name', 'pc-form-builder-xyz123' ),
|
||||
'response' => __( 'Response', 'pc-form-builder-xyz123' ),
|
||||
'dropdown' => __( 'Dropdown', 'pc-form-builder-xyz123' ),
|
||||
'checkbox' => __( 'Checkbox', 'pc-form-builder-xyz123' ),
|
||||
);
|
||||
}
|
||||
|
||||
public 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 render_field_item( $field, $index = 0 ) {
|
||||
$validation_rules = maybe_unserialize( $field->validation_rules );
|
||||
$options = maybe_unserialize( $field->options );
|
||||
$field_types = $this->get_field_types();
|
||||
$field_type_label = isset( $field_types[ $field->field_type ] ) ? $field_types[ $field->field_type ] : $field->field_type;
|
||||
?>
|
||||
<div class="pcfb-field-item" data-field-id="<?php echo esc_attr( $field->id ); ?>" data-field-type="<?php echo esc_attr( $field->field_type ); ?>">
|
||||
<input type="hidden" name="fields[<?php echo esc_attr( $index ); ?>][id]" value="<?php echo esc_attr( $field->id ); ?>">
|
||||
<input type="hidden" name="fields[<?php echo esc_attr( $index ); ?>][field_type]" value="<?php echo esc_attr( $field->field_type ); ?>">
|
||||
<input type="hidden" name="fields[<?php echo esc_attr( $index ); ?>][field_name]" value="<?php echo esc_attr( $field->field_name ); ?>">
|
||||
|
||||
<div class="pcfb-field-header">
|
||||
<span class="pcfb-field-type-badge"><?php echo esc_html( $field_type_label ); ?></span>
|
||||
<span class="pcfb-field-name-display"><?php echo esc_html( $field->field_name ); ?></span>
|
||||
<div class="pcfb-field-actions">
|
||||
<button type="button" class="button button-small pcfb-toggle-field">
|
||||
<span class="dashicons dashicons-arrow-up-alt2"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pcfb-field-content">
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Field Label', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<input type="text" name="fields[<?php echo esc_attr( $index ); ?>][field_label]" value="<?php echo esc_attr( $field->field_label ); ?>" class="pcfb-field-label-input" placeholder="<?php esc_attr_e( 'Enter field label', 'pc-form-builder-xyz123' ); ?>">
|
||||
</div>
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Placeholder Text', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<input type="text" name="fields[<?php echo esc_attr( $index ); ?>][placeholder]" value="<?php echo esc_attr( $field->placeholder ); ?>" placeholder="<?php esc_attr_e( 'Optional placeholder text', 'pc-form-builder-xyz123' ); ?>">
|
||||
</div>
|
||||
|
||||
<?php if ( 'dropdown' === $field->field_type ) : ?>
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Options', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<textarea name="fields[<?php echo esc_attr( $index ); ?>][options]" rows="3" placeholder="<?php esc_attr_e( 'One option per line', 'pc-form-builder-xyz123' ); ?>"><?php echo ! empty( $options ) ? esc_textarea( implode( "\n", $options ) ) : ''; ?></textarea>
|
||||
<p class="description"><?php esc_html_e( 'Enter each option on a new line.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
<?php elseif ( 'checkbox' === $field->field_type ) : ?>
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Checkbox Options', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<textarea name="fields[<?php echo esc_attr( $index ); ?>][options]" rows="3" placeholder="<?php esc_attr_e( 'One option per line', 'pc-form-builder-xyz123' ); ?>"><?php echo ! empty( $options ) ? esc_textarea( implode( "\n", $options ) ) : ''; ?></textarea>
|
||||
<p class="description"><?php esc_html_e( 'Enter each checkbox option on a new line.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="pcfb-form-group pcfb-validation-group">
|
||||
<label class="pcfb-checkbox-label">
|
||||
<input type="checkbox" name="fields[<?php echo esc_attr( $index ); ?>][validation_rules][required]" value="1" <?php checked( ! empty( $validation_rules['required'] ), true ); ?>>
|
||||
<?php esc_html_e( 'Required field', 'pc-form-builder-xyz123' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pcfb-field-footer">
|
||||
<button type="button" class="button button-link-delete pcfb-delete-field"><?php esc_html_e( 'Remove Field', 'pc-form-builder-xyz123' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function render_new_field_item( $field_type, $index ) {
|
||||
$field_types = $this->get_field_types();
|
||||
$field_type_label = isset( $field_types[ $field_type ] ) ? $field_types[ $field_type ] : $field_type;
|
||||
$default_labels = array(
|
||||
'text' => __( 'Text Field', 'pc-form-builder-xyz123' ),
|
||||
'email' => __( 'Email Address', 'pc-form-builder-xyz123' ),
|
||||
'name' => __( 'Full Name', 'pc-form-builder-xyz123' ),
|
||||
'response' => __( 'Your Response', 'pc-form-builder-xyz123' ),
|
||||
'dropdown' => __( 'Select Option', 'pc-form-builder-xyz123' ),
|
||||
'checkbox' => __( 'Checkboxes', 'pc-form-builder-xyz123' ),
|
||||
);
|
||||
$default_label = isset( $default_labels[ $field_type ] ) ? $default_labels[ $field_type ] : __( 'Field', 'pc-form-builder-xyz123' );
|
||||
$placeholder = '';
|
||||
if ( 'response' === $field_type ) {
|
||||
$placeholder = __( 'Enter your response here...', 'pc-form-builder-xyz123' );
|
||||
}
|
||||
?>
|
||||
<div class="pcfb-field-item pcfb-new-field" data-field-id="new" data-field-type="<?php echo esc_attr( $field_type ); ?>">
|
||||
<input type="hidden" name="fields[<?php echo esc_attr( $index ); ?>][id]" value="">
|
||||
<input type="hidden" name="fields[<?php echo esc_attr( $index ); ?>][field_type]" value="<?php echo esc_attr( $field_type ); ?>">
|
||||
<input type="hidden" name="fields[<?php echo esc_attr( $index ); ?>][field_name]" value="">
|
||||
|
||||
<div class="pcfb-field-header">
|
||||
<span class="pcfb-field-type-badge"><?php echo esc_html( $field_type_label ); ?></span>
|
||||
<span class="pcfb-field-name-display"><?php echo esc_html( sanitize_title( $default_label ) ); ?></span>
|
||||
<div class="pcfb-field-actions">
|
||||
<button type="button" class="button button-small pcfb-toggle-field">
|
||||
<span class="dashicons dashicons-arrow-up-alt2"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pcfb-field-content">
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Field Label', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<input type="text" name="fields[<?php echo esc_attr( $index ); ?>][field_label]" value="<?php echo esc_attr( $default_label ); ?>" class="pcfb-field-label-input" placeholder="<?php esc_attr_e( 'Enter field label', 'pc-form-builder-xyz123' ); ?>">
|
||||
</div>
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Placeholder Text', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<input type="text" name="fields[<?php echo esc_attr( $index ); ?>][placeholder]" value="<?php echo esc_attr( $placeholder ); ?>" placeholder="<?php esc_attr_e( 'Optional placeholder text', 'pc-form-builder-xyz123' ); ?>">
|
||||
</div>
|
||||
|
||||
<?php if ( 'dropdown' === $field_type ) : ?>
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Options', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<textarea name="fields[<?php echo esc_attr( $index ); ?>][options]" rows="3" placeholder="<?php esc_attr_e( 'One option per line', 'pc-form-builder-xyz123' ); ?>"></textarea>
|
||||
<p class="description"><?php esc_html_e( 'Enter each option on a new line.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
<?php elseif ( 'checkbox' === $field_type ) : ?>
|
||||
<div class="pcfb-form-group">
|
||||
<label><?php esc_html_e( 'Checkbox Options', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<textarea name="fields[<?php echo esc_attr( $index ); ?>][options]" rows="3" placeholder="<?php esc_attr_e( 'One option per line', 'pc-form-builder-xyz123' ); ?>"></textarea>
|
||||
<p class="description"><?php esc_html_e( 'Enter each checkbox option on a new line.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="pcfb-form-group pcfb-validation-group">
|
||||
<label class="pcfb-checkbox-label">
|
||||
<input type="checkbox" name="fields[<?php echo esc_attr( $index ); ?>][validation_rules][required]" value="1">
|
||||
<?php esc_html_e( 'Required field', 'pc-form-builder-xyz123' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pcfb-field-footer">
|
||||
<button type="button" class="button button-link-delete pcfb-delete-field"><?php esc_html_e( 'Remove Field', 'pc-form-builder-xyz123' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'PCFB_Field_Icons' ) ) {
|
||||
class PCFB_Field_Icons {
|
||||
private static $icons = array(
|
||||
'text' => 'dashicons-text',
|
||||
'email' => 'dashicons-email',
|
||||
'name' => 'dashicons-admin-users',
|
||||
'response' => 'dashicons-editor-quote',
|
||||
'dropdown' => 'dashicons-arrow-down-alt2',
|
||||
'checkbox' => 'dashicons-yes',
|
||||
);
|
||||
|
||||
public static function get_field_icon( $type ) {
|
||||
return isset( self::$icons[ $type ] ) ? self::$icons[ $type ] : 'dashicons-editor-help';
|
||||
}
|
||||
}
|
||||
}
|
||||
1330
chat/templates/Form Builder/admin/css/admin-style.css
Normal file
1330
chat/templates/Form Builder/admin/css/admin-style.css
Normal file
File diff suppressed because it is too large
Load Diff
240
chat/templates/Form Builder/admin/js/admin-script.js
Normal file
240
chat/templates/Form Builder/admin/js/admin-script.js
Normal file
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* PC Form Builder Admin Scripts
|
||||
*
|
||||
* JavaScript functionality for the form builder admin interface.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
var PCFB_Admin = {
|
||||
fieldIndex: 0,
|
||||
deletedFields: [],
|
||||
|
||||
init: function() {
|
||||
this.initFieldTypeButtons();
|
||||
this.initFieldToggle();
|
||||
this.initFieldDelete();
|
||||
this.initDeleteModal();
|
||||
this.initFormBuilder();
|
||||
},
|
||||
|
||||
initFieldTypeButtons: function() {
|
||||
var self = this;
|
||||
|
||||
$('.pcfb-add-field-btn').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var fieldType = $(this).data('field-type');
|
||||
self.addField(fieldType);
|
||||
});
|
||||
},
|
||||
|
||||
addField: function(fieldType) {
|
||||
var self = this;
|
||||
var container = $('#pcfb-fields-container');
|
||||
|
||||
if (container.find('.pcfb-empty-fields').length > 0) {
|
||||
container.find('.pcfb-empty-fields').remove();
|
||||
}
|
||||
|
||||
var fieldIndex = this.getNextFieldIndex();
|
||||
var nonce = pcfbAdminVars.nonce;
|
||||
|
||||
$.ajax({
|
||||
url: pcfbAdminVars.ajaxurl,
|
||||
type: 'POST',
|
||||
data: {
|
||||
action: 'pcfb_add_field',
|
||||
field_type: fieldType,
|
||||
field_index: fieldIndex,
|
||||
nonce: nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
container.append(response.data.html);
|
||||
self.reindexFields();
|
||||
self.initFieldToggle();
|
||||
self.initFieldDelete();
|
||||
self.updateLabelOnChange();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert(pcfbAdminVars.i18n.confirmDeleteField);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getNextFieldIndex: function() {
|
||||
var maxIndex = 0;
|
||||
$('#pcfb-fields-container [name^="fields["]').each(function() {
|
||||
var match = $(this).attr('name').match(/fields\[(\d+)\]/);
|
||||
if (match && parseInt(match[1]) > maxIndex) {
|
||||
maxIndex = parseInt(match[1]);
|
||||
}
|
||||
});
|
||||
return maxIndex + 1;
|
||||
},
|
||||
|
||||
reindexFields: function() {
|
||||
var fields = $('#pcfb-fields-container .pcfb-field-item');
|
||||
fields.each(function(index) {
|
||||
var field = $(this);
|
||||
field.find('[name^="fields["]').each(function() {
|
||||
var name = $(this).attr('name');
|
||||
var newName = name.replace(/fields\[\d+\]/, 'fields[' + index + ']');
|
||||
$(this).attr('name', newName);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
initFieldToggle: function() {
|
||||
$('.pcfb-toggle-field').off('click').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$(this).closest('.pcfb-field-item').toggleClass('collapsed');
|
||||
});
|
||||
},
|
||||
|
||||
initFieldDelete: function() {
|
||||
var self = this;
|
||||
|
||||
$('.pcfb-delete-field').off('click').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var fieldItem = $(this).closest('.pcfb-field-item');
|
||||
var fieldId = fieldItem.data('field-id');
|
||||
|
||||
if (confirm(pcfbAdminVars.i18n.confirmDeleteField)) {
|
||||
if (fieldId && fieldId !== 'new') {
|
||||
self.deletedFields.push(fieldId);
|
||||
$('<input type="hidden" name="deleted_fields[]" value="' + fieldId + '">').appendTo('#pcfb-form-builder');
|
||||
}
|
||||
fieldItem.fadeOut(300, function() {
|
||||
$(this).remove();
|
||||
self.reindexFields();
|
||||
self.checkEmptyFields();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
checkEmptyFields: function() {
|
||||
var container = $('#pcfb-fields-container');
|
||||
if (container.find('.pcfb-field-item').length === 0) {
|
||||
container.html('<div class="pcfb-empty-fields"><p>' + pcfbAdminVars.i18n.fieldLabel + '</p></div>');
|
||||
}
|
||||
},
|
||||
|
||||
updateLabelOnChange: function() {
|
||||
$('.pcfb-field-label-input').off('input').on('input', function() {
|
||||
var label = $(this).val();
|
||||
var fieldItem = $(this).closest('.pcfb-field-item');
|
||||
var fieldName = fieldItem.find('.pcfb-field-name-display');
|
||||
var baseName = this.getAttribute('name').match(/fields\[(\d+)\]\[field_label\]/);
|
||||
if (baseName) {
|
||||
var slug = label.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '');
|
||||
if (slug === '') {
|
||||
slug = 'field_' + baseName[1];
|
||||
}
|
||||
fieldName.text(slug);
|
||||
var hiddenName = fieldItem.find('input[name^="fields["][name$="[field_name]"]');
|
||||
hiddenName.val(slug);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
initDeleteModal: function() {
|
||||
var self = this;
|
||||
|
||||
$(document).on('click', '.pcfb-delete-form, .pcfb-delete-form-btn, .pcfb-delete-form-link', function(e) {
|
||||
if (e.target.tagName === 'BUTTON' || $(this).hasClass('pcfb-delete-form') || $(this).hasClass('pcfb-delete-form-btn') || $(this).hasClass('pcfb-delete-form-link')) {
|
||||
e.preventDefault();
|
||||
var formId = $(this).data('form-id');
|
||||
var formName = $(this).data('form-name');
|
||||
|
||||
$('#pcfb-delete-form-id').val(formId);
|
||||
$('#pcfb-delete-form-name').text(formName);
|
||||
$('#pcfb-delete-modal').addClass('active').show();
|
||||
}
|
||||
});
|
||||
|
||||
$('.pcfb-modal-close, .pcfb-modal-cancel').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$('#pcfb-delete-modal').removeClass('active').hide();
|
||||
});
|
||||
|
||||
$('#pcfb-delete-modal').on('click', function(e) {
|
||||
if ($(e.target).is('#pcfb-delete-modal')) {
|
||||
$(this).removeClass('active').hide();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
initFormBuilder: function() {
|
||||
var self = this;
|
||||
|
||||
if ($('#pcfb-fields-container').length > 0) {
|
||||
$('#pcfb-fields-container').sortable({
|
||||
handle: '.pcfb-field-header',
|
||||
placeholder: 'pcfb-field-placeholder',
|
||||
tolerance: 'pointer',
|
||||
update: function() {
|
||||
self.reindexFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ($('#pcfb-sections-container').length > 0) {
|
||||
$('#pcfb-sections-container').sortable({
|
||||
handle: '.pcfb-section-header',
|
||||
placeholder: 'pcfb-section-placeholder',
|
||||
tolerance: 'pointer'
|
||||
});
|
||||
}
|
||||
|
||||
$('#pcfb-add-section').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
self.addSection();
|
||||
});
|
||||
|
||||
$('#pcfb-form-builder').on('submit', function(e) {
|
||||
var formName = $('#form-name').val().trim();
|
||||
if (!formName) {
|
||||
e.preventDefault();
|
||||
alert(pcfbAdminVars.i18n.fieldLabel);
|
||||
$('#form-name').focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
var hasRequiredFields = false;
|
||||
$('.pcfb-field-item').each(function() {
|
||||
if ($(this).find('[name*="[validation_rules][required]"]').is(':checked')) {
|
||||
hasRequiredFields = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
addSection: function() {
|
||||
var container = $('#pcfb-sections-container');
|
||||
var sectionCount = container.find('.pcfb-section-box').length;
|
||||
var sectionHtml = '<div class="pcfb-section-box" data-section-id="new-' + sectionCount + '">' +
|
||||
'<div class="pcfb-section-header">' +
|
||||
'<span class="dashicons dashicons-menu"></span>' +
|
||||
'<span class="pcfb-section-title">Section ' + (sectionCount + 1) + '</span>' +
|
||||
'</div>' +
|
||||
'<div class="pcfb-section-content">' +
|
||||
'<input type="hidden" name="sections[' + sectionCount + '][id]" value="">' +
|
||||
'<input type="hidden" name="sections[' + sectionCount + '][title]" value="Section ' + (sectionCount + 1) + '">' +
|
||||
'<p class="description">Drag fields into this section or click to configure.</p>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
container.append(sectionHtml);
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
PCFB_Admin.init();
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
195
chat/templates/Form Builder/admin/page-all-forms.php
Normal file
195
chat/templates/Form Builder/admin/page-all-forms.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<div class="wrap pcfb-wrap">
|
||||
<h1 class="wp-heading-inline">
|
||||
<span class="pcfb-heading-icon dashicons dashicons-forms"></span>
|
||||
<?php esc_html_e( 'All Forms', 'pc-form-builder-xyz123' ); ?>
|
||||
</h1>
|
||||
<a href="<?php echo admin_url( 'admin.php?page=pcfb-form-builder' ); ?>" class="page-title-action">
|
||||
<span class="dashicons dashicons-plus"></span>
|
||||
<?php esc_html_e( 'Add New Form', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<?php
|
||||
$forms = PC_Form_Handler::get_forms( array( 'limit' => 50, 'status' => '' ) );
|
||||
$active_count = PC_Form_Handler::get_form_count( 'active' );
|
||||
$inactive_count = PC_Form_Handler::get_form_count( 'inactive' );
|
||||
$total_responses = 0;
|
||||
foreach ( $forms as $form ) {
|
||||
$total_responses += PC_Form_Handler::get_form_response_count( $form->id );
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="pcfb-all-forms-page">
|
||||
<div class="pcfb-stats-row">
|
||||
<div class="pcfb-stat-card">
|
||||
<div class="pcfb-stat-icon pcfb-stat-icon-blue">
|
||||
<span class="dashicons dashicons-forms"></span>
|
||||
</div>
|
||||
<div class="pcfb-stat-content">
|
||||
<span class="pcfb-stat-number"><?php echo esc_html( count( $forms ) ); ?></span>
|
||||
<span class="pcfb-stat-label"><?php esc_html_e( 'Total Forms', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-stat-card">
|
||||
<div class="pcfb-stat-icon pcfb-stat-icon-green">
|
||||
<span class="dashicons dashicons-yes-alt"></span>
|
||||
</div>
|
||||
<div class="pcfb-stat-content">
|
||||
<span class="pcfb-stat-number"><?php echo esc_html( $active_count ); ?></span>
|
||||
<span class="pcfb-stat-label"><?php esc_html_e( 'Active Forms', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-stat-card">
|
||||
<div class="pcfb-stat-icon pcfb-stat-icon-orange">
|
||||
<span class="dashicons dashicons-hidden"></span>
|
||||
</div>
|
||||
<div class="pcfb-stat-content">
|
||||
<span class="pcfb-stat-number"><?php echo esc_html( $inactive_count ); ?></span>
|
||||
<span class="pcfb-stat-label"><?php esc_html_e( 'Inactive Forms', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-stat-card">
|
||||
<div class="pcfb-stat-icon pcfb-stat-icon-purple">
|
||||
<span class="dashicons dashicons-pressthis"></span>
|
||||
</div>
|
||||
<div class="pcfb-stat-content">
|
||||
<span class="pcfb-stat-number"><?php echo esc_html( $total_responses ); ?></span>
|
||||
<span class="pcfb-stat-label"><?php esc_html_e( 'Total Signups', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( empty( $forms ) ) : ?>
|
||||
<div class="pcfb-empty-state">
|
||||
<span class="dashicons dashicons-forms pcfb-empty-icon"></span>
|
||||
<h3><?php esc_html_e( 'No forms created yet', 'pc-form-builder-xyz123' ); ?></h3>
|
||||
<p><?php esc_html_e( 'Create your first form to start collecting responses from your visitors.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<a href="<?php echo admin_url( 'admin.php?page=pcfb-form-builder' ); ?>" class="button button-primary">
|
||||
<?php esc_html_e( 'Create Your First Form', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="pcfb-forms-table-card">
|
||||
<div class="pcfb-card-header pcfb-table-header">
|
||||
<h2><?php esc_html_e( 'Your Forms', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
|
||||
<table class="widefat pcfb-table pcfb-forms-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="column-primary"><?php esc_html_e( 'Form Name', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Shortcode', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Fields', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Signups', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Status', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Created', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th class="column-actions"><?php esc_html_e( 'Actions', 'pc-form-builder-xyz123' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ( $forms as $form ) : ?>
|
||||
<?php
|
||||
$field_count = pcfb_get_field_count( $form->id );
|
||||
$response_count = PC_Form_Handler::get_form_response_count( $form->id );
|
||||
$edit_url = admin_url( 'admin.php?page=pcfb-form-builder&form_id=' . $form->id );
|
||||
$responses_url = admin_url( 'admin.php?page=pcfb-responses&form_id=' . $form->id );
|
||||
$status_class = 'active' === $form->status ? 'status-active' : 'status-inactive';
|
||||
$status_text = 'active' === $form->status ? __( 'Active', 'pc-form-builder-xyz123' ) : __( 'Inactive', 'pc-form-builder-xyz123' );
|
||||
?>
|
||||
<tr>
|
||||
<td class="column-primary">
|
||||
<strong>
|
||||
<a href="<?php echo esc_url( $edit_url ); ?>">
|
||||
<?php echo esc_html( $form->name ); ?>
|
||||
</a>
|
||||
</strong>
|
||||
<div class="row-actions">
|
||||
<span class="edit"><a href="<?php echo esc_url( $edit_url ); ?>"><?php esc_html_e( 'Edit', 'pc-form-builder-xyz123' ); ?></a> | </span>
|
||||
<span class="responses"><a href="<?php echo esc_url( $responses_url ); ?>"><?php esc_html_e( 'Responses', 'pc-form-builder-xyz123' ); ?></a> | </span>
|
||||
<span class="delete"><button type="button" class="pcfb-delete-form-link" data-form-id="<?php echo esc_attr( $form->id ); ?>" data-form-name="<?php echo esc_attr( $form->name ); ?>"><?php esc_html_e( 'Delete', 'pc-form-builder-xyz123' ); ?></button></span>
|
||||
</div>
|
||||
<?php if ( $form->description ) : ?>
|
||||
<br>
|
||||
<small class="description"><?php echo esc_html( $form->description ); ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td data-colname="<?php esc_attr_e( 'Shortcode', 'pc-form-builder-xyz123' ); ?>">
|
||||
<code class="pcfb-shortcode" onclick="this.select(); document.execCommand('copy');" title="<?php esc_attr_e( 'Click to copy', 'pc-form-builder-xyz123' ); ?>">
|
||||
[pcfb-form id="<?php echo esc_attr( $form->id ); ?>"]
|
||||
</code>
|
||||
</td>
|
||||
<td data-colname="<?php esc_attr_e( 'Fields', 'pc-form-builder-xyz123' ); ?>">
|
||||
<span class="pcfb-field-badge"><?php echo esc_html( $field_count ); ?></span>
|
||||
</td>
|
||||
<td data-colname="<?php esc_attr_e( 'Signups', 'pc-form-builder-xyz123' ); ?>">
|
||||
<?php if ( $response_count > 0 ) : ?>
|
||||
<a href="<?php echo esc_url( $responses_url ); ?>" class="pcfb-signups-link">
|
||||
<span class="pcfb-signup-count"><?php echo esc_html( $response_count ); ?></span>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<span class="pcfb-signup-count zero"><?php echo esc_html( $response_count ); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td data-colname="<?php esc_attr_e( 'Status', 'pc-form-builder-xyz123' ); ?>">
|
||||
<span class="pcfb-status <?php echo esc_attr( $status_class ); ?>">
|
||||
<?php echo esc_html( $status_text ); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td data-colname="<?php esc_attr_e( 'Created', 'pc-form-builder-xyz123' ); ?>">
|
||||
<?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $form->created_at ) ) ); ?>
|
||||
</td>
|
||||
<td class="column-actions" data-colname="<?php esc_attr_e( 'Actions', 'pc-form-builder-xyz123' ); ?>">
|
||||
<div class="pcfb-actions">
|
||||
<a href="<?php echo esc_url( $edit_url ); ?>" class="button button-small" title="<?php esc_attr_e( 'Edit Form', 'pc-form-builder-xyz123' ); ?>">
|
||||
<span class="dashicons dashicons-edit"></span>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( $responses_url ); ?>" class="button button-small" title="<?php esc_attr_e( 'View Responses', 'pc-form-builder-xyz123' ); ?>">
|
||||
<span class="dashicons dashicons-pressthis"></span>
|
||||
</a>
|
||||
<button type="button" class="button button-small pcfb-delete-form" data-form-id="<?php echo esc_attr( $form->id ); ?>" data-form-name="<?php echo esc_attr( $form->name ); ?>" title="<?php esc_attr_e( 'Delete Form', 'pc-form-builder-xyz123' ); ?>">
|
||||
<span class="dashicons dashicons-trash"></span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div id="pcfb-delete-modal" class="pcfb-modal" style="display: none;">
|
||||
<div class="pcfb-modal-content">
|
||||
<div class="pcfb-modal-header">
|
||||
<h3><?php esc_html_e( 'Delete Form', 'pc-form-builder-xyz123' ); ?></h3>
|
||||
<button type="button" class="pcfb-modal-close">×</button>
|
||||
</div>
|
||||
<div class="pcfb-modal-body">
|
||||
<p><?php esc_html_e( 'Are you sure you want to delete this form? All responses will also be deleted. This action cannot be undone.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<p><strong id="pcfb-delete-form-name"></strong></p>
|
||||
</div>
|
||||
<div class="pcfb-modal-footer">
|
||||
<form method="post" id="pcfb-delete-form">
|
||||
<?php wp_nonce_field( 'pcfb_admin_action', '_wpnonce' ); ?>
|
||||
<input type="hidden" name="pcfb_action" value="delete_form">
|
||||
<input type="hidden" name="form_id" id="pcfb-delete-form-id" value="">
|
||||
<button type="button" class="button pcfb-modal-cancel"><?php esc_html_e( 'Cancel', 'pc-form-builder-xyz123' ); ?></button>
|
||||
<button type="submit" class="button button-primary"><?php esc_html_e( 'Delete Form', 'pc-form-builder-xyz123' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
function pcfb_get_field_count( $form_id ) {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'pcfb_fields';
|
||||
return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE form_id = %d", $form_id ) );
|
||||
}
|
||||
?>
|
||||
199
chat/templates/Form Builder/admin/page-form-builder.php
Normal file
199
chat/templates/Form Builder/admin/page-form-builder.php
Normal file
@@ -0,0 +1,199 @@
|
||||
<div class="wrap pcfb-wrap">
|
||||
<h1 class="wp-heading-inline">
|
||||
<span class="pcfb-heading-icon dashicons dashicons-feedback"></span>
|
||||
<?php esc_html_e( 'Form Builder', 'pc-form-builder-xyz123' ); ?>
|
||||
</h1>
|
||||
<a href="<?php echo admin_url( 'admin.php?page=pcfb-all-forms' ); ?>" class="page-title-action">
|
||||
<span class="dashicons dashicons-list-view"></span>
|
||||
<?php esc_html_e( 'All Forms', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<?php
|
||||
require_once PCFB_PLUGIN_DIR . 'admin/class-admin-helper.php';
|
||||
$helper = PCFB_Admin_Helper::get_instance();
|
||||
|
||||
$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;
|
||||
$is_new = $form_id === 0;
|
||||
|
||||
if ( ! $is_new ) {
|
||||
$form = PC_Form_Handler::get_form_by_id( $form_id );
|
||||
if ( ! $form ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Form not found.', 'pc-form-builder-xyz123' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
$fields = $helper->get_form_fields( $form_id );
|
||||
$settings = maybe_unserialize( $form->settings );
|
||||
} else {
|
||||
$form = (object) array(
|
||||
'id' => 0,
|
||||
'name' => '',
|
||||
'description' => '',
|
||||
'status' => 'active',
|
||||
'settings' => array(),
|
||||
);
|
||||
$fields = array();
|
||||
$settings = array();
|
||||
}
|
||||
|
||||
$field_types = $helper->get_field_types();
|
||||
?>
|
||||
|
||||
<?php if ( ! $is_new ) : ?>
|
||||
<div class="pcfb-shortcode-notice" style="background: #f0f0f1; border: 1px solid #c3c4c7; border-radius: 6px; padding: 15px 20px; margin-bottom: 20px; display: flex; align-items: center; gap: 15px;">
|
||||
<span class="dashicons dashicons-shortcode" style="color: #2271b1; font-size: 24px; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;"></span>
|
||||
<div style="flex: 1;">
|
||||
<strong style="display: block; margin-bottom: 4px;"><?php esc_html_e( 'Form Shortcode', 'pc-form-builder-xyz123' ); ?></strong>
|
||||
<code onclick="this.select(); document.execCommand('copy');" style="background: #fff; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-size: 14px; display: inline-block;">[pcfb-form id="<?php echo esc_attr( $form->id ); ?>"]</code>
|
||||
<span class="description" style="display: block; margin-top: 4px; font-size: 12px;"><?php esc_html_e( 'Click the shortcode to copy it', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" id="pcfb-form-builder" class="pcfb-form-builder">
|
||||
<?php wp_nonce_field( 'pcfb_admin_action', '_wpnonce' ); ?>
|
||||
<input type="hidden" name="pcfb_action" value="save_form">
|
||||
<input type="hidden" name="form[id]" value="<?php echo esc_attr( $form->id ); ?>">
|
||||
|
||||
<div class="pcfb-builder-layout">
|
||||
<div class="pcfb-builder-main">
|
||||
<div class="pcfb-card pcfb-form-settings-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Form Details', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<div class="pcfb-form-group">
|
||||
<label for="form-name"><?php esc_html_e( 'Form Name', 'pc-form-builder-xyz123' ); ?> *</label>
|
||||
<input type="text" id="form-name" name="form[name]" value="<?php echo esc_attr( $form->name ); ?>" required placeholder="<?php esc_attr_e( 'Enter form name', 'pc-form-builder-xyz123' ); ?>">
|
||||
</div>
|
||||
<div class="pcfb-form-group">
|
||||
<label for="form-description"><?php esc_html_e( 'Description', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<textarea id="form-description" name="form[description]" rows="2" placeholder="<?php esc_attr_e( 'Brief description of this form', 'pc-form-builder-xyz123' ); ?>"><?php echo esc_textarea( $form->description ); ?></textarea>
|
||||
</div>
|
||||
<div class="pcfb-form-group">
|
||||
<label for="form-status"><?php esc_html_e( 'Status', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<select id="form-status" name="form[status]">
|
||||
<option value="active" <?php selected( $form->status, 'active' ); ?>><?php esc_html_e( 'Active', 'pc-form-builder-xyz123' ); ?></option>
|
||||
<option value="inactive" <?php selected( $form->status, 'inactive' ); ?>><?php esc_html_e( 'Inactive', 'pc-form-builder-xyz123' ); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-card pcfb-fields-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Form Fields', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-field-types-section">
|
||||
<h3><?php esc_html_e( 'Add Fields to Your Form', 'pc-form-builder-xyz123' ); ?></h3>
|
||||
<p class="description"><?php esc_html_e( 'Click on any field type below to add it to your form. You can then customize the label, placeholder, and other options.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<div class="pcfb-field-type-buttons">
|
||||
<?php foreach ( $field_types as $type => $label ) : ?>
|
||||
<button type="button" class="pcfb-add-field-btn" data-field-type="<?php echo esc_attr( $type ); ?>">
|
||||
<span class="dashicons <?php echo esc_attr( PCFB_Field_Icons::get_field_icon( $type ) ); ?>"></span>
|
||||
<span class="pcfb-field-label"><?php echo esc_html( $label ); ?></span>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-form-fields">
|
||||
<h3><?php esc_html_e( 'Form Structure', 'pc-form-builder-xyz123' ); ?></h3>
|
||||
<p class="description"><?php esc_html_e( 'Drag and drop fields to reorder them. Click on a field to expand and edit its properties.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<div id="pcfb-fields-container" class="pcfb-fields-container">
|
||||
<?php if ( empty( $fields ) ) : ?>
|
||||
<div class="pcfb-empty-fields">
|
||||
<span class="dashicons dashicons-plus-alt2 pcfb-empty-icon"></span>
|
||||
<p><?php esc_html_e( 'No fields added yet.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<p class="description"><?php esc_html_e( 'Click a field type above to start building your form.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<?php foreach ( $fields as $index => $field ) : ?>
|
||||
<?php echo $helper->render_field_item( $field, $index ); ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-card pcfb-sections-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Form Sections', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<p class="description"><?php esc_html_e( 'Organize your form fields into sections for better user experience.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<div id="pcfb-sections-container" class="pcfb-sections-container">
|
||||
<div class="pcfb-section-box pcfb-default-section">
|
||||
<div class="pcfb-section-header">
|
||||
<span class="dashicons dashicons-menu"></span>
|
||||
<span class="pcfb-section-title"><?php esc_html_e( 'Default Section', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
<div class="pcfb-section-content">
|
||||
<p class="description"><?php esc_html_e( 'All fields are placed in this default section by default. You can add section breaks between fields.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="button pcfb-add-section-btn" id="pcfb-add-section">
|
||||
<span class="dashicons dashicons-plus"></span>
|
||||
<?php esc_html_e( 'Add Section', 'pc-form-builder-xyz123' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-builder-sidebar">
|
||||
<div class="pcfb-card pcfb-publish-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Publish', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<button type="submit" class="button button-primary button-large pcfb-save-btn">
|
||||
<span class="dashicons dashicons-saved"></span>
|
||||
<?php esc_html_e( 'Save Form', 'pc-form-builder-xyz123' ); ?>
|
||||
</button>
|
||||
<a href="<?php echo admin_url( 'admin.php?page=pcfb-all-forms' ); ?>" class="button button-large">
|
||||
<?php esc_html_e( 'Cancel', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-card pcfb-settings-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Form Settings', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<div class="pcfb-form-group">
|
||||
<label for="form-success-message"><?php esc_html_e( 'Success Message', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<textarea id="form-success-message" name="form[settings][success_message]" rows="3" placeholder="<?php esc_attr_e( 'Thank you! Your response has been submitted.', 'pc-form-builder-xyz123' ); ?>"><?php echo isset( $settings['success_message'] ) ? esc_textarea( $settings['success_message'] ) : ''; ?></textarea>
|
||||
</div>
|
||||
<div class="pcfb-form-group">
|
||||
<label for="form-submit-text"><?php esc_html_e( 'Submit Button Text', 'pc-form-builder-xyz123' ); ?></label>
|
||||
<input type="text" id="form-submit-text" name="form[settings][submit_text]" value="<?php echo isset( $settings['submit_text'] ) ? esc_attr( $settings['submit_text'] ) : __( 'Submit', 'pc-form-builder-xyz123' ); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-card pcfb-help-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Quick Tips', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<p><strong><?php esc_html_e( 'Available Field Types:', 'pc-form-builder-xyz123' ); ?></strong></p>
|
||||
<ul>
|
||||
<li><span class="dashicons dashicons-text"></span> <strong><?php esc_html_e( 'Text', 'pc-form-builder-xyz123' ); ?></strong> - <?php esc_html_e( 'Single line text input', 'pc-form-builder-xyz123' ); ?></li>
|
||||
<li><span class="dashicons dashicons-email"></span> <strong><?php esc_html_e( 'Email', 'pc-form-builder-xyz123' ); ?></strong> - <?php esc_html_e( 'Email address with validation', 'pc-form-builder-xyz123' ); ?></li>
|
||||
<li><span class="dashicons dashicons-admin-users"></span> <strong><?php esc_html_e( 'Name', 'pc-form-builder-xyz123' ); ?></strong> - <?php esc_html_e( 'Full name field', 'pc-form-builder-xyz123' ); ?></li>
|
||||
<li><span class="dashicons dashicons-editor-quote"></span> <strong><?php esc_html_e( 'Response', 'pc-form-builder-xyz123' ); ?></strong> - <?php esc_html_e( 'Multi-line textarea for responses', 'pc-form-builder-xyz123' ); ?></li>
|
||||
<li><span class="dashicons dashicons-arrow-down-alt2"></span> <strong><?php esc_html_e( 'Dropdown', 'pc-form-builder-xyz123' ); ?></strong> - <?php esc_html_e( 'Select from predefined options', 'pc-form-builder-xyz123' ); ?></li>
|
||||
<li><span class="dashicons dashicons-yes"></span> <strong><?php esc_html_e( 'Checkbox', 'pc-form-builder-xyz123' ); ?></strong> - <?php esc_html_e( 'Checkbox options', 'pc-form-builder-xyz123' ); ?></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<p><?php esc_html_e( 'After saving, use the shortcode to embed this form on any page or post.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
111
chat/templates/Form Builder/admin/page-form-responses.php
Normal file
111
chat/templates/Form Builder/admin/page-form-responses.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<div class="wrap pcfb-wrap">
|
||||
<?php
|
||||
$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;
|
||||
|
||||
if ( empty( $form_id ) ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Form ID is required.', 'pc-form-builder-xyz123' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$form = PC_Form_Handler::get_form_by_id( $form_id );
|
||||
|
||||
if ( ! $form ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Form not found.', 'pc-form-builder-xyz123' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$paged = isset( $_GET['paged'] ) ? max( 1, intval( $_GET['paged'] ) ) : 1;
|
||||
$per_page = 20;
|
||||
$offset = ( $paged - 1 ) * $per_page;
|
||||
|
||||
$responses = PC_Form_Handler::get_form_responses( $form_id, array(
|
||||
'limit' => $per_page,
|
||||
'offset' => $offset,
|
||||
) );
|
||||
|
||||
$total_responses = PC_Form_Handler::get_form_response_count( $form_id );
|
||||
$total_pages = ceil( $total_responses / $per_page );
|
||||
?>
|
||||
|
||||
<h1 class="wp-heading-inline">
|
||||
<a href="<?php echo admin_url( 'admin.php?page=pcfb-responses' ); ?>" class="pcfb-back-link">
|
||||
<span class="dashicons dashicons-arrow-left-alt2"></span>
|
||||
</a>
|
||||
<span class="pcfb-heading-icon dashicons dashicons-pressthis"></span>
|
||||
<?php echo esc_html( $form->name ); ?> - <?php esc_html_e( 'Responses', 'pc-form-builder-xyz123' ); ?>
|
||||
</h1>
|
||||
|
||||
<span class="title-ext">
|
||||
<?php echo esc_html( $total_responses . ' ' . _n( 'Response', 'Responses', $total_responses, 'pc-form-builder-xyz123' ) ); ?>
|
||||
</span>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<div class="pcfb-form-responses-page">
|
||||
<?php if ( empty( $responses ) ) : ?>
|
||||
<div class="pcfb-empty-state">
|
||||
<span class="dashicons dashicons-pressthis pcfb-empty-icon"></span>
|
||||
<h3><?php esc_html_e( 'No responses yet', 'pc-form-builder-xyz123' ); ?></h3>
|
||||
<p><?php esc_html_e( 'This form has not received any responses yet.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="pcfb-responses-header">
|
||||
<div class="pcfb-response-count-badge">
|
||||
<span class="dashicons dashicons-pressthis"></span>
|
||||
<?php echo esc_html( $total_responses . ' ' . _n( 'Response', 'Responses', $total_responses, 'pc-form-builder-xyz123' ) ); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="widefat pcfb-table pcfb-responses-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'ID', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Submitted', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'IP Address', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Status', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<th><?php esc_html_e( 'Actions', 'pc-form-builder-xyz123' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ( $responses as $response ) : ?>
|
||||
<?php
|
||||
$detail_url = admin_url( 'admin.php?page=pcfb-responses&form_id=' . $form_id . '&response_id=' . $response->id );
|
||||
$status_class = 'new' === $response->status ? 'status-new' : 'status-read';
|
||||
$status_label = 'new' === $response->status ? __( 'New', 'pc-form-builder-xyz123' ) : __( 'Read', 'pc-form-builder-xyz123' );
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo esc_html( $response->id ); ?></td>
|
||||
<td><?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $response->created_at ) ) ); ?></td>
|
||||
<td><?php echo esc_html( $response->user_ip ); ?></td>
|
||||
<td>
|
||||
<span class="pcfb-status <?php echo esc_attr( $status_class ); ?>">
|
||||
<?php echo esc_html( $status_label ); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo esc_url( $detail_url ); ?>" class="button button-small">
|
||||
<?php esc_html_e( 'View Details', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php if ( $total_pages > 1 ) : ?>
|
||||
<div class="pcfb-pagination">
|
||||
<?php
|
||||
echo paginate_links( array(
|
||||
'base' => admin_url( 'admin.php?page=pcfb-responses&form_id=' . $form_id . '&paged=%#%' ),
|
||||
'format' => '',
|
||||
'prev_text' => __( '« Previous', 'pc-form-builder-xyz123' ),
|
||||
'next_text' => __( 'Next »', 'pc-form-builder-xyz123' ),
|
||||
'total' => $total_pages,
|
||||
'current' => $paged,
|
||||
) );
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
118
chat/templates/Form Builder/admin/page-response-detail.php
Normal file
118
chat/templates/Form Builder/admin/page-response-detail.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<div class="wrap pcfb-wrap">
|
||||
<?php
|
||||
$form_id = isset( $_GET['form_id'] ) ? intval( $_GET['form_id'] ) : 0;
|
||||
$response_id = isset( $_GET['response_id'] ) ? intval( $_GET['response_id'] ) : 0;
|
||||
|
||||
if ( empty( $form_id ) || empty( $response_id ) ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Invalid request.', 'pc-form-builder-xyz123' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$form = PC_Form_Handler::get_form_by_id( $form_id );
|
||||
|
||||
if ( ! $form ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Form not found.', 'pc-form-builder-xyz123' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$response_data = PC_Form_Handler::get_response_data( $response_id );
|
||||
|
||||
if ( empty( $response_data ) ) {
|
||||
echo '<div class="notice notice-error"><p>' . esc_html__( 'Response not found.', 'pc-form-builder-xyz123' ) . '</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
$back_url = admin_url( 'admin.php?page=pcfb-responses&form_id=' . $form_id );
|
||||
$response_meta = pcfb_get_response_meta( $response_id );
|
||||
?>
|
||||
|
||||
<h1 class="wp-heading-inline">
|
||||
<a href="<?php echo esc_url( $back_url ); ?>" class="pcfb-back-link">
|
||||
<span class="dashicons dashicons-arrow-left-alt2"></span>
|
||||
</a>
|
||||
<span class="pcfb-heading-icon dashicons dashicons-pressthis"></span>
|
||||
<?php esc_html_e( 'Response Details', 'pc-form-builder-xyz123' ); ?>
|
||||
</h1>
|
||||
|
||||
<span class="title-ext">
|
||||
<?php esc_html_e( 'Response #', 'pc-form-builder-xyz123' ); ?><?php echo esc_html( $response_id ); ?>
|
||||
</span>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<div class="pcfb-response-detail-page">
|
||||
<div class="pcfb-response-meta">
|
||||
<div class="pcfb-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Response Information', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<table class="widefat pcfb-meta-table">
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Form:', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<td><?php echo esc_html( $form->name ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'Submitted:', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<td><?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $response_meta['created_at'] ) ) ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'IP Address:', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<td><?php echo esc_html( $response_meta['user_ip'] ); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php esc_html_e( 'User Agent:', 'pc-form-builder-xyz123' ); ?></th>
|
||||
<td><?php echo esc_html( $response_meta['user_agent'] ); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-response-content">
|
||||
<div class="pcfb-card">
|
||||
<div class="pcfb-card-header">
|
||||
<h2><?php esc_html_e( 'Submitted Data', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
</div>
|
||||
<div class="pcfb-card-body">
|
||||
<?php foreach ( $response_data as $data ) : ?>
|
||||
<div class="pcfb-response-field">
|
||||
<div class="pcfb-response-field-label">
|
||||
<?php echo esc_html( $data->field_label ); ?>
|
||||
</div>
|
||||
<div class="pcfb-response-field-value">
|
||||
<?php
|
||||
if ( 'checkbox' === $data->field_type ) {
|
||||
$options = maybe_unserialize( $data->field_value );
|
||||
if ( is_array( $options ) ) {
|
||||
echo esc_html( implode( ', ', $options ) );
|
||||
} else {
|
||||
echo esc_html( $data->field_value );
|
||||
}
|
||||
} elseif ( 'response' === $data->field_type ) {
|
||||
echo wpautop( esc_html( $data->field_value ) );
|
||||
} else {
|
||||
echo esc_html( $data->field_value );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
function pcfb_get_response_meta( $response_id ) {
|
||||
global $wpdb;
|
||||
$table_name = $wpdb->prefix . 'pcfb_responses';
|
||||
$response = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d", $response_id ), ARRAY_A );
|
||||
return $response ? $response : array(
|
||||
'user_ip' => '',
|
||||
'user_agent' => '',
|
||||
'created_at' => '',
|
||||
);
|
||||
}
|
||||
?>
|
||||
74
chat/templates/Form Builder/admin/page-responses.php
Normal file
74
chat/templates/Form Builder/admin/page-responses.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<div class="wrap pcfb-wrap">
|
||||
<h1 class="wp-heading-inline">
|
||||
<span class="pcfb-heading-icon dashicons dashicons-pressthis"></span>
|
||||
<?php esc_html_e( 'Form Responses', 'pc-form-builder-xyz123' ); ?>
|
||||
</h1>
|
||||
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<?php
|
||||
$forms = PC_Form_Handler::get_forms( array( 'limit' => 100 ) );
|
||||
?>
|
||||
|
||||
<div class="pcfb-responses-page">
|
||||
<?php if ( empty( $forms ) ) : ?>
|
||||
<div class="pcfb-empty-state">
|
||||
<span class="dashicons dashicons-pressthis pcfb-empty-icon"></span>
|
||||
<h3><?php esc_html_e( 'No forms to show responses', 'pc-form-builder-xyz123' ); ?></h3>
|
||||
<p><?php esc_html_e( 'Create a form first to start collecting and viewing responses.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<a href="<?php echo admin_url( 'admin.php?page=pcfb-form-builder&form_id=new' ); ?>" class="button button-primary">
|
||||
<?php esc_html_e( 'Create a Form', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="pcfb-responses-overview">
|
||||
<h2><?php esc_html_e( 'Select a Form', 'pc-form-builder-xyz123' ); ?></h2>
|
||||
<p class="description"><?php esc_html_e( 'Choose a form to view its responses.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
|
||||
<div class="pcfb-forms-select-list">
|
||||
<?php foreach ( $forms as $form ) : ?>
|
||||
<?php
|
||||
$response_count = PC_Form_Handler::get_form_response_count( $form->id );
|
||||
$view_url = admin_url( 'admin.php?page=pcfb-responses&form_id=' . $form->id );
|
||||
$status_class = 'active' === $form->status ? 'status-active' : 'status-inactive';
|
||||
?>
|
||||
<div class="pcfb-form-select-item">
|
||||
<div class="pcfb-form-select-info">
|
||||
<h3>
|
||||
<a href="<?php echo esc_url( $view_url ); ?>">
|
||||
<?php echo esc_html( $form->name ); ?>
|
||||
</a>
|
||||
</h3>
|
||||
<span class="pcfb-status <?php echo esc_attr( $status_class ); ?>">
|
||||
<?php echo esc_html( 'active' === $form->status ? __( 'Active', 'pc-form-builder-xyz123' ) : __( 'Inactive', 'pc-form-builder-xyz123' ) ); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="pcfb-form-select-stats">
|
||||
<span class="pcfb-response-count">
|
||||
<strong><?php echo esc_html( $response_count ); ?></strong>
|
||||
<?php echo _n( 'Response', 'Responses', $response_count, 'pc-form-builder-xyz123' ); ?>
|
||||
</span>
|
||||
<a href="<?php echo esc_url( $view_url ); ?>" class="button button-small">
|
||||
<?php esc_html_e( 'View Responses', 'pc-form-builder-xyz123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-total-responses">
|
||||
<?php
|
||||
$total_responses = 0;
|
||||
foreach ( $forms as $form ) {
|
||||
$total_responses += PC_Form_Handler::get_form_response_count( $form->id );
|
||||
}
|
||||
?>
|
||||
<div class="pcfb-total-card">
|
||||
<span class="pcfb-total-number"><?php echo esc_html( $total_responses ); ?></span>
|
||||
<span class="pcfb-total-label"><?php esc_html_e( 'Total Responses Across All Forms', 'pc-form-builder-xyz123' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
131
chat/templates/Form Builder/includes/class-db-migration.php
Normal file
131
chat/templates/Form Builder/includes/class-db-migration.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* Database Migration Class
|
||||
*
|
||||
* Handles creation and management of database tables for forms and responses.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
class PC_DB_Migration {
|
||||
|
||||
private static $charset_collate = '';
|
||||
|
||||
public static function activate() {
|
||||
self::set_charset();
|
||||
self::create_forms_table();
|
||||
self::create_fields_table();
|
||||
self::create_responses_table();
|
||||
self::create_response_data_table();
|
||||
|
||||
update_option( 'pcfb_version', PCFB_VERSION );
|
||||
}
|
||||
|
||||
public static function deactivate() {
|
||||
// Cleanup if needed
|
||||
}
|
||||
|
||||
private static function set_charset() {
|
||||
global $wpdb;
|
||||
self::$charset_collate = $wpdb->get_charset_collate();
|
||||
}
|
||||
|
||||
private static function create_forms_table() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'pcfb_forms';
|
||||
|
||||
$sql = "CREATE TABLE {$table_name} (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
settings longtext NOT NULL,
|
||||
status varchar(20) DEFAULT 'active' NOT NULL,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) " . self::$charset_collate . ";";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( $sql );
|
||||
}
|
||||
|
||||
private static function create_fields_table() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'pcfb_fields';
|
||||
|
||||
$sql = "CREATE TABLE {$table_name} (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
form_id mediumint(9) NOT NULL,
|
||||
field_type varchar(50) NOT NULL,
|
||||
field_label varchar(255) NOT NULL,
|
||||
field_name varchar(255) NOT NULL,
|
||||
placeholder varchar(255) DEFAULT '',
|
||||
options longtext DEFAULT NULL,
|
||||
validation_rules longtext DEFAULT NULL,
|
||||
sort_order mediumint(9) DEFAULT 0 NOT NULL,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY form_id (form_id)
|
||||
) " . self::$charset_collate . ";";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( $sql );
|
||||
}
|
||||
|
||||
private static function create_responses_table() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'pcfb_responses';
|
||||
|
||||
$sql = "CREATE TABLE {$table_name} (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
form_id mediumint(9) NOT NULL,
|
||||
user_ip varchar(100) DEFAULT '',
|
||||
user_agent text DEFAULT '',
|
||||
status varchar(20) DEFAULT 'new' NOT NULL,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY form_id (form_id)
|
||||
) " . self::$charset_collate . ";";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( $sql );
|
||||
}
|
||||
|
||||
private static function create_response_data_table() {
|
||||
global $wpdb;
|
||||
|
||||
$table_name = $wpdb->prefix . 'pcfb_response_data';
|
||||
|
||||
$sql = "CREATE TABLE {$table_name} (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
response_id mediumint(9) NOT NULL,
|
||||
field_id mediumint(9) NOT NULL,
|
||||
field_value longtext NOT NULL,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY response_id (response_id),
|
||||
KEY field_id (field_id)
|
||||
) " . self::$charset_collate . ";";
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
dbDelta( $sql );
|
||||
}
|
||||
|
||||
public static function drop_tables() {
|
||||
global $wpdb;
|
||||
|
||||
$tables = array(
|
||||
$wpdb->prefix . 'pcfb_response_data',
|
||||
$wpdb->prefix . 'pcfb_responses',
|
||||
$wpdb->prefix . 'pcfb_fields',
|
||||
$wpdb->prefix . 'pcfb_forms',
|
||||
);
|
||||
|
||||
foreach ( $tables as $table ) {
|
||||
$wpdb->query( "DROP TABLE IF EXISTS {$table}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
402
chat/templates/Form Builder/includes/class-form-handler.php
Normal file
402
chat/templates/Form Builder/includes/class-form-handler.php
Normal file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
/**
|
||||
* Form Handler Class
|
||||
*
|
||||
* Handles form submission, validation, and storage.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
class PC_Form_Handler {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function __construct() {
|
||||
add_action( 'wp_ajax_pcfb_submit_form', array( $this, 'handle_form_submission' ) );
|
||||
add_action( 'wp_ajax_nopriv_pcfb_submit_form', array( $this, 'handle_form_submission' ) );
|
||||
add_action( 'wp_ajax_pcfb_add_field', array( $this, 'handle_add_field' ) );
|
||||
add_shortcode( 'pcfb-form', array( $this, 'shortcode_form' ) );
|
||||
}
|
||||
|
||||
public function handle_add_field() {
|
||||
check_ajax_referer( 'pcfb_admin_nonce', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error( array( 'message' => __( '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 '<p>' . esc_html__( 'Form ID is required.', 'pc-form-builder-xyz123' ) . '</p>';
|
||||
}
|
||||
|
||||
$form = $this->get_form( intval( $atts['id'] ) );
|
||||
|
||||
if ( ! $form ) {
|
||||
return '<p>' . esc_html__( 'Form not found.', 'pc-form-builder-xyz123' ) . '</p>';
|
||||
}
|
||||
|
||||
if ( 'active' !== $form->status ) {
|
||||
return '<p>' . esc_html__( 'This form is not currently active.', 'pc-form-builder-xyz123' ) . '</p>';
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
10
chat/templates/Form Builder/opencode.json
Normal file
10
chat/templates/Form Builder/opencode.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"permission": {
|
||||
"external_directory": {
|
||||
"*": "deny",
|
||||
"*/fir-qa0i/*": "allow",
|
||||
"apps/c7f9e5c6-e7c2-4258-a583-ccffcf9791c8/fir-qa0i/*": "allow"
|
||||
}
|
||||
}
|
||||
}
|
||||
128
chat/templates/Form Builder/pc-form-builder-xyz123.php
Normal file
128
chat/templates/Form Builder/pc-form-builder-xyz123.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: Plugin Compass Form Builder
|
||||
* Plugin URI: https://plugincompass.com/plugins/pc-form-builder-xyz123
|
||||
* Update URI: false
|
||||
* Description: A complete form builder plugin with form builder, all forms management, and responses tracking.
|
||||
* Version: 1.0.0
|
||||
* Author: Plugin Compass
|
||||
* Author URI: https://plugincompass.com
|
||||
* Text Domain: pc-form-builder-xyz123
|
||||
* Domain Path: /languages
|
||||
* License: GPL v2 or later
|
||||
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
define( 'PCFB_VERSION', '1.0.0' );
|
||||
define( 'PCFB_PLUGIN_FILE', __FILE__ );
|
||||
define( 'PCFB_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
|
||||
define( 'PCFB_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||
define( 'PCFB_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||
|
||||
require_once PCFB_PLUGIN_DIR . 'includes/class-db-migration.php';
|
||||
require_once PCFB_PLUGIN_DIR . 'includes/class-form-handler.php';
|
||||
require_once PCFB_PLUGIN_DIR . 'admin/admin-menu.php';
|
||||
|
||||
class PC_Form_Builder {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance() {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function __construct() {
|
||||
add_action( 'init', array( $this, 'init' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_public_assets' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) );
|
||||
}
|
||||
|
||||
public function init() {
|
||||
load_plugin_textdomain( 'pc-form-builder-xyz123', false, dirname( PCFB_PLUGIN_BASENAME ) . '/languages' );
|
||||
|
||||
PC_Form_Handler::get_instance();
|
||||
PCFB_Admin_Menu::get_instance();
|
||||
}
|
||||
|
||||
public function enqueue_public_assets() {
|
||||
wp_enqueue_style(
|
||||
'pcfb-public-style',
|
||||
PCFB_PLUGIN_URL . 'public/css/public-style.css',
|
||||
array(),
|
||||
PCFB_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'pcfb-public-script',
|
||||
PCFB_PLUGIN_URL . 'public/js/public-script.js',
|
||||
array( 'jquery' ),
|
||||
PCFB_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script( 'pcfb-public-script', 'pcfbVars', array(
|
||||
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'pcfb_public_nonce' ),
|
||||
) );
|
||||
}
|
||||
|
||||
public function enqueue_admin_assets() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( 'toplevel_page_pcfb-form-builder' === $screen->id ||
|
||||
'form-builder_page_pcfb-all-forms' === $screen->id ||
|
||||
'form-builder_page_pcfb-responses' === $screen->id ) {
|
||||
|
||||
wp_enqueue_style(
|
||||
'pcfb-admin-style',
|
||||
PCFB_PLUGIN_URL . 'admin/css/admin-style.css',
|
||||
array(),
|
||||
PCFB_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'pcfb-admin-script',
|
||||
PCFB_PLUGIN_URL . 'admin/js/admin-script.js',
|
||||
array( 'jquery', 'jquery-ui-sortable', 'jquery-ui-draggable' ),
|
||||
PCFB_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script( 'pcfb-admin-script', 'pcfbAdminVars', array(
|
||||
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'pcfb_admin_nonce' ),
|
||||
'i18n' => array(
|
||||
'confirmDelete' => __( 'Are you sure you want to delete this form?', 'pc-form-builder-xyz123' ),
|
||||
'confirmDeleteField' => __( 'Are you sure you want to delete this field?', 'pc-form-builder-xyz123' ),
|
||||
'fieldLabel' => __( 'Field Label', 'pc-form-builder-xyz123' ),
|
||||
'fieldPlaceholder' => __( 'Placeholder text', 'pc-form-builder-xyz123' ),
|
||||
'required' => __( 'Required', 'pc-form-builder-xyz123' ),
|
||||
'delete' => __( 'Delete', 'pc-form-builder-xyz123' ),
|
||||
),
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
register_activation_hook( __FILE__, array( 'PC_DB_Migration', 'activate' ) );
|
||||
register_deactivation_hook( __FILE__, array( 'PC_DB_Migration', 'deactivate' ) );
|
||||
register_uninstall_hook( __FILE__, array( 'PC_Form_Builder', 'uninstall' ) );
|
||||
|
||||
add_action( 'plugins_loaded', array( 'PC_Form_Builder', 'get_instance' ) );
|
||||
|
||||
add_filter( 'site_transient_update_plugins', function( $value ) {
|
||||
$plugin_file = plugin_basename( __FILE__ );
|
||||
if ( isset( $value->response[ $plugin_file ] ) ) {
|
||||
unset( $value->response[ $plugin_file ] );
|
||||
}
|
||||
return $value;
|
||||
} );
|
||||
528
chat/templates/Form Builder/public/css/public-style.css
Normal file
528
chat/templates/Form Builder/public/css/public-style.css
Normal file
@@ -0,0 +1,528 @@
|
||||
/**
|
||||
* PC Form Builder Public Styles
|
||||
*
|
||||
* Frontend styling for the form builder plugin.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
/* CSS Variables */
|
||||
:root {
|
||||
--pcfb-primary: #2271b1;
|
||||
--pcfb-primary-dark: #135e96;
|
||||
--pcfb-primary-light: #72aee6;
|
||||
--pcfb-success: #00a32a;
|
||||
--pcfb-success-light: #dcfce1;
|
||||
--pcfb-danger: #d63638;
|
||||
--pcfb-danger-light: #fbe9e9;
|
||||
--pcfb-warning: #dba617;
|
||||
--pcfb-warning-light: #fff9c4;
|
||||
--pcfb-text: #3c434a;
|
||||
--pcfb-text-light: #6c7781;
|
||||
--pcfb-bg: #ffffff;
|
||||
--pcfb-bg-light: #f6f7f7;
|
||||
--pcfb-border: #e1e2e3;
|
||||
--pcfb-border-radius: 6px;
|
||||
--pcfb-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
--pcfb-transition: all 0.2s ease;
|
||||
--pcfb-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
/* Reset & Base */
|
||||
.pcfb-form-wrapper {
|
||||
font-family: var(--pcfb-font-family);
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
color: var(--pcfb-text);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pcfb-form-wrapper *,
|
||||
.pcfb-form-wrapper *::before,
|
||||
.pcfb-form-wrapper *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
.pcfb-form-container {
|
||||
background: var(--pcfb-bg);
|
||||
border: 1px solid var(--pcfb-border);
|
||||
border-radius: var(--pcfb-border-radius);
|
||||
box-shadow: var(--pcfb-box-shadow);
|
||||
padding: 30px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Form Header */
|
||||
.pcfb-form-header {
|
||||
margin-bottom: 25px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid var(--pcfb-border);
|
||||
}
|
||||
|
||||
.pcfb-form-title {
|
||||
margin: 0 0 10px;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--pcfb-text);
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.pcfb-form-description {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
color: var(--pcfb-text-light);
|
||||
}
|
||||
|
||||
/* Form Fields */
|
||||
.pcfb-form-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.pcfb-form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.pcfb-label {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--pcfb-text);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.pcfb-required {
|
||||
color: var(--pcfb-danger);
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
/* Input Styles */
|
||||
.pcfb-input,
|
||||
.pcfb-textarea,
|
||||
.pcfb-select {
|
||||
width: 100%;
|
||||
padding: 12px 15px;
|
||||
font-family: inherit;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
color: var(--pcfb-text);
|
||||
background-color: var(--pcfb-bg);
|
||||
border: 1px solid var(--pcfb-border);
|
||||
border-radius: var(--pcfb-border-radius);
|
||||
transition: var(--pcfb-transition);
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.pcfb-input:focus,
|
||||
.pcfb-textarea:focus,
|
||||
.pcfb-select:focus {
|
||||
outline: none;
|
||||
border-color: var(--pcfb-primary);
|
||||
box-shadow: 0 0 0 3px rgba(34, 113, 177, 0.15);
|
||||
}
|
||||
|
||||
.pcfb-input::placeholder,
|
||||
.pcfb-textarea::placeholder {
|
||||
color: var(--pcfb-text-light);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.pcfb-textarea {
|
||||
resize: vertical;
|
||||
min-height: 100px;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
.pcfb-select {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236c7781' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 15px center;
|
||||
padding-right: 40px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Checkbox Styles */
|
||||
.pcfb-checkbox-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.pcfb-checkbox-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: var(--pcfb-text);
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.pcfb-checkbox-label:hover .pcfb-checkbox-text {
|
||||
color: var(--pcfb-primary);
|
||||
}
|
||||
|
||||
.pcfb-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
accent-color: var(--pcfb-primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pcfb-checkbox:checked + .pcfb-checkbox-text {
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
.pcfb-checkbox-text {
|
||||
transition: var(--pcfb-transition);
|
||||
}
|
||||
|
||||
/* Form Footer */
|
||||
.pcfb-form-footer {
|
||||
margin-top: 30px;
|
||||
padding-top: 25px;
|
||||
border-top: 1px solid var(--pcfb-border);
|
||||
}
|
||||
|
||||
/* Submit Button */
|
||||
.pcfb-submit-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 14px 30px;
|
||||
font-family: inherit;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
background: var(--pcfb-primary);
|
||||
border: none;
|
||||
border-radius: var(--pcfb-border-radius);
|
||||
cursor: pointer;
|
||||
transition: var(--pcfb-transition);
|
||||
text-decoration: none;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.pcfb-submit-button:hover {
|
||||
background: var(--pcfb-primary-dark);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.pcfb-submit-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.pcfb-submit-button:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* Spinner */
|
||||
.pcfb-spinner {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: pcfb-spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes pcfb-spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Error Messages */
|
||||
.pcfb-field-error {
|
||||
display: none;
|
||||
margin-top: 6px;
|
||||
font-size: 13px;
|
||||
color: var(--pcfb-danger);
|
||||
}
|
||||
|
||||
.pcfb-form-group.error .pcfb-input,
|
||||
.pcfb-form-group.error .pcfb-textarea,
|
||||
.pcfb-form-group.error .pcfb-select {
|
||||
border-color: var(--pcfb-danger);
|
||||
background-color: var(--pcfb-danger-light);
|
||||
}
|
||||
|
||||
.pcfb-form-group.error .pcfb-field-error {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Success/Error Messages */
|
||||
.pcfb-form-message {
|
||||
margin-top: 20px;
|
||||
padding: 15px 20px;
|
||||
border-radius: var(--pcfb-border-radius);
|
||||
animation: pcfb-fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes pcfb-fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.pcfb-success-message {
|
||||
background-color: var(--pcfb-success-light);
|
||||
border: 1px solid var(--pcfb-success);
|
||||
}
|
||||
|
||||
.pcfb-error-message {
|
||||
background-color: var(--pcfb-danger-light);
|
||||
border: 1px solid var(--pcfb-danger);
|
||||
}
|
||||
|
||||
.pcfb-message-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.pcfb-message-icon {
|
||||
font-size: 24px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pcfb-success-message .pcfb-message-icon {
|
||||
color: var(--pcfb-success);
|
||||
}
|
||||
|
||||
.pcfb-error-message .pcfb-message-icon {
|
||||
color: var(--pcfb-danger);
|
||||
}
|
||||
|
||||
.pcfb-message-text {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
/* No Fields Message */
|
||||
.pcfb-no-fields {
|
||||
text-align: center;
|
||||
color: var(--pcfb-text-light);
|
||||
padding: 40px 20px;
|
||||
background: var(--pcfb-bg-light);
|
||||
border-radius: var(--pcfb-border-radius);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media screen and (max-width: 600px) {
|
||||
.pcfb-form-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.pcfb-form-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.pcfb-form-fields {
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.pcfb-input,
|
||||
.pcfb-textarea,
|
||||
.pcfb-select {
|
||||
padding: 10px 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.pcfb-submit-button {
|
||||
width: 100%;
|
||||
padding: 14px 20px;
|
||||
}
|
||||
|
||||
.pcfb-checkbox-label {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark Mode Support */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.pcfb-form-wrapper {
|
||||
--pcfb-text: #f0f0f1;
|
||||
--pcfb-text-light: #a0a5aa;
|
||||
--pcfb-bg: #1d2327;
|
||||
--pcfb-bg-light: #2c3338;
|
||||
--pcfb-border: #3c434a;
|
||||
--pcfb-border-radius: 6px;
|
||||
--pcfb-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.pcfb-form-container {
|
||||
background: var(--pcfb-bg);
|
||||
border-color: var(--pcfb-border);
|
||||
}
|
||||
|
||||
.pcfb-form-header {
|
||||
border-bottom-color: var(--pcfb-border);
|
||||
}
|
||||
|
||||
.pcfb-form-title {
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
.pcfb-form-description {
|
||||
color: var(--pcfb-text-light);
|
||||
}
|
||||
|
||||
.pcfb-label {
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
.pcfb-input,
|
||||
.pcfb-textarea,
|
||||
.pcfb-select {
|
||||
background-color: var(--pcfb-bg-light);
|
||||
border-color: var(--pcfb-border);
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
.pcfb-input::placeholder,
|
||||
.pcfb-textarea::placeholder {
|
||||
color: var(--pcfb-text-light);
|
||||
}
|
||||
|
||||
.pcfb-checkbox-label {
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
.pcfb-form-footer {
|
||||
border-top-color: var(--pcfb-border);
|
||||
}
|
||||
|
||||
.pcfb-message-text {
|
||||
color: var(--pcfb-text);
|
||||
}
|
||||
|
||||
.pcfb-no-fields {
|
||||
background: var(--pcfb-bg-light);
|
||||
color: var(--pcfb-text-light);
|
||||
}
|
||||
}
|
||||
|
||||
/* High Contrast Mode */
|
||||
@media (prefers-contrast: high) {
|
||||
.pcfb-form-container {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.pcfb-input,
|
||||
.pcfb-textarea,
|
||||
.pcfb-select {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.pcfb-submit-button {
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reduced Motion */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.pcfb-form-wrapper *,
|
||||
.pcfb-form-wrapper *::before,
|
||||
.pcfb-form-wrapper *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print Styles */
|
||||
@media print {
|
||||
.pcfb-form-wrapper {
|
||||
box-shadow: none;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.pcfb-form-container {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.pcfb-submit-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessibility Focus Styles */
|
||||
.pcfb-input:focus-visible,
|
||||
.pcfb-textarea:focus-visible,
|
||||
.pcfb-select:focus-visible,
|
||||
.pcfb-checkbox:focus-visible {
|
||||
outline: 2px solid var(--pcfb-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Validation Styles */
|
||||
.pcfb-input:invalid:not(:placeholder-shown),
|
||||
.pcfb-input.pattern-violation:not(:placeholder-shown) {
|
||||
border-color: var(--pcfb-danger);
|
||||
}
|
||||
|
||||
/* Loading State */
|
||||
.pcfb-form.loading .pcfb-submit-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pcfb-form.loading .pcfb-submit-loader {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.pcfb-form.loading .pcfb-submit-button {
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
/* Form Layout Variations */
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-form-group {
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-label {
|
||||
flex: 0 0 150px;
|
||||
padding-top: 12px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-input,
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-textarea,
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-select {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-form-group {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.pcfb-form-wrapper.pcfb-form-aligned .pcfb-label {
|
||||
flex: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
136
chat/templates/Form Builder/public/js/public-script.js
Normal file
136
chat/templates/Form Builder/public/js/public-script.js
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* PC Form Builder Public Scripts
|
||||
*
|
||||
* Frontend JavaScript functionality for form handling.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
var PCFB_Public = {
|
||||
init: function() {
|
||||
this.initForms();
|
||||
},
|
||||
|
||||
initForms: function() {
|
||||
var self = this;
|
||||
|
||||
$(document).on('submit', '.pcfb-form', function(e) {
|
||||
e.preventDefault();
|
||||
self.handleFormSubmit($(this));
|
||||
});
|
||||
},
|
||||
|
||||
handleFormSubmit: function($form) {
|
||||
var self = this;
|
||||
var formId = $form.data('form-id');
|
||||
var $submitButton = $form.find('.pcfb-submit-button');
|
||||
var $submitText = $form.find('.pcfb-submit-text');
|
||||
var $submitLoader = $form.find('.pcfb-submit-loader');
|
||||
var $successMessage = $form.closest('.pcfb-form-container').find('.pcfb-success-message');
|
||||
var $errorMessage = $form.closest('.pcfb-form-container').find('.pcfb-error-message');
|
||||
|
||||
$form.find('.pcfb-form-group').removeClass('error');
|
||||
$form.find('.pcfb-field-error').text('');
|
||||
$errorMessage.hide().find('.pcfb-message-text').text('');
|
||||
$successMessage.hide();
|
||||
|
||||
var formData = $form.serialize();
|
||||
var ajaxData = {
|
||||
action: 'pcfb_submit_form',
|
||||
form_id: formId,
|
||||
form_data: {},
|
||||
nonce: pcfbVars.nonce
|
||||
};
|
||||
|
||||
$form.find('input, textarea, select').each(function() {
|
||||
var $field = $(this);
|
||||
var name = $field.attr('name');
|
||||
if (name && name !== 'action' && name !== 'form_id' && name !== 'pcfb_nonce') {
|
||||
if ($field.is(':checkbox')) {
|
||||
if ($field.is(':checked')) {
|
||||
if (!ajaxData.form_data[name]) {
|
||||
ajaxData.form_data[name] = [];
|
||||
}
|
||||
ajaxData.form_data[name].push($field.val());
|
||||
}
|
||||
} else if ($field.is(':radio')) {
|
||||
if ($field.is(':checked')) {
|
||||
ajaxData.form_data[name] = $field.val();
|
||||
}
|
||||
} else {
|
||||
ajaxData.form_data[name] = $field.val();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$form.addClass('loading');
|
||||
$submitButton.prop('disabled', true);
|
||||
$submitText.hide();
|
||||
$submitLoader.show();
|
||||
|
||||
$.ajax({
|
||||
url: pcfbVars.ajaxurl,
|
||||
type: 'POST',
|
||||
data: ajaxData,
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
$form.removeClass('loading');
|
||||
$submitButton.prop('disabled', false);
|
||||
$submitText.show();
|
||||
$submitLoader.hide();
|
||||
|
||||
if (response.success) {
|
||||
$successMessage.find('.pcfb-message-text').text(response.data.message || 'Thank you!');
|
||||
$successMessage.show();
|
||||
$form.hide();
|
||||
|
||||
if (response.data.response_id) {
|
||||
console.log('Response ID:', response.data.response_id);
|
||||
}
|
||||
} else {
|
||||
if (response.data.errors) {
|
||||
$.each(response.data.errors, function(fieldName, errorMessage) {
|
||||
var $fieldGroup = $form.find('[name="' + fieldName + '"]').closest('.pcfb-form-group');
|
||||
if ($fieldGroup.length === 0) {
|
||||
$fieldGroup = $form.find('[name^="' + fieldName + '"]').closest('.pcfb-form-group');
|
||||
}
|
||||
if ($fieldGroup.length > 0) {
|
||||
$fieldGroup.addClass('error');
|
||||
$fieldGroup.find('.pcfb-field-error').text(errorMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var errorText = response.data.message || 'An error occurred. Please try again.';
|
||||
$errorMessage.find('.pcfb-message-text').text(errorText);
|
||||
$errorMessage.show();
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
$form.removeClass('loading');
|
||||
$submitButton.prop('disabled', false);
|
||||
$submitText.show();
|
||||
$submitLoader.hide();
|
||||
|
||||
var errorText = 'An error occurred. Please try again.';
|
||||
if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
|
||||
errorText = xhr.responseJSON.data.message;
|
||||
} else if (xhr.statusText) {
|
||||
errorText = xhr.statusText;
|
||||
}
|
||||
|
||||
$errorMessage.find('.pcfb-message-text').text(errorText);
|
||||
$errorMessage.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
PCFB_Public.init();
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
166
chat/templates/Form Builder/public/templates/form-display.php
Normal file
166
chat/templates/Form Builder/public/templates/form-display.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* Form Display Template
|
||||
*
|
||||
* Frontend template for displaying forms.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$form_id = ! empty( $form->id ) ? $form->id : 0;
|
||||
$form_name = ! empty( $form->name ) ? $form->name : '';
|
||||
$form_description = ! empty( $form->description ) ? $form->description : '';
|
||||
$submit_text = ! empty( $settings['submit_text'] ) ? $settings['submit_text'] : __( 'Submit', 'pc-form-builder-xyz123' );
|
||||
$success_message = ! empty( $settings['success_message'] ) ? $settings['success_message'] : __( 'Thank you! Your response has been submitted.', 'pc-form-builder-xyz123' );
|
||||
?>
|
||||
|
||||
<div class="pcfb-form-wrapper" id="pcfb-form-wrapper-<?php echo esc_attr( $form_id ); ?>">
|
||||
<div class="pcfb-form-container">
|
||||
<?php if ( ! empty( $form_name ) ) : ?>
|
||||
<div class="pcfb-form-header">
|
||||
<h2 class="pcfb-form-title"><?php echo esc_html( $form_name ); ?></h2>
|
||||
<?php if ( ! empty( $form_description ) ) : ?>
|
||||
<p class="pcfb-form-description"><?php echo esc_html( $form_description ); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form class="pcfb-form" id="pcfb-form-<?php echo esc_attr( $form_id ); ?>" data-form-id="<?php echo esc_attr( $form_id ); ?>">
|
||||
<?php wp_nonce_field( 'pcfb_public_nonce', 'pcfb_nonce' ); ?>
|
||||
<input type="hidden" name="action" value="pcfb_submit_form">
|
||||
<input type="hidden" name="form_id" value="<?php echo esc_attr( $form_id ); ?>">
|
||||
|
||||
<div class="pcfb-form-fields">
|
||||
<?php if ( ! empty( $fields ) && is_array( $fields ) ) : ?>
|
||||
<?php foreach ( $fields as $field ) : ?>
|
||||
<?php
|
||||
$field_id = ! empty( $field->id ) ? $field->id : 0;
|
||||
$field_name = ! empty( $field->field_name ) ? $field->field_name : '';
|
||||
$field_label = ! empty( $field->field_label ) ? $field->field_label : '';
|
||||
$field_type = ! empty( $field->field_type ) ? $field->field_type : 'text';
|
||||
$placeholder = ! empty( $field->placeholder ) ? $field->placeholder : '';
|
||||
$options = ! empty( $field->options ) ? maybe_unserialize( $field->options ) : array();
|
||||
$validation_rules = ! empty( $field->validation_rules ) ? maybe_unserialize( $field->validation_rules ) : array();
|
||||
$is_required = ! empty( $validation_rules['required'] );
|
||||
?>
|
||||
|
||||
<div class="pcfb-form-group pcfb-field-<?php echo esc_attr( $field_type ); ?>">
|
||||
<label class="pcfb-label" for="<?php echo esc_attr( 'pcfb-' . $form_id . '-' . $field_name ); ?>">
|
||||
<?php echo esc_html( $field_label ); ?>
|
||||
<?php if ( $is_required ) : ?>
|
||||
<span class="pcfb-required">*</span>
|
||||
<?php endif; ?>
|
||||
</label>
|
||||
|
||||
<?php switch ( $field_type ) :
|
||||
case 'text':
|
||||
case 'email':
|
||||
case 'name':
|
||||
?>
|
||||
<input
|
||||
type="<?php echo esc_attr( 'email' === $field_type ? 'email' : 'text' ); ?>"
|
||||
id="<?php echo esc_attr( 'pcfb-' . $form_id . '-' . $field_name ); ?>"
|
||||
name="<?php echo esc_attr( $field_name ); ?>"
|
||||
class="pcfb-input"
|
||||
placeholder="<?php echo esc_attr( $placeholder ); ?>"
|
||||
<?php if ( $is_required ) : ?>required<?php endif; ?>
|
||||
>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case 'response':
|
||||
?>
|
||||
<textarea
|
||||
id="<?php echo esc_attr( 'pcfb-' . $form_id . '-' . $field_name ); ?>"
|
||||
name="<?php echo esc_attr( $field_name ); ?>"
|
||||
class="pcfb-textarea"
|
||||
rows="5"
|
||||
placeholder="<?php echo esc_attr( $placeholder ); ?>"
|
||||
<?php if ( $is_required ) : ?>required<?php endif; ?>
|
||||
></textarea>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case 'dropdown':
|
||||
?>
|
||||
<select
|
||||
id="<?php echo esc_attr( 'pcfb-' . $form_id . '-' . $field_name ); ?>"
|
||||
name="<?php echo esc_attr( $field_name ); ?>"
|
||||
class="pcfb-select"
|
||||
<?php if ( $is_required ) : ?>required<?php endif; ?>
|
||||
>
|
||||
<option value=""><?php echo esc_html( $placeholder ? $placeholder : __( '-- Select --', 'pc-form-builder-xyz123' ) ); ?></option>
|
||||
<?php if ( ! empty( $options ) && is_array( $options ) ) : ?>
|
||||
<?php foreach ( $options as $option ) : ?>
|
||||
<?php if ( ! empty( trim( $option ) ) ) : ?>
|
||||
<option value="<?php echo esc_attr( trim( $option ) ); ?>"><?php echo esc_html( trim( $option ) ); ?></option>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case 'checkbox':
|
||||
if ( ! empty( $options ) && is_array( $options ) ) :
|
||||
?>
|
||||
<div class="pcfb-checkbox-group">
|
||||
<?php foreach ( $options as $index => $option ) : ?>
|
||||
<?php if ( ! empty( trim( $option ) ) ) : ?>
|
||||
<?php $checkbox_id = 'pcfb-' . $form_id . '-' . $field_name . '-' . $index; ?>
|
||||
<label class="pcfb-checkbox-label" for="<?php echo esc_attr( $checkbox_id ); ?>">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="<?php echo esc_attr( $checkbox_id ); ?>"
|
||||
name="<?php echo esc_attr( $field_name ); ?>[]"
|
||||
value="<?php echo esc_attr( trim( $option ) ); ?>"
|
||||
class="pcfb-checkbox"
|
||||
>
|
||||
<span class="pcfb-checkbox-text"><?php echo esc_html( trim( $option ) ); ?></span>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
break;
|
||||
endswitch; ?>
|
||||
|
||||
<span class="pcfb-field-error" id="<?php echo esc_attr( 'pcfb-error-' . $form_id . '-' . $field_name ); ?>"></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else : ?>
|
||||
<p class="pcfb-no-fields"><?php esc_html_e( 'This form has no fields yet.', 'pc-form-builder-xyz123' ); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-form-footer">
|
||||
<button type="submit" class="pcfb-submit-button">
|
||||
<span class="pcfb-submit-text"><?php echo esc_html( $submit_text ); ?></span>
|
||||
<span class="pcfb-submit-loader" style="display: none;">
|
||||
<span class="pcfb-spinner"></span>
|
||||
<?php esc_html_e( 'Submitting...', 'pc-form-builder-xyz123' ); ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="pcfb-form-message pcfb-success-message" style="display: none;">
|
||||
<div class="pcfb-message-content">
|
||||
<span class="pcfb-message-icon dashicons dashicons-yes-alt"></span>
|
||||
<p class="pcfb-message-text"><?php echo esc_html( $success_message ); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pcfb-form-message pcfb-error-message" style="display: none;">
|
||||
<div class="pcfb-message-content">
|
||||
<span class="pcfb-message-icon dashicons dashicons-warning"></span>
|
||||
<p class="pcfb-message-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# PC Form Builder Plugin Validation Script
|
||||
#
|
||||
# Lints all PHP files and verifies plugin header.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PLUGIN_DIR="$1"
|
||||
|
||||
if [ -z "$PLUGIN_DIR" ]; then
|
||||
echo "Usage: ./scripts/validate-wordpress-plugin.sh <plugin-root-directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$PLUGIN_DIR" ]; then
|
||||
echo "Error: Directory $PLUGIN_DIR does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Validating WordPress Plugin: $PLUGIN_DIR"
|
||||
echo "=========================================="
|
||||
|
||||
ERRORS=0
|
||||
|
||||
for php_file in $(find "$PLUGIN_DIR" -name "*.php" -type f); do
|
||||
echo "Checking: $php_file"
|
||||
|
||||
output=$(php -l "$php_file" 2>&1)
|
||||
|
||||
if echo "$output" | grep -q "No syntax errors detected"; then
|
||||
echo " ✓ Syntax OK"
|
||||
else
|
||||
echo " ✗ Syntax Error:"
|
||||
echo "$output"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
|
||||
if [ $ERRORS -gt 0 ]; then
|
||||
echo "Found $ERRORS error(s)"
|
||||
exit 1
|
||||
else
|
||||
echo "All PHP files passed syntax validation!"
|
||||
exit 0
|
||||
fi
|
||||
36
chat/templates/Form Builder/uninstall.php
Normal file
36
chat/templates/Form Builder/uninstall.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* PC Form Builder Uninstall
|
||||
*
|
||||
* Cleans up plugin data when uninstalled.
|
||||
*
|
||||
* @package PCFormBuilder
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'delete_plugins' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
delete_option( 'pcfb_version' );
|
||||
delete_option( 'pcfb_activated' );
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$tables = array(
|
||||
$wpdb->prefix . 'pcfb_forms',
|
||||
$wpdb->prefix . 'pcfb_fields',
|
||||
$wpdb->prefix . 'pcfb_responses',
|
||||
$wpdb->prefix . 'pcfb_response_data',
|
||||
);
|
||||
|
||||
foreach ( $tables as $table ) {
|
||||
$wpdb->query( "DROP TABLE IF EXISTS {$table}" );
|
||||
}
|
||||
Reference in New Issue
Block a user