GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
SettingsValidator.php
Go to the documentation of this file.
1 <?php
2 /**
3  * @license GPL-2.0-or-later
4  *
5  * Modified by gravityview on 13-January-2023 using Strauss.
6  * @see https://github.com/BrianHenryIE/strauss
7  */
8 
10 
15 
16 class ValidatorException extends \Exception { }
17 
19  /**
20  * @since 1.0.0
21  *
22  * @var Filesystem\Filesystem Required dependency for Illuminate\Validation.
23  */
24  private $filesystem;
25 
26  /**
27  * @since 1.0.0
28  *
29  * @var Translation\FileLoader Required dependency for Illuminate\Validation.
30  */
31  private $file_loader;
32 
33  /**
34  * @since 1.0.0
35  *
36  * @var Translation\Translator Required dependency for Illuminate\Validation.
37  */
38  private $translator;
39 
40  /**
41  * @since 1.0.0
42  *
43  * @var Validation\Factory Validator instance.
44  */
46 
47  public function __construct() {
48  $this->filesystem = new Filesystem\Filesystem();
49  $this->file_loader = new Translation\FileLoader( $this->filesystem, '' );
50  $this->translator = new Translation\Translator( $this->file_loader, '' );
51  $this->validator_factory = new Validation\Factory( $this->translator );
52 
53  $this->add_custom_validation_rules();
54  }
55 
56  /**
57  * Adds custom validation rules (these match custom Yup rules added in the UI).
58  *
59  * @since 1.0.0
60  * @see `UI/src/lib/validation.js`
61  *
62  */
63  private function add_custom_validation_rules() {
64  $this->validator_factory->extend( 'is', function ( $attribute, $value, $parameters ) {
65  if ( ! is_array( $parameters ) ) {
66  return false;
67  }
68 
69  return $value === $parameters[0];
70  } );
71 
72  $this->validator_factory->extend( 'isNot', function ( $attribute, $value, $parameters ) {
73  if ( ! is_array( $parameters ) ) {
74  return false;
75  }
76 
77  return $value !== $parameters[0];
78  } );
79 
80  // Works for array or `multiple_checkboxes` type.
81  $this->validator_factory->extend( 'has', function ( $attribute, $value, $parameters ) {
82  if ( ! is_array( $parameters ) ) {
83  return false;
84  }
85 
86 
87  return in_array( $parameters[0], $value );
88  } );
89 
90  $this->validator_factory->extend( 'matches', function ( $attribute, $value, $parameters ) {
91  if ( ! is_array( $parameters ) ) {
92  return false;
93  }
94 
95  return preg_match( '/' . $parameters[0] . '/', $value );
96  } );
97  }
98 
99  /**
100  * Performs validation.
101  *
102  * @since 1.0.0
103  *
104  * @param string $rule Validation rule (see https://laravel.com/docs/5.4/validation#available-validation-rules).
105  * @param string $value Validation value.
106  *
107  * @throws ValidatorException
108  *
109  * @return bool
110  */
111  private function run_validator( $rule, $value ) {
112  $validator = $this->validator_factory->make(
113  [ 'value' => $value ], // Value to validate.
114  [ 'value' => $rule ], // Rule.
115  [] // Validation messages; not used.
116  );
117 
118  try {
119  if ( ! $validator->fails() ) {
120  return true;
121  }
122  } catch ( \Exception $e ) {
123  throw new ValidatorException( $e->getMessage() );
124  }
125 
126  return false;
127  }
128 
129  /**
130  * Validates settings.
131  *
132  * @since 1.0.0
133  *
134  * @param string $plugin Plugin ID.
135  * @param array $original_settings Flattened settings object (i.e., not split by sections) as defined by the plugin (see `gk/foundation/settings/data/plugins` filter).
136  * @param array $settings_to_validate Setting/value pair to validate.
137  *
138  * @throws ValidatorException
139  *
140  * @return bool
141  */
142  public function validate( $plugin, array $original_settings, array $settings_to_validate ) {
143  $validated_settings = [];
144 
145  $missing_settings = array_keys( array_diff_key( $original_settings, $settings_to_validate ) );
146 
147  if ( $missing_settings ) {
148  $missing_settings_title = array_map( function ( $setting ) use ( $original_settings ) {
149  return $original_settings[ $setting ]['title'];
150  }, $missing_settings );
151 
152  throw new ValidatorException(
153  strtr(
154  esc_html_x( 'Missing settings: [settings].', 'Placeholders inside [] are not to be translated.', 'gk-gravityview' ),
155  [ '[settings]' => implode( ', ', $missing_settings_title ) ]
156  )
157  );
158  }
159 
160  foreach ( $original_settings as $setting ) {
161  $value_to_validate = $settings_to_validate[ $setting['id'] ];
162 
163  if ( empty( $setting['validation'] ) ) {
164  /**
165  * @action `gk/foundation/settings/{plugin}/validation/{setting_id}` Runs when validation rules are not specified and before the setting is marked as validated.
166  *
167  * @since 1.0.0
168  *
169  * @param array $setting Original setting.
170  * @param string $value_to_validate Value to validate.
171  */
172  do_action( "gk/foundation/settings/${plugin}/validation/${setting['id']}", $setting, $value_to_validate );
173 
174  $validated_settings[ $setting['id'] ] = $value_to_validate;
175 
176  continue;
177  }
178 
179  // Validation can be a callback.
180  if ( CoreHelpers::is_callable_function( $setting['validation'] ) ) {
181  call_user_func( $setting['validation'], $setting, $value_to_validate );
182 
183  $validated_settings[ $setting['id'] ] = $value_to_validate;
184 
185  continue;
186  }
187 
188  // Convert validation object to a multidimensional array.
189  $validation_rules = empty( $setting['validation'][0] ) ? [ $setting['validation'] ] : $setting['validation'];
190 
191  $is_valid = true;
192  foreach ( $validation_rules as $validation_rule ) {
193  if ( empty( $validation_rule['rule'] ) ) {
194  throw new ValidatorException(
195  strtr(
196  esc_html_x( 'Validation rule for setting [setting] is missing.', 'Placeholders inside [] are not to be translated.', 'gk-gravityview' ),
197  [ '[setting]' => $setting['id'] ]
198 
199  )
200  );
201  }
202 
203  try {
204  if ( ! $this->run_validator( $validation_rule['rule'], $value_to_validate ) ) {
205  $is_valid = false;
206 
207  break;
208  }
209  } catch ( ValidatorException $e ) {
210  throw new ValidatorException(
211  strtr(
212  esc_html_x( 'Validation for setting [setting] failed: [reason].', 'Placeholders inside [] are not to be translated.', 'gk-gravityview' ),
213  [
214  '[setting]' => $setting['id'],
215  '[reason]' => $e->getMessage()
216  ]
217  )
218  );
219  }
220  }
221 
222  if ( $is_valid ) {
223  $validated_settings[ $setting['id'] ] = $value_to_validate;
224  }
225  }
226 
227  $settings_failed_validation = array_keys( array_diff_key( $settings_to_validate, $validated_settings ) );
228 
229  if ( ! empty( $settings_failed_validation ) ) {
230  throw new ValidatorException(
231  strtr(
232  esc_html_x( 'Settings that failed validation: [settings].', 'Placeholders inside [] are not to be translated.', 'gk-gravityview' ),
233  [ '[settings]' => implode( ', ', $settings_failed_validation ) ]
234  )
235  );
236  }
237 
238  return true;
239  }
240 }
validate( $plugin, array $original_settings, array $settings_to_validate)
Validates settings.
add_custom_validation_rules()
Adds custom validation rules (these match custom Yup rules added in the UI).