[ Index ] |
PHP Cross Reference of GlotPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Translation Validation API 4 * 5 * @package GlotPress 6 * @since 1.0.0 7 */ 8 9 /** 10 * Core class to handle validation of translations. 11 * 12 * Uses magic methods in the format of [field]_[rule]. 13 * 14 * The below is a list of all magic methods called. 15 * Note that once a method has been defined from one file it will not be redefine in subsequent file sections. 16 * 17 * From gp_includes/things/administrative-permissions.php: 18 * 19 * @method bool user_id_should_not_be( string $name, array $args = null ) 20 * @method bool action_should_not_be( string $name, array $args = null ) 21 * @method bool object_type_should_be( string $name, array $args = null ) 22 * @method bool object_id_should_be( string $name, array $args = null ) 23 * 24 * From gp_includes/things/glossary-entry.php: 25 * 26 * @method bool term_should_not_be( string $name, array $args = null ) 27 * @method bool part_of_speech_should_not_be( string $name, array $args = null ) 28 * @method bool glossary_id_should_be( string $name, array $args = null ) 29 * @method bool last_edited_by_should_be( string $name, array $args = null ) 30 * 31 * From gp_includes/things/original.php: 32 * 33 * @method bool singular_should_not_be( string $name, array $args = null ) 34 * @method bool status_should_not_be( string $name, array $args = null ) 35 * @method bool project_id_should_be( string $name, array $args = null ) 36 * @method bool priority_should_be( string $name, array $args = null ) 37 * 38 * From gp_includes/things/translation.php: 39 * 40 * @method bool translation_0_should_not_be( string $name, array $args = null ) 41 * @method bool original_id_should_be( string $name, array $args = null ) 42 * @method bool translation_set_id_should_be( string $name, array $args = null ) 43 * @method bool user_id_should_be( string $name, array $args = null ) 44 * @method bool user_id_last_modified_should_not_be( string $name, array $args = null ) 45 * 46 * From gp_includes/things/glossary.php: 47 * 48 * @method bool translation_set_id_should_not_be( string $name, array $args = null ) 49 * 50 * From gp_includes/things/project.php: 51 * 52 * @method bool name_should_not_be( string $name, array $args = null ) 53 * @method bool slug_should_not_be( string $name, array $args = null ) 54 * 55 * From gp_includes/things/translation-set.php: 56 * 57 * @method bool locale_should_not_be( string $name, array $args = null ) 58 * @method bool project_id_should_not_be( string $name, array $args = null ) 59 * 60 * From gp_includes/things/validator-permission.php: 61 * 62 * @method bool locale_slug_should_not_be( string $name, array $args = null ) 63 * @method bool user_id_should_not_be( string $name, array $args = null ) 64 * @method bool action_should_not_be( string $name, array $args = null ) 65 * @method bool set_slug_should_not_be( string $name, array $args = null ) 66 */ 67 class GP_Validation_Rules { 68 69 var $rules = array(); 70 71 public $errors = array(); 72 public $field_names; 73 74 static $positive_suffices = array( 75 'should_be', 76 'should', 77 'can', 78 'can_be', 79 ); 80 static $negative_suffices = array( 81 'should_not_be', 82 'should_not', 83 'cant', 84 'cant_be', 85 ); 86 87 public function __construct( $field_names ) { 88 $this->field_names = $field_names; 89 } 90 91 public function __call( $name, $args ) { 92 foreach ( array( 'positive', 'negative' ) as $kind ) { 93 $suffices = "{$kind}_suffices"; 94 foreach ( self::$$suffices as $suffix ) { 95 foreach ( $this->field_names as $field_name ) { 96 if ( "{$field_name}_{$suffix}" == $name ) { 97 $this->rules[ $field_name ][] = array( 98 'field' => $field_name, 99 'rule' => $args[0], 100 'kind' => $kind, 101 'args' => array_slice( $args, 1 ), 102 ); 103 return true; 104 } 105 } 106 } 107 } 108 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error 109 trigger_error( 110 sprintf( 111 /* translators: %s: Method name. */ 112 esc_html__( 'Call to undefined method: %s.', 'glotpress' ), 113 sprintf( 114 '%1$s::%2$s()', 115 esc_html( get_class( $this ) ), 116 esc_html( $name ) 117 ) 118 ), 119 E_USER_ERROR 120 ); 121 } 122 123 public function run( $thing ) { 124 $this->errors = array(); 125 $verdict = true; 126 foreach ( $this->field_names as $field_name ) { 127 // Do not try to validate missing fields. 128 if ( ! gp_object_has_var( $thing, $field_name ) ) { 129 continue; 130 } 131 $value = $thing->$field_name; 132 $field_verdict = $this->run_on_single_field( $field_name, $value ); 133 $verdict = $verdict && $field_verdict; 134 } 135 return $verdict; 136 } 137 138 public function run_on_single_field( $field, $value ) { 139 if ( ! isset( $this->rules[ $field ] ) || ! is_array( $this->rules[ $field ] ) ) { 140 // No rules means always valid. 141 return true; 142 } 143 $verdict = true; 144 145 foreach ( $this->rules[ $field ] as $rule ) { 146 $callback = GP_Validators::get( $rule['rule'] ); 147 if ( is_null( $callback ) ) { 148 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error 149 trigger_error( 150 sprintf( 151 /* translators: %s: Rule. */ 152 __( 'Non-existent validator: %s', 'glotpress' ), 153 esc_html( $rule['rule'] ) 154 ), 155 WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE 156 ); 157 continue; 158 } 159 $args = $rule['args']; 160 array_unshift( $args, $value ); 161 if ( 'positive' === $rule['kind'] ) { 162 if ( ! $callback['positive']( ...$args ) ) { 163 $this->errors[] = $this->construct_error_message( $rule ); 164 $verdict = false; 165 } 166 } else { 167 if ( null === $callback['negative'] ) { 168 if ( $callback['positive']( ...$args ) ) { 169 $this->errors[] = $this->construct_error_message( $rule ); 170 $verdict = false; 171 } 172 } elseif ( ! $callback['negative']( ...$args ) ) { 173 $this->errors[] = $this->construct_error_message( $rule ); 174 $verdict = false; 175 } 176 } 177 } 178 return $verdict; 179 } 180 181 public function construct_error_message( $rule ) { 182 $type_field = 'field'; 183 $name_field = $rule['field']; 184 $name_rule = str_replace( '_', ' ', $rule['rule'] ); 185 186 if ( 1 === preg_match( '/translation_[0-9]/', $name_field ) ) { 187 $type_field = 'textarea'; 188 $name_field = 'Translation ' . ( intval( substr( $name_field, 12 ) ) + 1 ); 189 } 190 191 if ( 'positive' == $rule['kind'] ) { 192 /* translators: 1: type of a validation field, 2: name of a validation field, 3: validation rule */ 193 return sprintf( __( 'The %1$s %2$s is invalid and should be %3$s!', 'glotpress' ), $type_field, '<strong>' . $name_field . '</strong>', $name_rule ); 194 } else { // if ( 'negative' == $rule['kind'] ) 195 /* translators: 1: type of a validation field, 2: name of a validation field, 3: validation rule */ 196 return sprintf( __( 'The %1$s %2$s is invalid and should not be %3$s!', 'glotpress' ), $type_field, '<strong>' . $name_field . '</strong>', $name_rule ); 197 } 198 } 199 } 200 201 class GP_Validators { 202 static $callbacks = array(); 203 204 public static function register( $key, $callback, $negative_callback = null ) { 205 // TODO: add data for easier generation of error messages 206 self::$callbacks[ $key ] = array( 207 'positive' => $callback, 208 'negative' => $negative_callback, 209 ); 210 } 211 212 public static function unregister( $key ) { 213 unset( self::$callbacks[ $key ] ); 214 } 215 216 public static function get( $key ) { 217 return gp_array_get( self::$callbacks, $key, null ); 218 } 219 } 220 221 GP_Validators::register( 'empty', 'gp_is_empty' ); 222 GP_Validators::register( 'empty_string', 'gp_is_empty_string' ); 223 GP_Validators::register( 'positive_int', 'gp_is_positive_int' ); 224 GP_Validators::register( 'int', 'gp_is_int' ); 225 GP_Validators::register( 'null', 'gp_is_null' ); 226 GP_Validators::register( 'between', 'gp_is_between' ); 227 GP_Validators::register( 'between_exclusive', 'gp_is_between_exclusive' ); 228 GP_Validators::register( 'one_of', 'gp_is_one_of' ); 229 GP_Validators::register( 'consisting_only_of_ASCII_characters', 'gp_is_ascii_string' ); 230 GP_Validators::register( 'starting_and_ending_with_a_word_character', 'gp_is_starting_and_ending_with_a_word_character' );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:01:07 2024 | Cross-referenced by PHPXref 0.7.1 |