AnsPress_Form()
Description #
AnsPress HTML form handler
Source #
File: includes/class/form.php
class AnsPress_Form { /** * Name of the form. * * @var string */ private $name; /** * Form arguments. * * @var array */ private $args = array(); /** * HTML output. * * @var string */ private $output = ''; /** * Current field. * * @var array */ private $field; /** * Form error. * * @var array */ private $errors; /** * Initiate the class. * * @param array $args Form arguments. */ public function __construct( $args = array() ) { // Default form arguments. $defaults = array( 'method' => 'POST', 'action' => '', 'is_ajaxified' => false, 'class' => 'ap-form', 'multipart' => false, 'submit_button' => __( 'Submit', 'anspress-question-answer' ), ); // Merge defaults args. $this->args = wp_parse_args( $args, $defaults ); // Set the name of the form. $this->name = $this->args['name']; global $ap_errors; $this->errors = $ap_errors; $this->add_default_in_field(); $this->order_fields(); } /** * Add fields default values. */ private function add_default_in_field() { if ( ! isset( $this->args['fields'] ) ) { return; } foreach ( (array) $this->args['fields'] as $k => $field ) { if ( ! is_array( $field ) ) { return; } $this->args['fields'][ $k ] = wp_parse_args( $field, array( 'order' => 10, 'show_desc_tip' => false, 'type' => 'text', ) ); // Get value from opttions if options_form. if ( 'options_form' == $this->name && isset( $field['name'] ) && ! isset( $field['value'] ) ) { $this->args['fields'][ $k ]['value'] = ap_opt( $field['name'] ); } } } /** * Order fields. * * @since 2.0.1 */ private function order_fields() { if ( ! isset( $this->args['fields'] ) ) { return; } $this->args['fields'] = ap_sort_array_by_order( $this->args['fields'] ); } /** * Build the form. * * @since 2.0.1 */ public function build() { $this->form_head(); $this->form_fields(); if ( ! isset( $this->args['hide_footer'] ) || false !== $this->args['hide_footer'] ) { $this->hidden_fields(); $this->form_footer(); } } /** * FORM element. * * @since 2.0.1 */ private function form_head() { $attr = ''; if ( ! empty( $this->args['attr'] ) ) { $attr .= $this->args['attr']; } if ( $this->args['is_ajaxified'] ) { $attr .= ' data-action="ap_ajax_form"'; } if ( ! empty( $this->args['class'] ) ) { $attr .= ' class="' . $this->args['class'] . '"'; } ob_start(); /** * ACTION: ap_form_before_[form_name] * action for hooking before form. * * @since 2.0.1 */ do_action( 'ap_form_before_' . $this->name ); $this->output .= ob_get_clean(); // Add enctype if form is multipart. $multipart = $this->args['multipart'] ? ' enctype="multipart/form-data"' : ''; if ( ! isset( $this->args['hide_footer'] ) || false !== $this->args['hide_footer'] ) { $this->output .= '<form name="' . $this->args['name'] . '" id="' . $this->args['name'] . '" method="' . $this->args['method'] . '" action="' . $this->args['action'] . '"' . $attr . $multipart . '>'; } } /** * FORM footer. * * @since 2.0.1 */ private function form_footer() { ob_start(); /** * ACTION: ap_form_bottom_[form_name] * action for hooking captcha and extar fields * * @since 2.0.1 */ do_action( 'ap_form_bottom_' . $this->name ); $this->output .= ob_get_clean(); $this->output .= '<button type="submit" class="ap-btn ap-btn-submit">' . $this->args['submit_button'] . '</button>'; if ( isset( $this->args['show_reset'] ) && true === $this->args['show_reset'] ) { $this->output .= '<input type="submit" name="reset" class="button ap-btn ap-btn-reset" value="' . __( 'Reset', 'anspress-question-answer' ) . '" />'; } if ( isset( $this->args['show_cancel'] ) && true === $this->args['show_cancel'] ) { $this->output .= '<button type="button" class="ap-btn ap-btn-cancel">' . __( 'Cancel', 'anspress-question-answer' ) . '</button>'; } $this->output .= '</form>'; } /** * Add nonce field */ private function nonce() { $nonce_name = isset( $this->args['nonce_name'] ) ? $this->args['nonce_name'] : $this->name; $this->output .= wp_nonce_field( $nonce_name, '__nonce', true, false ); } /** * Form hidden fields. * * @since 2.0.1 */ private function hidden_fields() { $this->output .= '<input type="hidden" name="ap_form_action" value="' . $this->name . '">'; $this->nonce(); } /** * Form field label. * * @since 2.0.1 */ private function label() { if ( $this->field['label'] && ! $this->field['show_desc_tip'] ) { $this->output .= '<label class="ap-form-label" for="'. @$this->field['name'] .'">'. @$this->field['label'].'</label>'; } elseif ( $this->field['label'] ) { $this->output .= '<label class="ap-form-label" for="'. @$this->field['name'] .'">'. @$this->field['label']; $this->desc(); $this->output .= '</label>'; } } /** * Output placeholder attribute of current field. * * @return string * @since 2.0.1 */ private function placeholder() { return ! empty( $this->field['placeholder'] ) ? ' placeholder="' . $this->field['placeholder'] . '"' : ''; } /** * Output description of a form fields. * * @since 2.0.1 */ private function desc() { if ( ! $this->field['show_desc_tip'] ) { $this->output .= ( ! empty( $this->field['desc'] ) ? '<p class="ap-field-desc">' . $this->field['desc'] . '</p>' : ''); } else { $this->output .= ( ! empty( $this->field['desc'] ) ? '<span class="ap-tip ap-field-desc" data-tipposition="right" title="' . esc_html( $this->field['desc'] ) . '">?</span>' : ''); } } /** * Output text fields. * * @param array $field Field. * @param string $type Type of field. * @since 2.0 */ private function text_field( $field = array(), $type = 'text' ) { if ( isset( $field['label'] ) ) { $this->label(); } $placeholder = $this->placeholder(); $autocomplete = isset( $field['autocomplete'] ) ? ' autocomplete="off"' : ''; $this->output .= '<div class="ap-form-fields-in">'; if ( ! isset( $field['repeatable'] ) || ! $field['repeatable'] ) { $this->output .= '<input id="' . $field['name'] . '" type="' . $type . '" class="ap-form-control" value="' . $field['value'] . '" name="' . $field['name'] . '"' . $placeholder . ' ' . $this->attr( $field ) . $autocomplete . ' />'; if ( 'password' === $type ) { $this->output .= '<input id="' . $field['name'] . '-1" type="' . $type . '" class="ap-form-control" value="' . $field['value'] . '" name="' . $field['name'] . '-1" placeholder="' . __( 'Repeat your password', 'anspress-question-answer' ).'" ' . $this->attr( $field ) . $autocomplete . ' />'; } } else { if ( ! empty( $field['value'] ) && is_array( $field['value'] ) ) { $this->output .= '<div id="ap-repeat-c-' . $field['name'] . '" class="ap-repeatbable-field">'; foreach ( $field['value'] as $k => $rep_f ) { $this->output .= '<div id="ap_text_rep_' . $field['name'] . '_' . $k . '" class="ap-repeatbable-field"><input id="' . $field['name'] . '_' . $k . '" type="text" class="ap-form-control ap-repeatable-text" value="' . $rep_f . '" name="' . $field['name'] . '[' . $k . ']"' . $placeholder . ' ' . $this->attr( $field ) . $autocomplete . ' />'; $this->output .= '<button data-action="ap_delete_field" type="button" data-toggle="'. $field['name'] . '_' . $k . '">' . __( 'Delete', 'anspress-question-answer' ) . '</button>'; $this->output .= '</div>'; } $this->output .= '</div>'; $this->output .= '<div id="ap-repeatbable-field-' . $field['name'] . '" class="ap-reapt-field-copy">'; $this->output .= '<div id="ap_text_rep_' . $field['name'] . '_#" class="ap-repeatbable-field"><input id="' . $field['name'] . '_#" type="text" class="ap-form-control ap-repeatable-text" value="" name="' . $field['name'] . '[#]"' . $placeholder . ' ' . $this->attr( $field ) . $autocomplete . ' />'; $this->output .= '<button data-action="ap_delete_field" type="button" data-toggle="' . $field['name'] . '_#">' . __( 'Delete', 'anspress-question-answer' ) . '</button>'; $this->output .= '</div></div>'; $this->output .= '<button data-action="ap_add_field" type="button" data-field="ap-repeat-c-' . $field['name'] . '" data-copy="ap-repeatbable-field-' . $field['name'] . '">' . __( 'Add more', 'anspress-question-answer' ) . '</button>'; } } $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * Output text type="number". * * @param array $field * @return void * @since 2.0.0 */ private function number_field( $field = array() ) { if ( isset( $field['label'] ) ) { $this->label(); } $placeholder = $this->placeholder(); $autocomplete = isset( $field['autocomplete'] ) ? ' autocomplete="off"' : ''; $this->output .= '<div class="ap-form-fields-in">'; $this->output .= '<input id="'. @$field['name'] .'" type="number" class="ap-form-control" value="'. @$field['value'] .'" name="'. @$field['name'] .'"'.$placeholder.' '. $this->attr( $field ) .$autocomplete.' />'; $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * Checkbox field. * * @param array $field Field. * @since 2.0.1 */ private function checkbox_field( $field = array() ) { if ( isset( $field['label'] ) ) { $this->label(); } $this->output .= '<div class="ap-form-fields-in">'; if ( ! empty( $field['desc'] ) ) { $this->output .= '<label for="' . $field['name'] . '">'; } $this->output .= '<input id="' . $field['name'] . '" type="checkbox" class="ap-form-control" value="1" name="' . $field['name'] . '" ' . checked( (bool) $field['value'], true, false ) . ' ' . $this->attr( $field ) . ' />'; // Hack for getting value of unchecked checkbox. $this->output .= '<input type="hidden" value="0" name="_hidden_' . $field['name'] . '" />'; if ( ! empty( $field['desc'] ) ) { $this->output .= $field['desc'] . '</label>'; } $this->error_messages(); $this->output .= '</div>'; } /** * Radio field. * * @param array $field Field. * @since 2.0.1 */ private function radio_field( $field = [] ) { if ( isset( $field['label'] ) ) { $this->label(); } $this->output .= '<div class="ap-form-fields-in">'; foreach ( (array) $field['options'] as $opt_value => $opt_label ) { $this->output .= '<label>'; $this->output .= '<input id="' . $field['name'] . '" type="radio" class="ap-form-control" value="' . esc_attr( $opt_value ) . '" name="' . $field['name'] . '" ' . checked( $opt_value, $field['value'], false ) . ' ' . $this->attr( $field ) . ' />'; $this->output .= $opt_label; $this->output .= '</label>'; } if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->error_messages(); $this->output .= '</div>'; } /** * Output select field options. * * @param array $field Field. * @return void * @since 2.0.1 */ private function select_options( $field = array() ) { foreach ( $field['options'] as $k => $opt ) { $this->output .= '<option value="'.$k.'" '.selected( $k, $field['value'], false ).'>'.$opt.'</option>'; } } /** * Select fields * @param array $field * @return void * @since 2.0.1 */ private function select_field($field = array()) { if ( isset( $field['label'] ) ) { $this->label(); } $this->output .= '<div class="ap-form-fields-in">'; $this->output .= '<select id="'. @$field['name'] .'" class="ap-form-control" value="'. @$field['value'] .'" name="'. @$field['name'] .'" '. $this->attr( $field ) .'>'; $this->output .= '<option value=""></option>'; $this->select_options( $field ); $this->output .= '</select>'; $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * Taxonomy select field * @param array $field * @return void * @since 2.0.1 */ private function taxonomy_select_field($field = array()) { if ( isset( $field['label'] ) ) { $this->label(); } $this->output .= '<div class="ap-form-fields-in">'; $taxonomies = wp_dropdown_categories( array( 'taxonomy' => $field['taxonomy'], 'orderby' => @$field['orderby'], 'hide_empty' => 0, 'hierarchical' => 1, 'selected' => @$field['value'], 'name' => @$field['name'], 'class' => 'ap-form-control', 'id' => @$field['name'], 'echo' => false ) ); $this->output .= $taxonomies; $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * Page select field * @param array $field * @return void * @since 2.0.0 */ private function page_select_field($field = array()) { if ( isset( $field['label'] ) ) { $this->label(); } $this->output .= '<div class="ap-form-fields-in">'; $this->output .= wp_dropdown_pages( array( 'show_option_none' => __( 'Select a page', 'anspress-question-answer' ), 'selected' => @$field['value'], 'name' => @$field['name'], 'post_type' => 'page', 'echo' => false ) ); $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * Textarea field output. * @param array $field Field args. * @return void * @since 2.0 */ private function textarea_field($field = array()) { $field = wp_parse_args( $field, array( 'name' => 'textarea', 'rows' => '6', 'value' => '', ) ); if ( isset( $field['label'] ) ) { $this->label(); } $this->output .= '<div class="ap-form-fields-in">'; $placeholder = $this->placeholder(); $this->output .= '<textarea id="'. $field['name'] .'" rows="'. $field['rows'] .'" class="ap-form-control" name="'. $field['name'] .'"'.$placeholder.' '. $this->attr( $field ) .'>'. $field['value'] .'</textarea>'; $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * Create wp_editor field * @param array $field * @return void * @since 2.0.1 */ private function editor_field($field = array()) { if ( isset( $field['label'] ) ) { $this->label(); } if ( $field['settings']['tinymce'] !== false ) { $field['settings']['tinymce'] = array( 'content_css' => ap_get_theme_url( 'css/editor.css' ), 'wp_autoresize_on' => true, ); } /** * FILTER: ap_pre_editor_settings * Can be used to mody wp_editor settings * @var array * @since 2.0.1 */ $settings = apply_filters( 'ap_pre_editor_settings', $field['settings'] ); $this->output .= '<div class="ap-form-fields-in">'; // Turn on the output buffer ob_start(); echo '<div class="ap-editor">'; wp_editor( $field['value'], $field['name'], $settings ); echo '</div>'; $this->output .= ob_get_clean(); $this->error_messages(); if ( ! $this->field['show_desc_tip'] ) { $this->desc(); } $this->output .= '</div>'; } /** * For creating hidden input fields * @param array $field * @return void * @since 2.0.1 */ private function hidden_field( $field = array() ) { $this->output .= '<input type="hidden" value="'. @$field['value'] .'" name="'. @$field['name'] .'" '. $this->attr( $field ) .' />'; } private function custom_field($field = array()) { $this->output .= $field['html']; } private function attr( $field ) { return isset( $field['attr'] ) ? $field['attr'] : ''; } /** * Check if current field have any error * @return boolean * @since 2.0.1 */ private function have_error() { if ( isset( $this->field['name'] ) && isset( $this->errors[$this->field['name']] ) ) { return true; } return false; } private function error_messages() { if ( isset( $this->errors[$this->field['name']] ) ) { $this->output .= '<div class="ap-form-error-messages">'; foreach ( $this->errors[$this->field['name']] as $error ) { $this->output .= '<p class="ap-form-error-message">'. $error .'</p>'; } $this->output .= '</div>'; } } /** * Out put all form fields based on on their type * @return void * @since 2.0 */ private function form_fields() { /** * FILTER: ap_pre_form_fields * Provide filter to add or override form fields before output. * @var array * @since 2.0.1 */ $this->args['fields'] = apply_filters( 'ap_pre_form_fields', $this->args['fields'] ); foreach ( $this->args['fields'] as $field ) { $this->field = $field; $error_class = $this->have_error() ? ' ap-have-error' : ''; if ( isset( $this->args['field_hidden'] ) && $this->args['field_hidden'] ) { if ( isset( $field['name'] ) && $field['type'] != 'hidden' && (@$field['visibility'] != 'me' || ( @$field['visibility'] == 'me' && $this->args['user_id'] == get_current_user_id())) ) { $nonce = wp_create_nonce( 'user_field_form_'.$field['name'].'_'.$this->args['user_id'] ); $this->output .= '<div id="'.@$field['name'].'_field_wrap" class="clearfix ap-form-fields-wrap'.$error_class.'">'; $this->output .= '<label class="ap-form-fields-wrap-label">'.@$field['label'].'</label>'; $this->output .= '<div id="user_field_form_'.$field['name'].'" class="ap-form-fields-wrap-inner"><span>'.@$field['value'].'</apn></div>'; $this->output .= '</div>'; } } else { switch ( $field['type'] ) { case 'text': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->text_field( $field, 'text' ); $this->output .= '</div>'; break; case 'password': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->text_field( $field, 'password' ); $this->output .= '</div>'; break; case 'number': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->number_field( $field ); $this->output .= '</div>'; break; case 'checkbox': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->checkbox_field( $field ); $this->output .= '</div>'; break; case 'radio': $this->output .= '<div class="ap-field-'.@$field['name'] .' ap-form-fields' . $error_class .'">'; $this->radio_field( $field ); $this->output .= '</div>'; break; case 'select': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->select_field( $field ); $this->output .= '</div>'; break; case 'taxonomy_select': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->taxonomy_select_field( $field ); $this->output .= '</div>'; break; case 'page_select': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->page_select_field( $field ); $this->output .= '</div>'; break; case 'textarea': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->textarea_field( $field ); $this->output .= '</div>'; break; case 'editor': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->editor_field( $field ); $this->output .= '</div>'; break; case 'hidden': $this->hidden_field( $field ); break; case 'custom': $this->output .= '<div class="ap-field-'.@$field['name'].' ap-form-fields'.$error_class.'">'; $this->custom_field( $field ); $this->output .= '</div>'; break; default: /** * FILTER: ap_form_fields_[type] * filter for custom form field type */ $this->output .= apply_filters( 'ap_form_fields_'.$field['type'], $field ); break; } } } } /** * Output form * @return string * @since 2.0.1 */ public function get_form() { if ( empty( $this->args['fields'] ) ) { return __( 'No fields found', 'anspress-question-answer' ); } $this->build(); return $this->output; } }
Expand full source code Collapse full source code View on GitHub: includes/class/form.php:16
Add your comment