← All changes
|
modules/mcp/abilities/utils/composition-compiler.php
+84
-18
4.3.0-beta1
→
4.3.2
View file →
| @@ -33,9 +33,8 @@ | ||
| 33 | 33 | final class Composition_Compiler { |
| 34 | 34 | |
| 35 | 35 | private const DEFAULT_PARENT_ID = 'document'; |
| 36 | 36 | private const DOCUMENT_ROOT_WRAPPER = 'e-div-block'; |
| 37 | - private const COMPONENT_INSTANCE_WIDGET_TYPE = 'e-component'; | |
| 38 | 37 | |
| 39 | 38 | public const COMPONENT_PARENT_ID = 'component'; |
| 40 | 39 | |
| 41 | 40 | public static function make(): self { |
| @@ -64,22 +63,24 @@ | ||
| 64 | 63 | if ( is_wp_error( $dom ) ) { |
| 65 | 64 | return $dom; |
| 66 | 65 | } |
| 67 | 66 | |
| 68 | - $form_structure_error = ( new Form_Structure_Validator( $xml_parser ) )->validate( | |
| 67 | + [ | |
| 68 | + 'configs' => $widget_configs, | |
| 69 | + 'unknown_tag_errors' => $unknown_widget_tag_errors, | |
| 70 | + ] = $type_resolver->collect_referenced_widget_configs( $dom ); | |
| 71 | + | |
| 72 | + $validation_error = $this->validate_xml_before_apply( | |
| 69 | 73 | $dom, |
| 74 | + $xml_parser, | |
| 70 | 75 | $document_tree, |
| 71 | - $parent_id | |
| 76 | + $parent_id, | |
| 77 | + $unknown_widget_tag_errors | |
| 72 | 78 | ); |
| 73 | - if ( $form_structure_error ) { | |
| 74 | - return $form_structure_error; | |
| 79 | + if ( $validation_error ) { | |
| 80 | + return $validation_error; | |
| 75 | 81 | } |
| 76 | 82 | |
| 77 | - $widget_configs = $type_resolver->collect_used( $dom ); | |
| 78 | - if ( is_wp_error( $widget_configs ) ) { | |
| 79 | - return $widget_configs; | |
| 80 | - } | |
| 81 | - | |
| 82 | 83 | $wrapping_result = $this->wrap_document_root_content( $dom, $widget_configs, $parent_id, $type_resolver, $xml_parser ); |
| 83 | 84 | if ( is_wp_error( $wrapping_result ) ) { |
| 84 | 85 | return $wrapping_result; |
| 85 | 86 | } |
| @@ -85,11 +86,15 @@ | ||
| 85 | 86 | } |
| 86 | 87 | |
| 87 | 88 | $widget_configs = $wrapping_result['widget_configs']; |
| 88 | 89 | |
| 89 | - $child_type_error = $type_resolver->validate_child_types( $dom, $widget_configs ); | |
| 90 | - if ( $child_type_error ) { | |
| 91 | - return $child_type_error; | |
| 90 | + $child_type_errors = $type_resolver->collect_child_type_and_required_child_errors( $dom, $widget_configs ); | |
| 91 | + if ( ! empty( $child_type_errors ) ) { | |
| 92 | + return new \WP_Error( | |
| 93 | + 'elementor_invalid_child_type', | |
| 94 | + implode( ' ', $child_type_errors ), | |
| 95 | + [ 'status' => \WP_Http::BAD_REQUEST ] | |
| 96 | + ); | |
| 92 | 97 | } |
| 93 | 98 | |
| 94 | 99 | $subtrees = $subtree_builder->build( $dom, $widget_configs ); |
| 95 | 100 | if ( empty( $subtrees ) ) { |
| @@ -129,13 +134,72 @@ | ||
| 129 | 134 | |
| 130 | 135 | return [ |
| 131 | 136 | 'elements' => $subtrees, |
| 132 | 137 | 'warnings' => array_merge( $wrapping_result['warnings'], $config_result['warnings'], $style_result['warnings'], $interactions_result['warnings'] ), |
| 138 | + 'warning_codes' => array_values( array_unique( array_merge( | |
| 139 | + $wrapping_result['warning_codes'] ?? [], | |
| 140 | + $config_result['warning_codes'] ?? [], | |
| 141 | + $style_result['warning_codes'] ?? [], | |
| 142 | + $interactions_result['warning_codes'] ?? [] | |
| 143 | + ) ) ), | |
| 133 | 144 | 'dom' => $dom, |
| 134 | 145 | 'xml_parser' => $xml_parser, |
| 135 | 146 | ]; |
| 136 | 147 | } |
| 137 | 148 | |
| 149 | + /** | |
| 150 | + * @param \DOMDocument $dom | |
| 151 | + * @param Xml_Parser $xml_parser | |
| 152 | + * @param array $document_tree | |
| 153 | + * @param string $parent_id | |
| 154 | + * @param string[] $unknown_widget_tag_errors | |
| 155 | + * | |
| 156 | + * @return \WP_Error|null | |
| 157 | + */ | |
| 158 | + private function validate_xml_before_apply( | |
| 159 | + \DOMDocument $dom, | |
| 160 | + Xml_Parser $xml_parser, | |
| 161 | + array $document_tree, | |
| 162 | + string $parent_id, | |
| 163 | + array $unknown_widget_tag_errors | |
| 164 | + ) { | |
| 165 | + $errors = array_merge( | |
| 166 | + $this->tag_errors( 'elementor_duplicate_configuration_id', $xml_parser->collect_duplicate_configuration_id_errors( $dom ) ), | |
| 167 | + $this->tag_errors( 'elementor_invalid_form_structure', ( new Form_Structure_Validator( $xml_parser ) )->collect_errors( $dom, $document_tree, $parent_id ) ), | |
| 168 | + $this->tag_errors( 'elementor_unknown_type', $unknown_widget_tag_errors ), | |
| 169 | + ); | |
| 170 | + | |
| 171 | + if ( empty( $errors ) ) { | |
| 172 | + return null; | |
| 173 | + } | |
| 174 | + | |
| 175 | + $status = [ 'status' => \WP_Http::BAD_REQUEST ]; | |
| 176 | + $joined = implode( ' ', array_column( $errors, 'message' ) ); | |
| 177 | + | |
| 178 | + $aggregated = new \WP_Error( $errors[0]['code'], $joined, $status ); | |
| 179 | + foreach ( array_slice( $errors, 1 ) as $error ) { | |
| 180 | + $aggregated->add( $error['code'], $error['message'], $status ); | |
| 181 | + } | |
| 182 | + | |
| 183 | + return $aggregated; | |
| 184 | + } | |
| 185 | + | |
| 186 | + /** | |
| 187 | + * @param string $code Error code to tag each message with. | |
| 188 | + * @param string[] $messages List of error messages. | |
| 189 | + * | |
| 190 | + * @return array<int, array{code: string, message: string}> | |
| 191 | + */ | |
| 192 | + private function tag_errors( string $code, array $messages ): array { | |
| 193 | + return array_map( | |
| 194 | + fn ( $message ) => [ | |
| 195 | + 'code' => $code, | |
| 196 | + 'message' => $message, | |
| 197 | + ], | |
| 198 | + $messages | |
| 199 | + ); | |
| 200 | + } | |
| 201 | + | |
| 138 | 202 | private function wrap_document_root_content( |
| 139 | 203 | \DOMDocument $dom, |
| 140 | 204 | array $widget_configs, |
| 141 | 205 | string $parent_id, |
| @@ -145,8 +209,9 @@ | ||
| 145 | 209 | if ( self::DEFAULT_PARENT_ID !== $parent_id ) { |
| 146 | 210 | return [ |
| 147 | 211 | 'widget_configs' => $widget_configs, |
| 148 | 212 | 'warnings' => [], |
| 213 | + 'warning_codes' => [], | |
| 149 | 214 | ]; |
| 150 | 215 | } |
| 151 | 216 | |
| 152 | 217 | $root = $xml_parser->get_root( $dom ); |
| @@ -153,8 +218,9 @@ | ||
| 153 | 218 | if ( ! $root ) { |
| 154 | 219 | return [ |
| 155 | 220 | 'widget_configs' => $widget_configs, |
| 156 | 221 | 'warnings' => [], |
| 222 | + 'warning_codes' => [], | |
| 157 | 223 | ]; |
| 158 | 224 | } |
| 159 | 225 | |
| 160 | 226 | $root_children = $xml_parser->get_child_elements( $root ); |
| @@ -166,12 +232,8 @@ | ||
| 166 | 232 | if ( 'widget' !== ( $config['elType'] ?? null ) ) { |
| 167 | 233 | continue; |
| 168 | 234 | } |
| 169 | 235 | |
| 170 | - if ( self::COMPONENT_INSTANCE_WIDGET_TYPE === ( $config['widgetType'] ?? null ) ) { | |
| 171 | - continue; | |
| 172 | - } | |
| 173 | - | |
| 174 | 236 | $has_widget = true; |
| 175 | 237 | break; |
| 176 | 238 | } |
| 177 | 239 | |
| @@ -178,8 +240,9 @@ | ||
| 178 | 240 | if ( ! $has_widget ) { |
| 179 | 241 | return [ |
| 180 | 242 | 'widget_configs' => $widget_configs, |
| 181 | 243 | 'warnings' => [], |
| 244 | + 'warning_codes' => [], | |
| 182 | 245 | ]; |
| 183 | 246 | } |
| 184 | 247 | |
| 185 | 248 | $wrapper_config = $type_resolver->resolve_type_config( self::DOCUMENT_ROOT_WRAPPER ); |
| @@ -198,8 +261,9 @@ | ||
| 198 | 261 | |
| 199 | 262 | return [ |
| 200 | 263 | 'widget_configs' => $widget_configs, |
| 201 | 264 | 'warnings' => [ __( 'Direct document-root content was wrapped in an e-div-block element.', 'elementor' ) ], |
| 265 | + 'warning_codes' => [ 'root_auto_wrapped' ], | |
| 202 | 266 | ]; |
| 203 | 267 | } |
| 204 | 268 | |
| 205 | 269 | private function as_map( $value ): array { |
| @@ -258,8 +322,9 @@ | ||
| 258 | 322 | if ( empty( $interactions ) ) { |
| 259 | 323 | return [ |
| 260 | 324 | 'error' => null, |
| 261 | 325 | 'warnings' => [], |
| 326 | + 'warning_codes' => [], | |
| 262 | 327 | ]; |
| 263 | 328 | } |
| 264 | 329 | |
| 265 | 330 | if ( ! Plugin::$instance->experiments->is_feature_active( Interactions_Module::EXPERIMENT_NAME ) ) { |
| @@ -265,14 +330,15 @@ | ||
| 265 | 330 | if ( ! Plugin::$instance->experiments->is_feature_active( Interactions_Module::EXPERIMENT_NAME ) ) { |
| 266 | 331 | return [ |
| 267 | 332 | 'error' => null, |
| 268 | 333 | 'warnings' => [ __( 'Interactions experiment is not active. Interactions were not applied.', 'elementor' ) ], |
| 334 | + 'warning_codes' => [ 'interactions_experiment_off' ], | |
| 269 | 335 | ]; |
| 270 | 336 | } |
| 271 | 337 | |
| 272 | 338 | $applier = new Interactions_Applier( $this->get_plain_values_resolver() ); |
| 273 | 339 | |
| 274 | - return $applier->apply( $index, $interactions ); | |
| 340 | + return $applier->apply( $index, $interactions ) + [ 'warning_codes' => [] ]; | |
| 275 | 341 | } |
| 276 | 342 | |
| 277 | 343 | private function is_variables_active(): bool { |
| 278 | 344 | $experiments = Plugin::$instance->experiments; |