| @@ -1,13 +1,8 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Elementor\Modules\Interactions; |
| 4 | 4 | |
| 5 | -use Elementor\Modules\Interactions\Validators\Breakpoints_Value as BreakpointsValueValidator; | |
| 6 | -use Elementor\Modules\Interactions\Validators\Custom_Effect_Value; | |
| 7 | -use Elementor\Modules\Interactions\Validators\String_Value as StringValueValidator; | |
| 8 | -use Elementor\Modules\Interactions\Validators\Trigger_Value as TriggerValueValidator; | |
| 9 | - | |
| 10 | 5 | if ( ! defined( 'ABSPATH' ) ) { |
| 11 | 6 | exit; // Exit if accessed directly. |
| 12 | 7 | } |
| 13 | 8 | |
| @@ -14,12 +9,12 @@ | ||
| 14 | 9 | class Validation { |
| 15 | 10 | private $elements_to_interactions_counter = []; |
| 16 | 11 | private $max_number_of_interactions = 5; |
| 17 | 12 | |
| 18 | - private const VALID_EFFECTS = [ 'fade', 'slide', 'scale', 'custom' ]; | |
| 13 | + private const VALID_TRIGGERS = [ 'load', 'scrollIn', 'scrollOut', 'scrollOn' ]; | |
| 14 | + private const VALID_EFFECTS = [ 'fade', 'slide', 'scale' ]; | |
| 19 | 15 | private const VALID_TYPES = [ 'in', 'out' ]; |
| 20 | - private const VALID_DIRECTIONS = [ '', 'left', 'right', 'top', 'bottom', 'top-left', 'top-right', 'bottom-left', 'bottom-right' ]; | |
| 21 | - private const VALID_REPEAT_MODES = [ '', 'loop', 'times' ]; | |
| 16 | + private const VALID_DIRECTIONS = [ '', 'left', 'right', 'top', 'bottom' ]; | |
| 22 | 17 | |
| 23 | 18 | public function sanitize( $document ) { |
| 24 | 19 | return $this->sanitize_document_data( $document ); |
| 25 | 20 | } |
| @@ -68,11 +63,8 @@ | ||
| 68 | 63 | } |
| 69 | 64 | |
| 70 | 65 | private function decode_interactions( $interactions ) { |
| 71 | 66 | if ( is_array( $interactions ) ) { |
| 72 | - if ( isset( $interactions['items']['$$type'] ) && 'array' === $interactions['items']['$$type'] ) { | |
| 73 | - return isset( $interactions['items']['value'] ) ? $interactions['items']['value'] : []; | |
| 74 | - } | |
| 75 | 67 | return isset( $interactions['items'] ) ? $interactions['items'] : []; |
| 76 | 68 | } |
| 77 | 69 | |
| 78 | 70 | if ( is_string( $interactions ) ) { |
| @@ -77,11 +69,8 @@ | ||
| 77 | 69 | |
| 78 | 70 | if ( is_string( $interactions ) ) { |
| 79 | 71 | $decoded = json_decode( $interactions, true ); |
| 80 | 72 | if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) { |
| 81 | - if ( isset( $decoded['items']['$$type'] ) && 'array' === $decoded['items']['$$type'] ) { | |
| 82 | - return isset( $decoded['items']['value'] ) ? $decoded['items']['value'] : []; | |
| 83 | - } | |
| 84 | 73 | return isset( $decoded['items'] ) ? $decoded['items'] : []; |
| 85 | 74 | } |
| 86 | 75 | } |
| 87 | 76 | |
| @@ -140,9 +129,9 @@ | ||
| 140 | 129 | if ( isset( $value['interaction_id'] ) && ! $this->is_valid_string_prop( $value, 'interaction_id' ) ) { |
| 141 | 130 | return false; |
| 142 | 131 | } |
| 143 | 132 | |
| 144 | - if ( ! $this->is_valid_trigger_prop( $value ) ) { | |
| 133 | + if ( ! $this->is_valid_string_prop( $value, 'trigger', self::VALID_TRIGGERS ) ) { | |
| 145 | 134 | return false; |
| 146 | 135 | } |
| 147 | 136 | |
| 148 | 137 | if ( ! $this->is_valid_animation_prop( $value ) ) { |
| @@ -148,37 +137,31 @@ | ||
| 148 | 137 | if ( ! $this->is_valid_animation_prop( $value ) ) { |
| 149 | 138 | return false; |
| 150 | 139 | } |
| 151 | 140 | |
| 152 | - if ( ! $this->is_valid_breakpoints_prop( $value ) ) { | |
| 153 | - return false; | |
| 154 | - } | |
| 155 | - | |
| 156 | 141 | return true; |
| 157 | 142 | } |
| 158 | 143 | |
| 159 | - private function is_valid_trigger_prop( $data ) { | |
| 160 | - if ( ! array_key_exists( 'trigger', $data ) ) { | |
| 144 | + private function is_valid_string_prop( $data, $key, $allowed_values = null ) { | |
| 145 | + if ( ! isset( $data[ $key ] ) || ! is_array( $data[ $key ] ) ) { | |
| 161 | 146 | return false; |
| 162 | 147 | } |
| 163 | 148 | |
| 164 | - return TriggerValueValidator::is_valid( $data['trigger'] ); | |
| 165 | - } | |
| 149 | + $prop = $data[ $key ]; | |
| 166 | 150 | |
| 167 | - private function is_valid_breakpoints_prop( $data ) { | |
| 168 | - if ( array_key_exists( 'breakpoints', $data ) ) { | |
| 169 | - return BreakpointsValueValidator::is_valid( $data['breakpoints'] ); | |
| 151 | + if ( ! isset( $prop['$$type'] ) || 'string' !== $prop['$$type'] ) { | |
| 152 | + return false; | |
| 170 | 153 | } |
| 171 | 154 | |
| 172 | - return true; | |
| 173 | - } | |
| 155 | + if ( ! isset( $prop['value'] ) || ! is_string( $prop['value'] ) ) { | |
| 156 | + return false; | |
| 157 | + } | |
| 174 | 158 | |
| 175 | - private function is_valid_string_prop( $data, $key, $allowed_values = null ) { | |
| 176 | - if ( ! isset( $data[ $key ] ) ) { | |
| 159 | + if ( null !== $allowed_values && ! in_array( $prop['value'], $allowed_values, true ) ) { | |
| 177 | 160 | return false; |
| 178 | 161 | } |
| 179 | 162 | |
| 180 | - return StringValueValidator::is_valid( $data[ $key ], $allowed_values ); | |
| 163 | + return true; | |
| 181 | 164 | } |
| 182 | 165 | |
| 183 | 166 | private function is_valid_boolean_prop( $data, $key ) { |
| 184 | 167 | if ( ! isset( $data[ $key ] ) || ! is_array( $data[ $key ] ) ) { |
| @@ -238,35 +221,33 @@ | ||
| 238 | 221 | if ( ! isset( $data['config'] ) || ! is_array( $data['config'] ) ) { |
| 239 | 222 | return false; |
| 240 | 223 | } |
| 241 | 224 | |
| 242 | - $config_value = $data['config']['value']; | |
| 225 | + $config = $data['config']; | |
| 243 | 226 | |
| 244 | - if ( isset( $config_value['replay'] ) && ! $this->is_valid_boolean_prop( $config_value, 'replay' ) ) { | |
| 227 | + if ( ! isset( $config['$$type'] ) || 'config' !== $config['$$type'] ) { | |
| 245 | 228 | return false; |
| 246 | 229 | } |
| 247 | 230 | |
| 248 | - if ( isset( $config_value['easing'] ) && ! $this->is_valid_string_prop( $config_value, 'easing' ) ) { | |
| 231 | + if ( ! isset( $config['value'] ) || ! is_array( $config['value'] ) ) { | |
| 249 | 232 | return false; |
| 250 | 233 | } |
| 251 | 234 | |
| 252 | - if ( isset( $config_value['relativeTo'] ) && ! $this->is_valid_string_prop( $config_value, 'relativeTo' ) ) { | |
| 253 | - return false; | |
| 254 | - } | |
| 235 | + $config_value = $config['value']; | |
| 255 | 236 | |
| 256 | - if ( isset( $config_value['repeat'] ) && ! $this->is_valid_string_prop( $config_value, 'repeat', self::VALID_REPEAT_MODES ) ) { | |
| 237 | + if ( isset( $config_value['replay'] ) && ! $this->is_valid_boolean_prop( $config_value, 'replay' ) ) { | |
| 257 | 238 | return false; |
| 258 | 239 | } |
| 259 | 240 | |
| 260 | - if ( isset( $config_value['times'] ) && ! $this->is_valid_number_prop_in_range( $config_value, 'times', 1 ) ) { | |
| 241 | + if ( isset( $config_value['relativeTo'] ) && ! $this->is_valid_string_prop( $config_value, 'relativeTo' ) ) { | |
| 261 | 242 | return false; |
| 262 | 243 | } |
| 263 | 244 | |
| 264 | - if ( isset( $config_value['start'] ) && ! $this->is_valid_size_prop_in_range( $config_value, 'start', 0, 100 ) ) { | |
| 245 | + if ( isset( $config_value['offsetTop'] ) && ! $this->is_valid_number_prop_in_range( $config_value, 'offsetTop', 0, 100 ) ) { | |
| 265 | 246 | return false; |
| 266 | 247 | } |
| 267 | 248 | |
| 268 | - if ( isset( $config_value['end'] ) && ! $this->is_valid_size_prop_in_range( $config_value, 'end', 0, 100 ) ) { | |
| 249 | + if ( isset( $config_value['offsetBottom'] ) && ! $this->is_valid_number_prop_in_range( $config_value, 'offsetBottom', 0, 100 ) ) { | |
| 269 | 250 | return false; |
| 270 | 251 | } |
| 271 | 252 | |
| 272 | 253 | return true; |
| @@ -312,12 +293,8 @@ | ||
| 312 | 293 | if ( isset( $animation_value['config'] ) && ! $this->is_valid_config_prop( $animation_value ) ) { |
| 313 | 294 | return false; |
| 314 | 295 | } |
| 315 | 296 | |
| 316 | - if ( ! Custom_Effect_Value::is_valid( $animation_value ) ) { | |
| 317 | - return false; | |
| 318 | - } | |
| 319 | - | |
| 320 | 297 | return true; |
| 321 | 298 | } |
| 322 | 299 | |
| 323 | 300 | private function is_valid_timing_config( $data ) { |
| @@ -336,79 +313,15 @@ | ||
| 336 | 313 | } |
| 337 | 314 | |
| 338 | 315 | $timing_value = $timing['value']; |
| 339 | 316 | |
| 340 | - // Validate duration (accepts both 'number' and 'size' formats) | |
| 341 | - if ( ! $this->is_valid_timing_value( $timing_value, 'duration', 0 ) ) { | |
| 317 | + // Validate duration | |
| 318 | + if ( ! $this->is_valid_number_prop( $timing_value, 'duration' ) ) { | |
| 342 | 319 | return false; |
| 343 | 320 | } |
| 344 | 321 | |
| 345 | - // Validate delay (accepts both 'number' and 'size' formats) | |
| 346 | - if ( ! $this->is_valid_timing_value( $timing_value, 'delay', 0 ) ) { | |
| 347 | - return false; | |
| 348 | - } | |
| 349 | - | |
| 350 | - return true; | |
| 351 | - } | |
| 352 | - | |
| 353 | - /** | |
| 354 | - * Validate timing value that can be either 'number' or 'size' type. | |
| 355 | - * - number format: {$$type: 'number', value: 123} | |
| 356 | - * - size format: {$$type: 'size', value: {size: 123, unit: 'ms'}} | |
| 357 | - */ | |
| 358 | - private function is_valid_timing_value( $data, $key, $min = null, $max = null ) { | |
| 359 | - if ( ! isset( $data[ $key ] ) || ! is_array( $data[ $key ] ) ) { | |
| 360 | - return false; | |
| 361 | - } | |
| 362 | - | |
| 363 | - $prop = $data[ $key ]; | |
| 364 | - | |
| 365 | - if ( ! isset( $prop['$$type'] ) ) { | |
| 366 | - return false; | |
| 367 | - } | |
| 368 | - | |
| 369 | - // Accept 'number' format | |
| 370 | - if ( 'number' === $prop['$$type'] ) { | |
| 371 | - return $this->is_valid_number_prop_in_range( $data, $key, $min, $max ); | |
| 372 | - } | |
| 373 | - | |
| 374 | - // Accept 'size' format | |
| 375 | - if ( 'size' === $prop['$$type'] ) { | |
| 376 | - return $this->is_valid_size_prop_in_range( $data, $key, $min, $max ); | |
| 377 | - } | |
| 378 | - | |
| 379 | - return false; | |
| 380 | - } | |
| 381 | - | |
| 382 | - /** | |
| 383 | - * Validate size prop: {$$type: 'size', value: {size: X, unit: 'ms'}} | |
| 384 | - */ | |
| 385 | - private function is_valid_size_prop_in_range( $data, $key, $min = null, $max = null ) { | |
| 386 | - if ( ! isset( $data[ $key ] ) || ! is_array( $data[ $key ] ) ) { | |
| 387 | - return false; | |
| 388 | - } | |
| 389 | - | |
| 390 | - $prop = $data[ $key ]; | |
| 391 | - | |
| 392 | - if ( ! isset( $prop['$$type'] ) || 'size' !== $prop['$$type'] ) { | |
| 393 | - return false; | |
| 394 | - } | |
| 395 | - | |
| 396 | - if ( ! isset( $prop['value'] ) || ! is_array( $prop['value'] ) ) { | |
| 397 | - return false; | |
| 398 | - } | |
| 399 | - | |
| 400 | - if ( ! isset( $prop['value']['size'] ) || ! is_numeric( $prop['value']['size'] ) ) { | |
| 401 | - return false; | |
| 402 | - } | |
| 403 | - | |
| 404 | - $value = (float) $prop['value']['size']; | |
| 405 | - | |
| 406 | - if ( null !== $min && $value < $min ) { | |
| 407 | - return false; | |
| 408 | - } | |
| 409 | - | |
| 410 | - if ( null !== $max && $value > $max ) { | |
| 322 | + // Validate delay | |
| 323 | + if ( ! $this->is_valid_number_prop( $timing_value, 'delay' ) ) { | |
| 411 | 324 | return false; |
| 412 | 325 | } |
| 413 | 326 | |
| 414 | 327 | return true; |