AtLeastOneTriggerRule.php
3 years ago
ConsistentStepMapRule.php
3 years ago
NoCycleRule.php
2 years ago
NoDuplicateEdgesRule.php
2 years ago
NoJoinRule.php
2 years ago
NoUnreachableStepsRule.php
2 years ago
TriggerNeedsToBeFollowedByActionRule.php
2 years ago
TriggersUnderRootRule.php
2 years ago
UnknownStepRule.php
3 years ago
ValidStepArgsRule.php
3 years ago
ValidStepFiltersRule.php
2 years ago
ValidStepOrderRule.php
3 years ago
ValidStepRule.php
2 months ago
ValidStepValidationRule.php
3 years ago
index.php
3 years ago
ValidStepRule.php
140 lines
| 1 | <?php declare(strict_types = 1); |
| 2 | |
| 3 | namespace MailPoet\Automation\Engine\Validation\AutomationRules; |
| 4 | |
| 5 | if (!defined('ABSPATH')) exit; |
| 6 | |
| 7 | |
| 8 | use MailPoet\Automation\Engine\Data\Automation; |
| 9 | use MailPoet\Automation\Engine\Exceptions; |
| 10 | use MailPoet\Automation\Engine\Exceptions\UnexpectedValueException; |
| 11 | use MailPoet\Automation\Engine\Validation\AutomationGraph\AutomationNode; |
| 12 | use MailPoet\Automation\Engine\Validation\AutomationGraph\AutomationNodeVisitor; |
| 13 | use MailPoet\Validator\ValidationException; |
| 14 | use Throwable; |
| 15 | |
| 16 | class ValidStepRule implements AutomationNodeVisitor { |
| 17 | /** @var AutomationNodeVisitor[] */ |
| 18 | private $rules; |
| 19 | |
| 20 | /** @var array<string, array{step_id: string, message?: string, fields: array<string, string>, filters: array<string, string>}> */ |
| 21 | private $errors = []; |
| 22 | |
| 23 | /** @param AutomationNodeVisitor[] $rules */ |
| 24 | public function __construct( |
| 25 | array $rules |
| 26 | ) { |
| 27 | $this->rules = $rules; |
| 28 | } |
| 29 | |
| 30 | public function initialize(Automation $automation): void { |
| 31 | if (!$automation->needsFullValidation()) { |
| 32 | return; |
| 33 | } |
| 34 | |
| 35 | foreach ($this->rules as $rule) { |
| 36 | $rule->initialize($automation); |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | public function visitNode(Automation $automation, AutomationNode $node): void { |
| 41 | if (!$automation->needsFullValidation()) { |
| 42 | return; |
| 43 | } |
| 44 | |
| 45 | foreach ($this->rules as $rule) { |
| 46 | $stepId = $node->getStep()->getId(); |
| 47 | try { |
| 48 | $rule->visitNode($automation, $node); |
| 49 | } catch (UnexpectedValueException $e) { |
| 50 | if (!isset($this->errors[$stepId])) { |
| 51 | $this->errors[$stepId] = ['step_id' => $stepId, 'message' => $e->getMessage(), 'fields' => [], 'filters' => []]; |
| 52 | } |
| 53 | $this->errors[$stepId]['fields'] = array_merge( |
| 54 | $this->mapErrorCodesToErrorMessages($e->getErrors()), |
| 55 | $this->errors[$stepId]['fields'] |
| 56 | ); |
| 57 | } catch (ValidationException $e) { |
| 58 | if (!isset($this->errors[$stepId])) { |
| 59 | $this->errors[$stepId] = ['step_id' => $stepId, 'message' => $e->getMessage(), 'fields' => [], 'filters' => []]; |
| 60 | } |
| 61 | |
| 62 | $key = $rule instanceof ValidStepFiltersRule ? 'filters' : 'fields'; |
| 63 | $this->errors[$stepId][$key] = array_merge( |
| 64 | $this->mapErrorCodesToErrorMessages($e->getErrors()), |
| 65 | $this->errors[$stepId][$key] |
| 66 | ); |
| 67 | } catch (Throwable $e) { |
| 68 | if (!isset($this->errors[$stepId])) { |
| 69 | $this->errors[$stepId] = ['step_id' => $stepId, 'message' => __('Unknown error.', 'mailpoet'), 'fields' => [], 'filters' => []]; |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | private function mapErrorCodesToErrorMessages(array $errorCodes): array { |
| 76 | |
| 77 | return array_map( |
| 78 | function(string $errorCode): string { |
| 79 | switch ($errorCode) { |
| 80 | case "rest_property_required": |
| 81 | return __('This is a required field.', 'mailpoet'); |
| 82 | case "rest_additional_properties_forbidden": |
| 83 | case "rest_too_few_properties": |
| 84 | case "rest_too_many_properties": |
| 85 | return ""; |
| 86 | case "rest_invalid_type": |
| 87 | case "rest_invalid_multiple": |
| 88 | case "rest_not_in_enum": |
| 89 | return __('This field is not well formed.', 'mailpoet'); |
| 90 | case "rest_too_few_items": |
| 91 | return __('Please add more items.', 'mailpoet'); |
| 92 | case "rest_too_many_items": |
| 93 | return __('Please remove some items.', 'mailpoet'); |
| 94 | case "rest_duplicate_items": |
| 95 | return __('Please remove duplicate items.', 'mailpoet'); |
| 96 | case "rest_out_of_bounds": |
| 97 | return __('This value is out of bounds.', 'mailpoet'); |
| 98 | case "rest_too_short": |
| 99 | return __('This value is not long enough.', 'mailpoet'); |
| 100 | case "rest_too_long": |
| 101 | return __('This value is too long.', 'mailpoet'); |
| 102 | case "rest_invalid_pattern": |
| 103 | return __('This value is not well formed.', 'mailpoet'); |
| 104 | case "rest_no_matching_schema": |
| 105 | return __('This value does not match the expected format.', 'mailpoet'); |
| 106 | case "rest_one_of_multiple_matches": |
| 107 | return __('This value is not matching the correct times.', 'mailpoet'); |
| 108 | case "rest_invalid_hex_color": |
| 109 | return __('This value is not a hex formatted color.', 'mailpoet'); |
| 110 | case "rest_invalid_date": |
| 111 | return __('This value is not a date.', 'mailpoet'); |
| 112 | case "rest_invalid_email": |
| 113 | return __('This value is not an email address.', 'mailpoet'); |
| 114 | case "rest_invalid_ip": |
| 115 | return __('This value is not an IP address.', 'mailpoet'); |
| 116 | case "rest_invalid_uuid": |
| 117 | return __('This value is not an UUID.', 'mailpoet'); |
| 118 | default: |
| 119 | return $errorCode; |
| 120 | } |
| 121 | }, |
| 122 | $errorCodes |
| 123 | ); |
| 124 | } |
| 125 | |
| 126 | public function complete(Automation $automation): void { |
| 127 | if (!$automation->needsFullValidation()) { |
| 128 | return; |
| 129 | } |
| 130 | |
| 131 | foreach ($this->rules as $rule) { |
| 132 | $rule->complete($automation); |
| 133 | } |
| 134 | |
| 135 | if ($this->errors) { |
| 136 | throw Exceptions::automationNotValid(__('Some steps are not valid', 'mailpoet'), $this->errors); |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 |