options[$option][$so] = $filter; } } elseif ( is_null( $suboption ) ) { $this->options[$option] = $filter; } else { $this->options[$option][$suboption] = $filter; } add_filter( 'sanitize_option_' . $option, array( $this, 'sanitize' ), 10, 2 ); return true; } /** * Checks sanitization filter exists, and if so, passes the value through it. * * @since 1.0.0 */ function do_filter( $filter, $new_value, $old_value ) { $available_filters = $this->get_available_filters(); if ( ! in_array( $filter, array_keys( $available_filters ) ) ) { return $new_value; } return call_user_func( $available_filters[$filter], $new_value, $old_value ); } /** * Return array of known sanitization filter types. * * @since 1.0.0 */ function get_available_filters() { $default_filters = array( 'one_zero' => array( $this, 'one_zero' ), 'no_html' => array( $this, 'no_html' ), 'absint' => array( $this, 'absint' ), 'safe_html' => array( $this, 'safe_html' ), 'requires_unfiltered_html' => array( $this, 'requires_unfiltered_html' ), 'url' => array( $this, 'url' ), ); return apply_filters( 'bizznis_available_sanitizer_filters', $default_filters ); } /** * Sanitize a value, via the sanitization filter type associated with an option. * * @since 1.0.0 */ function sanitize( $new_value, $option ) { if ( !isset( $this->options[$option] ) ) { # We are not filtering this option at all return $new_value; } elseif ( is_string( $this->options[$option] ) ) { # Single option value return $this->do_filter( $this->options[$option], $new_value, get_option( $option ) ); } elseif ( is_array( $this->options[$option] ) ) { # Array of suboption values to loop through $old_value = get_option( $option ); foreach ( $this->options[$option] as $suboption => $filter ) { $old_value[$suboption] = isset( $old_value[$suboption] ) ? $old_value[$suboption] : ''; $new_value[$suboption] = isset( $new_value[$suboption] ) ? $new_value[$suboption] : ''; $new_value[$suboption] = $this->do_filter( $filter, $new_value[$suboption], $old_value[$suboption] ); } return $new_value; } else { # Should never hit this, but: return $new_value; } } //* Now, our filter methods /** * Returns a 1 or 0, for all truthy / falsy values. Uses double casting. First, we cast to bool, * then to integer. * * @since 1.0.0 */ function one_zero( $new_value ) { return (int) (bool) $new_value; } /** * Returns a positive integer value. * * @since 1.0.0 */ function absint( $new_value ) { return absint( $new_value ); } /** * Removes HTML tags from string. * * @since 1.0.0 */ function no_html( $new_value ) { return strip_tags( $new_value ); } /** * Makes URLs safe * * @since 1.0.0 */ function url( $new_value ) { return esc_url_raw( $new_value ); } /** * Removes unsafe HTML tags, via wp_kses_post(). * * @since 1.0.0 */ function safe_html( $new_value ) { return wp_kses_post( $new_value ); } /** * Keeps the option from being updated if the user lacks unfiltered_html capability. * * @since 1.0.0 */ function requires_unfiltered_html( $new_value, $old_value ) { if ( current_user_can( 'unfiltered_html' ) ) { return $new_value; } else { return $old_value; } } } /** * Keeps the option from being updated if the user lacks unfiltered_html capability. * * If the option is an "array" option type with "suboptions", you have to use the third param to specify the * suboption or suboptions you want the filter to apply to. DO NOT call this without the third parameter on an option * that is an array option, because in that case it will apply that filter to the array(), not each member. * * @since 1.0.0 */ function bizznis_add_option_filter( $filter, $option, $suboption = null ) { return Bizznis_Settings_Sanitizer::$instance->add_filter( $filter, $option, $suboption ); } /** * Instantiate the Sanitizer. * * @since 1.0.0 */ add_action( 'admin_init', 'bizznis_settings_sanitizer_init' ); function bizznis_settings_sanitizer_init() { new Bizznis_Settings_Sanitizer; }