← All changes
|
modules/mcp/abilities/manage-variable-ability.php
+116
-5
4.3.0-beta2
→
4.3.2
View file →
| @@ -2,8 +2,10 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace Elementor\Modules\Mcp\Abilities; |
| 4 | 4 | |
| 5 | 5 | use Elementor\Modules\Mcp\Abilities\Utils\Bulk_Operations_Result; |
| 6 | +use Elementor\Modules\Mcp\Abilities\Utils\Tool_Performance_Metrics; | |
| 7 | +use Elementor\Modules\Mcp\Events\Mcp_Event_Dispatcher; | |
| 6 | 8 | use Elementor\Modules\Variables\Services\Batch_Operations\Batch_Processor; |
| 7 | 9 | use Elementor\Modules\Variables\Services\Variables_Service; |
| 8 | 10 | use Elementor\Modules\Variables\Storage\Exceptions\FatalError; |
| 9 | 11 | use Elementor\Modules\Variables\Storage\Variables_Repository; |
| @@ -83,21 +85,26 @@ | ||
| 83 | 85 | ); |
| 84 | 86 | } |
| 85 | 87 | |
| 86 | 88 | public function execute( $input = [] ) { |
| 87 | - $input = is_array( $input ) ? $input : []; | |
| 89 | + $started_at = hrtime( true ); | |
| 90 | + $input = is_array( $input ) ? $input : []; | |
| 88 | 91 | $operations = $input['operations'] ?? null; |
| 89 | 92 | |
| 90 | 93 | if ( ! is_array( $operations ) ) { |
| 91 | - return $this->bad_request( __( 'operations array is required.', 'elementor' ) ); | |
| 94 | + $error = $this->bad_request( __( 'operations array is required.', 'elementor' ) ); | |
| 95 | + $this->emit_mcp_manage_global_variable_executed( $started_at, [], $error ); | |
| 96 | + return $error; | |
| 92 | 97 | } |
| 93 | 98 | |
| 94 | 99 | if ( empty( $operations ) ) { |
| 95 | - return $this->bad_request( __( 'operations must not be empty.', 'elementor' ) ); | |
| 100 | + $error = $this->bad_request( __( 'operations must not be empty.', 'elementor' ) ); | |
| 101 | + $this->emit_mcp_manage_global_variable_executed( $started_at, [], $error ); | |
| 102 | + return $error; | |
| 96 | 103 | } |
| 97 | 104 | |
| 98 | 105 | if ( count( $operations ) > self::MAX_BATCH_SIZE ) { |
| 99 | - return new \WP_Error( | |
| 106 | + $error = new \WP_Error( | |
| 100 | 107 | 'batch_size_exceeded', |
| 101 | 108 | sprintf( |
| 102 | 109 | /* translators: %d: maximum operations per request */ |
| 103 | 110 | __( 'Maximum %d operations per request.', 'elementor' ), |
| @@ -107,11 +114,19 @@ | ||
| 107 | 114 | 'status' => \WP_Http::BAD_REQUEST, |
| 108 | 115 | 'max_allowed' => self::MAX_BATCH_SIZE, |
| 109 | 116 | ] |
| 110 | 117 | ); |
| 118 | + $this->emit_mcp_manage_global_variable_executed( $started_at, $operations, $error ); | |
| 119 | + return $error; | |
| 111 | 120 | } |
| 112 | 121 | |
| 113 | - return $this->handle_bulk( $operations ); | |
| 122 | + $response = $this->handle_bulk( $operations ); | |
| 123 | + if ( is_wp_error( $response ) ) { | |
| 124 | + $this->emit_mcp_manage_global_variable_executed( $started_at, $operations, $response ); | |
| 125 | + } else { | |
| 126 | + $this->emit_mcp_manage_global_variable_executed( $started_at, $operations, null, $response ); | |
| 127 | + } | |
| 128 | + return $response; | |
| 114 | 129 | } |
| 115 | 130 | |
| 116 | 131 | private function handle_bulk( array $operations ) { |
| 117 | 132 | $results = new Bulk_Operations_Result(); |
| @@ -147,8 +162,9 @@ | ||
| 147 | 162 | $batch_result = $this->get_service()->process_batch( $batch_operations, true ); |
| 148 | 163 | $watermark = $batch_result['watermark'] ?? null; |
| 149 | 164 | |
| 150 | 165 | $this->merge_batch_results( $batch_result['results'], $index_map, $results ); |
| 166 | + $this->emit_variable_events( $batch_result['results'] ); | |
| 151 | 167 | } catch ( FatalError $e ) { |
| 152 | 168 | return new \WP_Error( |
| 153 | 169 | 'unexpected_server_error', |
| 154 | 170 | __( 'Unexpected server error', 'elementor' ), |
| @@ -276,6 +292,101 @@ | ||
| 276 | 292 | return new Variables_Service( |
| 277 | 293 | new Variables_Repository( $kit ), |
| 278 | 294 | new Batch_Processor() |
| 279 | 295 | ); |
| 296 | + } | |
| 297 | + | |
| 298 | + private function emit_variable_events( array $batch_results ): void { | |
| 299 | + $event_by_action = [ | |
| 300 | + 'create' => 'variable_created', | |
| 301 | + 'update' => 'variable_updated', | |
| 302 | + ]; | |
| 303 | + | |
| 304 | + $var_type_labels = [ | |
| 305 | + self::TYPE_COLOR => 'color', | |
| 306 | + self::TYPE_FONT => 'font', | |
| 307 | + self::TYPE_SIZE => 'size', | |
| 308 | + self::TYPE_CUSTOM_SIZE => 'size', | |
| 309 | + ]; | |
| 310 | + | |
| 311 | + foreach ( $batch_results as $result ) { | |
| 312 | + if ( 'ok' !== ( $result['status'] ?? '' ) ) { | |
| 313 | + continue; | |
| 314 | + } | |
| 315 | + | |
| 316 | + $action = $result['action'] ?? ''; | |
| 317 | + | |
| 318 | + if ( ! isset( $event_by_action[ $action ] ) ) { | |
| 319 | + continue; | |
| 320 | + } | |
| 321 | + | |
| 322 | + $raw_type = $result['type'] ?? ''; | |
| 323 | + $var_type = $var_type_labels[ $raw_type ] ?? $raw_type; | |
| 324 | + | |
| 325 | + Mcp_Event_Dispatcher::emit( $event_by_action[ $action ], [ | |
| 326 | + 'id' => $result['id'] ?? '', | |
| 327 | + 'name' => $result['label'] ?? '', | |
| 328 | + 'var_type' => $var_type, | |
| 329 | + ] ); | |
| 330 | + } | |
| 331 | + } | |
| 332 | + | |
| 333 | + private function emit_mcp_manage_global_variable_executed( | |
| 334 | + int $started_at, | |
| 335 | + array $operations, | |
| 336 | + ?\WP_Error $top_level_error = null, | |
| 337 | + array $response = [] | |
| 338 | + ): void { | |
| 339 | + $duration_ms = Tool_Performance_Metrics::duration_ms_since( $started_at ); | |
| 340 | + | |
| 341 | + [ 'status' => $status, 'error_code' => $error_code ] = Tool_Performance_Metrics::resolve_status( $response, $top_level_error ); | |
| 342 | + | |
| 343 | + $failed_results = array_filter( $response['results'] ?? [], fn( $r ) => 'error' === ( $r['status'] ?? '' ) ); | |
| 344 | + $failed_count = count( $failed_results ); | |
| 345 | + $failed_codes = array_values( array_unique( array_column( $failed_results, 'code' ) ) ); | |
| 346 | + | |
| 347 | + $ops_count = count( $operations ); | |
| 348 | + $by_action = []; | |
| 349 | + $variable_types = []; | |
| 350 | + | |
| 351 | + foreach ( $operations as $op ) { | |
| 352 | + $action = $op['action'] ?? ''; | |
| 353 | + if ( is_string( $action ) && '' !== $action ) { | |
| 354 | + $by_action[ $action ] = ( $by_action[ $action ] ?? 0 ) + 1; | |
| 355 | + } | |
| 356 | + } | |
| 357 | + | |
| 358 | + $ok_results = array_filter( $response['results'] ?? [], fn( $r ) => 'ok' === ( $r['status'] ?? '' ) ); | |
| 359 | + foreach ( $ok_results as $row ) { | |
| 360 | + $type = $row['type'] ?? ''; | |
| 361 | + if ( is_string( $type ) && '' !== $type ) { | |
| 362 | + $variable_types[ $type ] = ( $variable_types[ $type ] ?? 0 ) + 1; | |
| 363 | + } | |
| 364 | + } | |
| 365 | + | |
| 366 | + $dominant_action = ''; | |
| 367 | + if ( ! empty( $by_action ) ) { | |
| 368 | + arsort( $by_action ); | |
| 369 | + $dominant_action = (string) array_key_first( $by_action ); | |
| 370 | + } | |
| 371 | + | |
| 372 | + $payload = [ | |
| 373 | + 'tool_name' => $this->get_ability_id(), | |
| 374 | + 'status' => $status, | |
| 375 | + 'duration_ms' => $duration_ms, | |
| 376 | + 'action' => $dominant_action, | |
| 377 | + 'operations_count' => $ops_count, | |
| 378 | + 'operations_by_type' => $by_action, | |
| 379 | + 'variable_types' => $variable_types, | |
| 380 | + 'failed_operations_count' => $failed_count, | |
| 381 | + 'failed_operation_codes' => $failed_codes, | |
| 382 | + 'warning_count' => 0, | |
| 383 | + 'warning_types' => [], | |
| 384 | + ]; | |
| 385 | + | |
| 386 | + if ( null !== $error_code ) { | |
| 387 | + $payload['error_code'] = $error_code; | |
| 388 | + } | |
| 389 | + | |
| 390 | + Mcp_Event_Dispatcher::emit( 'mcp_manage_global_variable_executed', $payload ); | |
| 280 | 391 | } |
| 281 | 392 | } |