Field()
Description #
Base field class.
Source #
File: lib/form/class-field.php
class Field { /** * The current field name. * * @var string */ public $field_name = ''; /** * The original field name. * * @var string */ public $original_name = ''; /** * The form name. * * @var string */ public $form_name; /** * Unique name without square brackets. * * @var string */ public $field_id = ''; /** * The field arguments. * * @var array */ public $args = array(); /** * The field HTML markup. * * @var string */ protected $html = ''; /** * The HTML output order. * * @var array */ protected $output_order = array(); /** * The errors. * * @var array */ public $errors = array(); /** * Field type. * * @var string */ public $type = 'input'; /** * Child fields. * * @var object */ public $child; /** * Is editing. * * @var boolean */ public $editing = false; /** * Editing post ID. * * @var boolean|integer */ public $editing_id = false; /** * Is validated? * * @var boolean */ protected $validated = false; /** * The validation callbacks. * * @var array */ protected $validate_cb = array(); /** * The sanitization callback. * * @var array */ protected $sanitize_cb = array(); /** * Is sanitized? * * @var boolean */ protected $sanitized = false; /** * The sanitized values. * * @var array */ public $sanitized_value; /** * The field value (unsafe). * * @var mixed */ public $value = null; /** * Initialize the class. * * @param string $form_name Name of parent form. * @param string $name Name of field. * @param array $args Field arguments. */ public function __construct( $form_name, $name, $args ) { $this->original_name = $name; $this->field_name = $form_name . '[' . $name . ']'; $this->form_name = $form_name; $this->args = $args; $this->field_id = $this->id(); $this->prepare(); } /** * Prepare field. * * @return void */ protected function prepare() { $this->sanitize_cb(); $this->validate_cb(); } /** * Get parent form. * * @return object */ public function form() { $form_name = explode( '.', ap_to_dot_notation( $this->form_name ) ); return anspress()->get_form( $form_name[0] ); } /** * Parse sanitization callbacks. * * @return void */ protected function sanitize_cb() { if ( ! empty( $this->args['sanitize'] ) ) { if ( is_array( $this->args['sanitize'] ) ) { $this->sanitize_cb = array_unique( $this->args['sanitize'] ); } else { $this->sanitize_cb = array_unique( explode( ',', $this->args['sanitize'] ) ); } } } /** * Parse validation callbacks. * * @return void */ protected function validate_cb() { if ( ! empty( $this->args['validate'] ) ) { if ( is_array( $this->args['validate'] ) ) { $this->validate_cb = array_unique( $this->args['validate'] ); } else { $this->validate_cb = array_unique( explode( ',', $this->args['validate'] ) ); } } } /** * Get a value from a path or default value if the path doesn't exist * * @param string $key Path. * @param mixed $default_val Default value. * @param array $arr Array to search. * @return mixed */ public function get( $key, $default_val = null, $arr = null ) { $keys = explode( '.', (string) $key ); if ( null === $arr ) { $arr = &$this->args; } foreach ( $keys as $key ) { if ( ! is_array( $arr ) || ! array_key_exists( $key, $arr ) ) { return $default_val; } $arr = &$arr[ $key ]; } return $arr; } /** * Add HTML markup to property. * * @param string $html Html as string. * @return void */ public function add_html( $html ) { $this->html = $this->html . $html; } /** * Order of HTML markup. * * @return void * @since 4.1.8 Allow overriding order from arguments. */ protected function html_order() { if ( empty( $this->args['output_order'] ) ) { $this->output_order = array( 'wrapper_start', 'label', 'field_wrap_start', 'errors', 'field_markup', 'desc', 'field_wrap_end', 'wrapper_end' ); } else { $this->output_order = $this->args['output_order']; } } /** * Create field markup. * * @return null|string */ public function output() { $this->html = ''; $this->html_order(); foreach ( (array) $this->output_order as $method ) { if ( method_exists( $this, $method ) ) { $this->add_html( $this->$method() ); } } /** * Filter applied before returning a html of a field. * * @param string $html Field HTML markup. * @param object $field Current field object. */ $this->html = apply_filters( 'ap_field_html', $this->html, $this ); // xss okay. if ( ! empty( $this->html ) ) { return $this->html; // xss okay. } } /** * Get POST (unsafe) value of a field. * * @return null|mixed */ public function unsafe_value() { $request_value = $this->get( ap_to_dot_notation( $this->field_name ), null, $_REQUEST ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $request_value ) ) { return wp_unslash( $request_value ); } } /** * Check if request value is set. * * @return boolean */ public function isset_value() { $request_value = $this->get( ap_to_dot_notation( $this->field_name ), null, $_REQUEST ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( is_null( $request_value ) ) { return false; } return true; } /** * Get value of a field. * * @param mixed $custom_val Set custom value for field. * @return mixed * * @since 4.1.8 Pass a value to set it as value of field. */ public function value( $custom_val = null ) { if ( null !== $custom_val ) { $this->value = $custom_val; return true; } if ( ! is_null( $this->value ) ) { return $this->value; } $sanitized = $this->sanitize(); if ( null !== $sanitized ) { return $sanitized; } return $this->get( 'value' ); } /** * Field wrapper start. * * @return void */ protected function field_wrap_start() { $this->add_html( '<div class="ap-field-group-w">' ); } /** * Field wrapper end. * * @return void */ protected function field_wrap_end() { $this->add_html( '</div>' ); } /** * Output label of field. * * @return void */ public function label() { $this->add_html( '<label class="ap-form-label" for="' . $this->id() . '">' . esc_html( $this->get( 'label' ) ) . '</label>' ); } /** * Check if field have any errors. * * @return boolean */ public function have_errors() { if ( ! empty( $this->errors ) ) { return true; } return false; } /** * Add error message to a field. * * @param string $code Error code. * @param string $message Error message. * @return void */ public function add_error( $code, $message = '' ) { $this->errors[ $code ] = $message; $name = explode( '.', ap_to_dot_notation( $this->form_name ) ); if ( is_array( $name ) ) { anspress()->get_form( $name[0] )->add_error( 'fields-error', __( 'Error found in fields, please check and re-submit', 'anspress-question-answer' ) ); } } /** * Output label of field. * * @return void */ public function errors() { $wrapper = $this->get( 'wrapper', array() ); if ( false !== $wrapper ) { $this->add_html( '<div class="ap-field-errorsc">' ); } if ( $this->have_errors() ) { $this->add_html( '<div class="ap-field-errors">' ); foreach ( $this->errors as $code => $err ) { $this->add_html( '<span class="ap-field-error ecode-' . esc_attr( $code ) . '">' . esc_html( $err ) . '</span>' ); } $this->add_html( '</div>' ); } if ( false !== $wrapper ) { $this->add_html( '</div>' ); } } /** * Return safe css ID. * * @param string $str String. * @return string */ public function id( $str = false ) { if ( ! empty( $this->field_id ) ) { return $this->field_id; } if ( false === $str ) { $str = $this->field_name; } return sanitize_html_class( rtrim( preg_replace( '/-+/', '-', str_replace( array( '[', ']' ), '-', $str ) ), '-' ) ); } /** * Field markup. * * @return void */ public function field_markup() { /** * Action triggered before rendering field markup. * * @param object $field Field object passed by reference. * @since 4.1.0 */ do_action_ref_array( 'ap_before_field_markup', array( $this ) ); } /** * Output field description. * * @return void */ public function desc() { if ( $this->get( 'desc' ) ) { $this->add_html( '<div class="ap-field-desc">' . wp_kses_post( $this->get( 'desc' ) ) . '</div>' ); } } /** * Form field wrapper start. * * @return void */ protected function wrapper_start() { $wrapper = $this->get( 'wrapper', array() ); if ( false !== $wrapper ) { $errors = $this->have_errors() ? ' ap-have-errors' : ''; $this->add_html( '<div class="ap-form-group ap-field-' . $this->id() . ' ap-field-type-' . esc_attr( $this->type ) . $errors . ' ' . esc_attr( $this->get( 'wrapper.class', '' ) ) . '"' . $this->get_attr( $this->get( 'wrapper.attr' ) ) . '>' ); } } /** * Form field wrapper end. * * @return void */ protected function wrapper_end() { if ( false !== $this->get( 'wrapper', array() ) ) { $this->add_html( '</div>' ); } } /** * Convert and sanitize attributes of array to string. * * @param array $arr Custom attributes to apply. * @return string */ protected function get_attr( $arr ) { $html = ''; if ( ! empty( $arr ) && is_array( $arr ) ) { foreach ( $arr as $attr_key => $attr_value ) { $html .= ' ' . sanitize_html_class( $attr_key ) . '="' . esc_attr( $attr_value ) . '"'; } } return $html; } /** * Output common attributes of a field. * * @return string */ protected function common_attr() { return ' name="' . esc_attr( $this->field_name ) . '" id="' . $this->id() . '" class="ap-form-control ' . esc_attr( $this->get( 'class', '' ) ) . '"'; } /** * Sanitized custom attributes of a field. * * @return string */ protected function custom_attr() { return $this->get_attr( $this->get( 'attr', array() ) ); } /** * Arguments passed to sanitization callback. * * @param mixed $val Value to sanitize. * @return array */ protected function sanitize_cb_args( $val ) { return array( $val ); } /** * Sanitize value of current field. * * @return mixed */ public function sanitize() { if ( true === $this->sanitized ) { return $this->sanitized_value; } if ( ! empty( $this->sanitize_cb ) ) { $unsafe_value = $this->unsafe_value(); $sanitize_applied = false; foreach ( (array) $this->sanitize_cb as $sanitize ) { // Callback for sanitizing field type. $cb = 'sanitize_' . trim( $sanitize ); if ( method_exists( 'AnsPress\Form\Validate', $cb ) ) { $sanitized_val = call_user_func_array( 'AnsPress\Form\Validate::' . $cb, $this->sanitize_cb_args( $unsafe_value ) ); // If callback is null then do not apply. if ( null !== $sanitized_val ) { $sanitize_applied = true; $unsafe_value = $sanitized_val; } } } $this->sanitized = true; if ( null !== $unsafe_value && true === $sanitize_applied ) { $this->sanitized_value = $unsafe_value; } } return $this->sanitized_value; } /** * Validate current field. * * @return void */ public function validate() { if ( true === $this->validated ) { return; } if ( ! empty( $this->validate_cb ) ) { foreach ( (array) $this->validate_cb as $validate ) { // Callback for validating field type. $cb = 'validate_' . trim( $validate ); if ( method_exists( 'AnsPress\Form\Validate', $cb ) ) { call_user_func_array( 'AnsPress\Form\Validate::' . $cb, array( $this ) ); } /** * Custom validation callback. * * @param string $field_name CUrrent field. * @param object $field CUrrent field. * @since 4.1.7 */ apply_filters_ref_array( "ap_field_{$cb}", array( $this->field_name, $this ) ); } $this->validated = true; } } /** * Before getting data. */ public function pre_get() { } /** * After save. * * @param array $args Arguments. */ public function after_save( $args = array() ) { } /** * Call save callback. * * This will call save callback with two parameter `value` * and current field object. * * @return mixed * @since 4.1.8 */ public function save_cb() { if ( ! empty( $this->args['save'] ) && is_callable( $this->args['save'] ) ) { return call_user_func( $this->args['save'], $this->value(), $this ); } } }
Expand full source code Collapse full source code View on GitHub: lib/form/class-field.php:25
Add your comment