PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 3.2.3
Tutor LMS – eLearning and online course solution v3.2.3
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / helpers / ValidationHelper.php
tutor / helpers Last commit date
DateTimeHelper.php 1 year ago HttpHelper.php 1 year ago PluginInstaller.php 1 year ago QueryHelper.php 1 year ago SessionHelper.php 3 years ago ValidationHelper.php 1 year ago
ValidationHelper.php
326 lines
1 <?php
2 /**
3 * Form validation helper
4 *
5 * Provides static helper methods for form validation.
6 *
7 * @package Tutor\Helper
8 * @author Themum<support@themeum.com>
9 * @link https://themeum.com
10 * @since 2.6.0
11 */
12
13 namespace Tutor\Helpers;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 return;
17 }
18
19 /**
20 * Validation class contains static methods
21 */
22 class ValidationHelper {
23
24 /**
25 * Validate array elements
26 *
27 * @since 2.6.0
28 *
29 * @param array $validation_rules associative array for validation
30 * rules. For ex: [id => 'required|number', name => 'alpha_numeric|max:255'].
31 *
32 * @param array $data key value pair of data. Note array index should
33 * exactly match with validation_rules array index.
34 *
35 * @return object validation response
36 */
37 public static function validate( array $validation_rules, array $data ): object {
38 $validation_pass = true;
39 $validation_errors = array();
40
41 foreach ( $validation_rules as $key => $validation_rule ) {
42 $rules = explode( '|', $validation_rule );
43
44 $required_rule_failed = false;
45
46 foreach ( $rules as $rule ) {
47 if ( $required_rule_failed ) {
48 break;
49 }
50
51 $nested_rules = explode( ':', $rule );
52
53 /**
54 * Optional input validation.
55 */
56 if ( isset( $nested_rules[0] ) && 'if_input' === $nested_rules[0] ) {
57 if ( ! self::has_key( $key, $data ) ) {
58 break;
59 }
60 }
61
62 foreach ( $nested_rules as $nested_rule ) {
63 switch ( $nested_rule ) {
64 case 'required':
65 if ( ! self::has_key( $key, $data ) || self::is_empty( $data[ $key ] ) ) {
66 $validation_pass = false;
67 $validation_errors[ $key ][] = $key . __( ' is required', 'tutor' );
68 $required_rule_failed = true;
69 }
70 break;
71 case 'numeric':
72 if ( ! self::is_numeric( $data[ $key ] ) ) {
73 $validation_pass = false;
74 $validation_errors[ $key ][] = $key . __( ' is not numeric', 'tutor' );
75 }
76 break;
77 /* Greater than (gt) */
78 case 'gt':
79 if ( $data[ $key ] < $nested_rules[1] ) {
80 $validation_pass = false;
81 /* translators: %1$s: field name, %2$d: value */
82 $validation_errors[ $key ][] = sprintf( __( '%1$s need to be greater than %2$d', 'tutor' ), $key, $nested_rules[1] );
83 }
84 break;
85 /* Less than (lt) */
86 case 'lt':
87 if ( $data[ $key ] > $nested_rules[1] ) {
88 $validation_pass = false;
89 /* translators: %1$s: field name, %2$d: value */
90 $validation_errors[ $key ][] = sprintf( __( '%1$s need to be less than %2$d', 'tutor' ), $key, $nested_rules[1] );
91 }
92 break;
93 case 'email':
94 if ( ! is_email( $data[ $key ] ) ) {
95 $validation_pass = false;
96 /* translators: %s: field name */
97 $validation_errors[ $key ][] = sprintf( __( '%s is not valid email', 'tutor' ), $key );
98 }
99 break;
100 case 'min_length':
101 if ( strlen( $data[ $key ] ) < $nested_rules[1] ) {
102 $validation_pass = false;
103 /* translators: %1$s: field name, %2$d: value */
104 $validation_errors[ $key ][] = sprintf( __( '%1$s minimum length is %2$d' ), $key, $nested_rule[1] );
105 }
106 break;
107 case 'max_length':
108 if ( strlen( $data[ $key ] ) > $nested_rules[1] ) {
109 $validation_pass = false;
110 /* translators: %1$s: field name, %2$d: value */
111 $validation_errors[ $key ][] = sprintf( __( '%1$s maximum length is %2$d' ), $key, $nested_rule[1] );
112 }
113 break;
114 case 'mimes':
115 $extensions = explode( ',', $nested_rules[1] );
116 if ( ! self::in_array( $data[ $key ], $extensions ) ) {
117 $validation_pass = false;
118 $validation_errors[ $key ][] = $key . __( ' extension is not valid', 'tutor' );
119 }
120 break;
121 case 'match_string':
122 $strings = explode( ',', $nested_rules[1] );
123 if ( ! self::in_array( $data[ $key ], $strings ) ) {
124 $validation_pass = false;
125 $validation_errors[ $key ][] = $key . __( ' string is not valid', 'tutor' );
126 }
127 break;
128 case 'boolean':
129 if ( ! self::is_boolean( $data[ $key ] ) ) {
130 $validation_pass = false;
131 $validation_errors[ $key ][] = $key . __( ' is not boolean', 'tutor' );
132 }
133 break;
134 case 'is_array':
135 if ( ! self::is_array( $data[ $key ] ) ) {
136 $validation_pass = false;
137 $validation_errors[ $key ][] = $key . __( ' is not an array', 'tutor' );
138 }
139 break;
140 case 'date_format':
141 $format = explode( ':', $rule, 2 )[1];
142 if ( ! self::is_valid_date( $data[ $key ], $format ) ) {
143 $validation_pass = false;
144 $validation_errors[ $key ][] = $key . __( ' invalid date format', 'tutor' );
145 }
146 break;
147
148 case 'has_record':
149 list( $table, $column ) = explode( ',', $nested_rules[1], 2 );
150
151 $value = $data[ $key ];
152 $has_record = self::has_record( $table, $column, $value );
153 if ( ! $has_record ) {
154 $validation_pass = false;
155 $validation_errors[ $key ][] = $key . __( ' record not found', 'tutor' );
156 }
157 break;
158
159 case 'user_exists':
160 $user_id = (int) $data[ $key ];
161 $is_exists = self::is_user_exists( $user_id );
162 if ( ! $is_exists ) {
163 $validation_pass = false;
164 $validation_errors[ $key ][] = $key . __( ' user does not exist', 'tutor' );
165 }
166 break;
167 default:
168 // code...
169 break;
170 }
171 }
172 }
173 }
174
175 $response = array(
176 'success' => $validation_pass,
177 'errors' => $validation_errors,
178 );
179
180 return (object) $response;
181 }
182
183 /**
184 * Check if value is numeric
185 *
186 * Rules: numeric
187 *
188 * @param mixed $value value to check.
189 *
190 * @return boolean
191 */
192 public static function is_numeric( $value ): bool {
193 return is_numeric( $value );
194 }
195
196 /**
197 * Check if value is empty
198 *
199 * Value will be considered empty if it is either null or empty string.
200 *
201 * Rules: required
202 *
203 * @param mixed $value value to check.
204 *
205 * @return boolean
206 */
207 public static function is_empty( $value ): bool {
208 return '' === $value || is_null( $value ) ? true : false;
209 }
210
211 /**
212 * Check if array has key
213 *
214 * @param string $key key to check.
215 * @param array $array_assoc array where to check.
216 *
217 * @return boolean
218 */
219 public static function has_key( string $key, array $array_assoc ): bool {
220 return isset( $array_assoc[ $key ] );
221 }
222
223 /**
224 * Check if element has in array
225 *
226 * Rules: match_string:{value1},{value2}",
227 *
228 * @param string $key key to check.
229 * @param array $array array where to check.
230 *
231 * @return boolean
232 */
233 public static function in_array( string $key, array $array ): bool {
234 return in_array( $key, $array );
235 }
236
237
238 /**
239 * The function checks if a given value is a boolean.
240 *
241 * Considered values: array( 1, 0, 'true', 'false', true, false ), any value
242 * except these will be not counted as boolean
243 *
244 * Rules: boolean
245 *
246 * @param mixed $value is the variable that will be checked if it is a boolean value or not.
247 *
248 * @return bool A boolean value is being returned, indicating whether the input value is a valid
249 * boolean or not.
250 */
251 public static function is_boolean( $value ): bool {
252 $allowed_booleans = array( 1, 0, '1', '0', 'true', 'false', true, false );
253 return in_array( $value, $allowed_booleans, true );
254 }
255
256 /**
257 * The function checks if a given value is an array.
258 *
259 * Usage: is_array:{value}
260 *
261 * @param mixed $value is the variable that will be checked if it is an array or not.
262 *
263 * @return bool A boolean value is being returned, indicating whether the input value is a valid
264 * boolean or not.
265 */
266 public static function is_array( $value ): bool {
267 return is_array( $value );
268 }
269
270 /**
271 * The function checks if a given date string is valid according to a specified format in PHP.
272 *
273 * Rules: date_format:Y-m-d
274 *
275 * @since 2.6.0
276 *
277 * @param string $date_string is a string representing a date in a specific format. For example,
278 * "2022-01-31" or "31/01/2022".
279 * @param string $format The format parameter is a string that specifies the expected format of the date
280 * string. It uses the same format as the PHP date() function, with placeholders for different parts of
281 * the date (e.g. "Y" for the year, "m" for the month, "d" for the day.
282 *
283 * @return bool A boolean value (true or false) is being returned, depending on whether the given date
284 * string is valid according to the specified format.
285 */
286 public static function is_valid_date( $date_string, $format ): bool {
287 $date_object = \DateTime::createFromFormat( $format, $date_string );
288 return $date_object && $date_object->format( $format ) === $date_string;
289 }
290
291 /**
292 * Check if user exists
293 *
294 * Rules: user_exists:{user_id}
295 *
296 * @param integer $user_id user id.
297 * @return boolean
298 */
299 public static function is_user_exists( int $user_id ): bool {
300 $user = get_user_by( 'id', $user_id );
301 return $user ? true : false;
302 }
303
304 /**
305 * Check a table has record.
306 *
307 * @since 2.7.0
308 *
309 * @param string $table table name with prefix or without.
310 * @param string $column table column name.
311 * @param mixed $value table column value.
312 *
313 * @return boolean
314 */
315 public static function has_record( $table, $column, $value ) {
316 global $wpdb;
317 $table_prefix = $wpdb->prefix;
318 if ( strpos( $table, $table_prefix ) !== 0 ) {
319 $table = $table_prefix . $table;
320 }
321
322 $record = QueryHelper::get_row( $table, array( $column => $value ), $column );
323 return $record ? true : false;
324 }
325 }
326