Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 23 | class Schema_Class extends Singleton_Util { |
||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | /** |
||
| 28 | * Requried for Singleton_Util |
||
| 29 | * |
||
| 30 | * @since 0.1.0 |
||
| 31 | * @version 1.0.0 |
||
| 32 | */ |
||
| 33 | protected function construct() {} |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Vérifie si les données sont bien typées. Cette méthode ne force pas le typage des données. |
||
| 37 | * Renvoies des erreurs si une des données ne correspond pas au type attendu. |
||
| 38 | * |
||
| 39 | * @since 0.1.0 |
||
| 40 | * @version 1.0.0 |
||
| 41 | * |
||
| 42 | * @param array $data Toutes les données y compris les meta. |
||
| 43 | * @param array $model Le schéma. |
||
| 44 | * @param array $current_data Les données actuelles. |
||
| 45 | * @param array $errors Les erreurs de typages. |
||
| 46 | * |
||
| 47 | * @return array Les erreurs de typages. |
||
| 48 | */ |
||
| 49 | public static function check_data_from_schema( $data, $model, $current_data = null, $errors = array() ) { |
||
| 50 | $current_data = ( null === $current_data ) ? $data : $current_data; |
||
| 51 | |||
| 52 | foreach ( $model as $field_name => $field_def ) { |
||
| 53 | $value = null; |
||
| 54 | $error = null; |
||
| 55 | // Si la définition de la donnée ne contient pas "child". |
||
| 56 | if ( ! isset( $field_def['child'] ) ) { |
||
| 57 | |||
| 58 | // Si on est au premier niveau de $current_object, sinon si on est plus haut que le premier niveau. |
||
| 59 | if ( isset( $field_def['field'] ) && isset( $current_data[ $field_def['field'] ] ) ) { |
||
| 60 | $value = $current_data[ $field_def['field'] ]; |
||
| 61 | } elseif ( isset( $current_data[ $field_name ] ) && isset( $field_def ) && ! isset( $field_def['child'] ) ) { |
||
| 62 | $value = $current_data[ $field_name ]; |
||
| 63 | } |
||
| 64 | |||
| 65 | // Verifie si le champ est required. |
||
| 66 | if ( isset( $field_def['required'] ) && $field_def['required'] && null === $value ) { |
||
| 67 | $errors[] = $field_name . ' is required'; |
||
| 68 | } |
||
| 69 | |||
| 70 | // Vérifie le type de $value. |
||
| 71 | if ( null !== $value ) { |
||
| 72 | if ( ! self::check_type( $value, $field_name, $field_def['type'], $error ) ) { |
||
| 73 | $errors[] = $error; |
||
| 74 | } |
||
| 75 | } |
||
| 76 | } else { |
||
| 77 | // Values car c'est un tableau, nous sommes dans "child". Nous avons donc un tableau dans $data[ $field_name ]. |
||
| 78 | $values = ! empty( $data[ $field_name ] ) ? $data[ $field_name ] : array(); |
||
| 79 | |||
| 80 | // Récursivité sur les enfants de la définition courante. |
||
| 81 | $errors = self::check_data_from_schema( $data, $field_def['child'], $values, $errors ); |
||
| 82 | } |
||
| 83 | } |
||
| 84 | |||
| 85 | return $errors; |
||
| 86 | } |
||
| 87 | |||
| 88 | /** |
||
| 89 | * Vérifie le type de la valeur courante. |
||
| 90 | * |
||
| 91 | * @since 0.1.0 |
||
| 92 | * @version 1.0.0 |
||
| 93 | * |
||
| 94 | * @param mixed $value N'importe quel type de valeur. |
||
| 95 | * @param string $field_name Le nom du champ à vérifier. |
||
| 96 | * @param string $type Le type de la donnée à vérifier. |
||
| 97 | * @param array $error Une référence pour ajouter les messages d'erreurs. |
||
| 98 | * |
||
| 99 | * @return bool False si une erreur, sinon true. |
||
| 100 | */ |
||
| 101 | public static function check_type( $value, $field_name, $type, &$error ) { |
||
| 102 | $checked_type = true; |
||
| 103 | |||
| 104 | switch ( $type ) { |
||
| 105 | case 'string': |
||
| 106 | if ( ! is_string( $value ) ) { |
||
| 107 | $error = $field_name . ': ' . $value . '(' . gettype( $value ) . ') is not a ' . $type; |
||
| 108 | $checked_type = false; |
||
| 109 | } |
||
| 110 | break; |
||
| 111 | case 'integer': |
||
| 112 | if ( ! is_int( $value ) ) { |
||
| 113 | $error = $field_name . ': ' . $value . '(' . gettype( $value ) . ') is not a ' . $type; |
||
| 114 | $checked_type = false; |
||
| 115 | } |
||
| 116 | break; |
||
| 117 | default: |
||
| 118 | if ( empty( $type ) ) { |
||
| 119 | $error = $field_name . ': ' . $value . '(' . gettype( $value ) . ') no setted in schema. Type accepted: ' . join( ',', self::$accepted_types ); |
||
| 120 | } |
||
| 121 | |||
| 122 | if ( ! in_array( $type, self::$accepted_types, true ) ) { |
||
| 123 | $error = $field_name . ': ' . $value . '(' . gettype( $value ) . ') incorrect type: "' . $type . '". Type accepted: ' . join( ',', self::$accepted_types ); |
||
| 124 | } |
||
| 125 | |||
| 126 | $checked_type = false; |
||
| 127 | |||
| 128 | break; |
||
| 129 | } |
||
| 130 | |||
| 131 | return $checked_type; |
||
| 132 | } |
||
| 133 | } |
||
| 134 | } // End if(). |
||
| 135 |