class-redux-validation.php (8474B)
1 <?php 2 /** 3 * Redux Validation Class 4 * 5 * @class Redux_Validation 6 * @version 4.0.0 7 * @package Redux Framework 8 */ 9 10 defined( 'ABSPATH' ) || exit; 11 12 if ( ! class_exists( 'Redux_Validation', false ) ) { 13 14 /** 15 * Class Redux_Validation 16 */ 17 class Redux_Validation extends Redux_Class { 18 19 /** 20 * Validate values from options form (used in settings api validate function) 21 * calls the custom validation class for the field so authors can override with custom classes 22 * 23 * @since 1.0.0 24 * @access public 25 * 26 * @param array $plugin_options Plugin Options. 27 * @param array $options Options. 28 * @param array $sections Sections array. 29 * 30 * @return array $plugin_options 31 */ 32 public function validate( array $plugin_options, array $options, array $sections ): array { 33 $core = $this->core(); 34 35 foreach ( $sections as $k => $section ) { 36 if ( isset( $section['fields'] ) ) { 37 foreach ( $section['fields'] as $fkey => $field ) { 38 39 if ( is_array( $field ) ) { 40 $field['section_id'] = $k; 41 } 42 43 if ( isset( $field['type'] ) && ( 'checkbox' === $field['type'] || 'checkbox_hide_below' === $field['type'] || 'checkbox_hide_all' === $field['type'] ) ) { 44 if ( ! isset( $plugin_options[ $field['id'] ] ) ) { 45 $plugin_options[ $field['id'] ] = 0; 46 } 47 } 48 49 // Part of Dovy's serialize typography effort. Preserved here in case it becomes a thing. - kp. 50 /** 51 * If ( isset ( $field['type'] ) && $field['type'] == 'typography' ) { 52 * if ( ! is_array( $plugin_options[ $field['id'] ] ) && ! empty( $plugin_options[ $field['id'] ] ) ) { 53 * $plugin_options[ $field['id'] ] = json_decode( $plugin_options[ $field['id'] ], true ); 54 * } 55 * } 56 */ 57 58 if ( isset( $core->extensions[ $field['type'] ] ) && method_exists( $core->extensions[ $field['type'] ], '_validate_values' ) ) { 59 $plugin_options = $core->extensions[ $field['type'] ]->_validate_values( $plugin_options, $field, $sections ); 60 } 61 62 // Make sure 'validate' field is set. 63 if ( isset( $field['validate'] ) ) { 64 65 // Can we make this an array of validations? 66 $val_arr = array(); 67 68 if ( is_array( $field['validate'] ) ) { 69 $val_arr = $field['validate']; 70 } else { 71 $val_arr[] = $field['validate']; 72 } 73 74 foreach ( $val_arr as $idx => $val ) { 75 // shim for old *_not_empty validations. 76 if ( 'email_not_empty' === $val || 'numeric_not_empty' === $val ) { 77 $val = 'not_empty'; 78 } 79 80 // Make sure 'validate field' is set to 'not_empty'. 81 $is_not_empty = false; 82 83 if ( 'not_empty' === $val ) { 84 // Set the flag. 85 $is_not_empty = true; 86 } 87 88 // Check for empty id value. 89 if ( ! isset( $field['id'] ) || ! isset( $plugin_options[ $field['id'] ] ) || ( isset( $plugin_options[ $field['id'] ] ) && '' === $plugin_options[ $field['id'] ] ) ) { 90 91 // If we are looking for an empty value, in the case of 'not_empty' 92 // then we need to keep processing. 93 if ( ! $is_not_empty ) { 94 95 // Empty id and not checking for 'not_empty. Bail out... 96 if ( ! isset( $field['validate_callback'] ) ) { 97 continue; 98 } 99 } 100 } 101 102 // Force validate of custom field types. 103 if ( isset( $field['type'] ) && ! isset( $val ) && ! isset( $field['validate_callback'] ) ) { 104 if ( 'color' === $field['type'] || 'color_gradient' === $field['type'] ) { 105 $val = 'color'; 106 } elseif ( 'date' === $field['type'] ) { 107 $val = 'date'; 108 } 109 } 110 111 // No need. Spectrum self validates. 112 if ( 'color_rgba' === $field['type'] ) { 113 continue; 114 } 115 116 // Shim out old colorgrba validators. 117 if ( 'color_rgba' === $val || 'colorrgba' === $val ) { 118 $val = 'color'; 119 } 120 121 $validate = 'Redux_Validation_' . $val; 122 123 if ( ! class_exists( $validate ) ) { 124 125 /** 126 * Filter 'redux/validate/{opt_name}/class/{field.validate}' 127 * 128 * @param string validation class file path 129 * @param string $class_file validation class file path 130 */ 131 132 $file = str_replace( '_', '-', $val ); 133 134 // phpcs:ignore WordPress.NamingConventions.ValidHookName 135 $class_file = apply_filters( "redux/validate/{$core->args['opt_name']}/class/$val", Redux_Core::$dir . "inc/validation/$val/class-redux-validation-$file.php", $validate ); 136 137 if ( $class_file ) { 138 if ( file_exists( $class_file ) ) { 139 require_once $class_file; 140 } 141 } 142 } 143 144 if ( class_exists( $validate ) ) { 145 if ( empty( $options[ $field['id'] ] ) ) { 146 $options[ $field['id'] ] = ''; 147 } 148 149 if ( isset( $plugin_options[ $field['id'] ] ) && is_array( $plugin_options[ $field['id'] ] ) && ! empty( $plugin_options[ $field['id'] ] ) ) { 150 foreach ( $plugin_options[ $field['id'] ] as $key => $value ) { 151 $before = null; 152 $after = null; 153 154 if ( isset( $plugin_options[ $field['id'] ][ $key ] ) && ( ! empty( $plugin_options[ $field['id'] ][ $key ] ) || '0' === $plugin_options[ $field['id'] ][ $key ] ) ) { 155 if ( is_array( $plugin_options[ $field['id'] ][ $key ] ) ) { 156 $before = $plugin_options[ $field['id'] ][ $key ]; 157 } else { 158 $before = trim( $plugin_options[ $field['id'] ][ $key ] ); 159 } 160 } 161 162 if ( isset( $options[ $field['id'] ][ $key ] ) && ( ! empty( $plugin_options[ $field['id'] ][ $key ] ) || '0' === $plugin_options[ $field['id'] ][ $key ] ) ) { 163 $after = $options[ $field['id'] ][ $key ]; 164 } 165 166 $validation = new $validate( $core, $field, $before, $after ); 167 168 if ( ! empty( $validation->value ) || '0' === $validation->value ) { 169 $plugin_options[ $field['id'] ][ $key ] = $validation->value; 170 } else { 171 unset( $plugin_options[ $field['id'] ][ $key ] ); 172 } 173 174 if ( isset( $validation->error ) ) { 175 $core->errors[] = $validation->error; 176 } 177 178 if ( isset( $validation->warning ) ) { 179 $core->warnings[] = $validation->warning; 180 } 181 182 if ( isset( $validation->sanitize ) ) { 183 $core->sanitize[] = $validation->sanitize; 184 } 185 } 186 } else { 187 if ( isset( $plugin_options[ $field['id'] ] ) ) { 188 if ( is_array( $plugin_options[ $field['id'] ] ) ) { 189 $pofi = $plugin_options[ $field['id'] ]; 190 } else { 191 $pofi = trim( $plugin_options[ $field['id'] ] ); 192 } 193 } else { 194 $pofi = null; 195 } 196 197 $validation = new $validate( $core, $field, $pofi, $options[ $field['id'] ] ); 198 $plugin_options[ $field['id'] ] = $validation->value; 199 200 if ( isset( $validation->error ) ) { 201 $core->errors[] = $validation->error; 202 } 203 204 if ( isset( $validation->warning ) ) { 205 $core->warnings[] = $validation->warning; 206 } 207 208 if ( isset( $validation->sanitize ) ) { 209 $core->sanitize[] = $validation->sanitize; 210 } 211 } 212 213 break; 214 } 215 } 216 } 217 218 if ( isset( $field['validate_callback'] ) && ( is_callable( $field['validate_callback'] ) || ( is_string( $field['validate_callback'] ) && function_exists( $field['validate_callback'] ) ) ) ) { 219 $callback = $field['validate_callback']; 220 unset( $field['validate_callback'] ); 221 222 $plugin_option = $plugin_options[ $field['id'] ] ?? null; 223 $option = $options[ $field['id'] ] ?? null; 224 225 $callbackvalues = call_user_func( $callback, $field, $plugin_option, $option ); 226 227 $plugin_options[ $field['id'] ] = $callbackvalues['value']; 228 229 if ( isset( $callbackvalues['error'] ) ) { 230 $core->errors[] = $callbackvalues['error']; 231 } 232 233 if ( isset( $callbackvalues['warning'] ) ) { 234 $core->warnings[] = $callbackvalues['warning']; 235 } 236 237 if ( isset( $callbackvalues['sanitize'] ) ) { 238 $core->sanitize[] = $callbackvalues['sanitize']; 239 } 240 } 241 } 242 } 243 } 244 245 return $plugin_options; 246 } 247 } 248 }