[ Index ]

PHP Cross Reference of GlotPress

title

Body

[close]

/gp-includes/ -> validation.php (source)

   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 to ensure Scrutinizer recognizes them.
  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: 1: Class name, 2: method name.  */
 112                  'Call to undefined method: %1$::%2$().',
 113                  esc_html( get_class( $this ) ),
 114                  esc_html( $name )
 115              ),
 116              E_USER_ERROR
 117          );
 118      }
 119  
 120  	public function run( $thing ) {
 121          $this->errors = array();
 122          $verdict      = true;
 123          foreach ( $this->field_names as $field_name ) {
 124              // Do not try to validate missing fields.
 125              if ( ! gp_object_has_var( $thing, $field_name ) ) {
 126                  continue;
 127              }
 128              $value         = $thing->$field_name;
 129              $field_verdict = $this->run_on_single_field( $field_name, $value );
 130              $verdict       = $verdict && $field_verdict;
 131          }
 132          return $verdict;
 133      }
 134  
 135  	public function run_on_single_field( $field, $value ) {
 136          if ( ! isset( $this->rules[ $field ] ) || ! is_array( $this->rules[ $field ] ) ) {
 137              // No rules means always valid.
 138              return true;
 139          }
 140          $verdict = true;
 141  
 142          foreach ( $this->rules[ $field ] as $rule ) {
 143              $callback = GP_Validators::get( $rule['rule'] );
 144              if ( is_null( $callback ) ) {
 145                  // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
 146                  trigger_error(
 147                      sprintf(
 148                          /* translators: %s: Rule. */
 149                          __( 'Non-existent validator: %s', 'glotpress' ),
 150                          esc_html( $rule['rule'] )
 151                      ),
 152                      WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
 153                  );
 154                  continue;
 155              }
 156              $args = $rule['args'];
 157              array_unshift( $args, $value );
 158              if ( 'positive' === $rule['kind'] ) {
 159                  if ( ! $callback['positive']( ...$args ) ) {
 160                      $this->errors[] = $this->construct_error_message( $rule );
 161                      $verdict        = false;
 162                  }
 163              } else {
 164                  if ( null === $callback['negative'] ) {
 165                      if ( $callback['positive']( ...$args ) ) {
 166                          $this->errors[] = $this->construct_error_message( $rule );
 167                          $verdict        = false;
 168                      }
 169                  } elseif ( ! $callback['negativ']( ...$args ) ) {
 170                      $this->errors[] = $this->construct_error_message( $rule );
 171                      $verdict        = false;
 172                  }
 173              }
 174          }
 175          return $verdict;
 176      }
 177  
 178  	public function construct_error_message( $rule ) {
 179          $type_field = 'field';
 180          $name_field = $rule['field'];
 181          $name_rule  = str_replace( '_', ' ', $rule['rule'] );
 182  
 183          if ( 1 === preg_match( '/translation_[0-9]/', $name_field ) ) {
 184              $type_field = 'textarea';
 185              $name_field = 'Translation ' . ( intval( substr( $name_field, 12 ) ) + 1 );
 186          }
 187  
 188          if ( 'positive' == $rule['kind'] ) {
 189              /* translators: 1: type of a validation field, 2: name of a validation field, 3: validation rule */
 190              return sprintf( __( 'The %1$s %2$s is invalid and should be %3$s!', 'glotpress' ), $type_field, '<strong>' . $name_field . '</strong>', $name_rule );
 191          } else { // if ( 'negative' == $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 not be %3$s!', 'glotpress' ), $type_field, '<strong>' . $name_field . '</strong>', $name_rule );
 194          }
 195      }
 196  }
 197  
 198  class GP_Validators {
 199      static $callbacks = array();
 200  
 201  	public static function register( $key, $callback, $negative_callback = null ) {
 202          // TODO: add data for easier generation of error messages
 203          self::$callbacks[ $key ] = array(
 204              'positive' => $callback,
 205              'negative' => $negative_callback,
 206          );
 207      }
 208  
 209  	public static function unregister( $key ) {
 210          unset( self::$callbacks[ $key ] );
 211      }
 212  
 213  	public static function get( $key ) {
 214          return gp_array_get( self::$callbacks, $key, null );
 215      }
 216  }
 217  
 218  GP_Validators::register( 'empty', 'gp_is_empty' );
 219  GP_Validators::register( 'empty_string', 'gp_is_empty_string' );
 220  GP_Validators::register( 'positive_int', 'gp_is_positive_int' );
 221  GP_Validators::register( 'int', 'gp_is_int' );
 222  GP_Validators::register( 'null', 'gp_is_null' );
 223  GP_Validators::register( 'between', 'gp_is_between' );
 224  GP_Validators::register( 'between_exclusive', 'gp_is_between_exclusive' );


Generated: Wed Dec 2 01:01:54 2020 Cross-referenced by PHPXref 0.7.1