PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.1
Elementor Website Builder – more than just a page builder v4.3.1
4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 All 454 releases
← All changes | modules/mcp/abilities/manage-classes-ability.php +104 -5 4.3.0-beta1 → 4.3.1 View file →
@@ -14,8 +14,10 @@
14 14 use Elementor\Modules\GlobalClasses\Global_Classes_Repository;
15 15 use Elementor\Modules\GlobalClasses\Global_Classes_REST_API;
16 16 use Elementor\Modules\Mcp\Abilities\Utils\Bulk_Operations_Result;
17 17 use Elementor\Modules\Mcp\Abilities\Utils\Style_Variants_Merger;
18 +use Elementor\Modules\Mcp\Abilities\Utils\Tool_Performance_Metrics;
19 +use Elementor\Modules\Mcp\Events\Mcp_Event_Dispatcher;
18 20 use Elementor\Modules\Variables\Module as Variables_Module;
19 21 use Elementor\Modules\Variables\Services\Batch_Operations\Batch_Processor;
20 22 use Elementor\Modules\Variables\Services\Variables_Service;
21 23 use Elementor\Modules\Variables\Storage\Variables_Repository;
@@ -103,21 +105,26 @@
103 105 );
104 106 }
105 107
106 108 public function execute( $input = [] ) {
107 - $input = is_array( $input ) ? $input : [];
109 + $started_at = hrtime( true );
110 + $input = is_array( $input ) ? $input : [];
108 111 $operations = $input['operations'] ?? null;
109 112
110 113 if ( ! is_array( $operations ) ) {
111 - return $this->bad_request( __( 'operations array is required.', 'elementor' ) );
114 + $error = $this->bad_request( __( 'operations array is required.', 'elementor' ) );
115 + $this->emit_mcp_manage_classes_executed( $started_at, [], $error );
116 + return $error;
112 117 }
113 118
114 119 if ( empty( $operations ) ) {
115 - return $this->bad_request( __( 'operations must not be empty.', 'elementor' ) );
120 + $error = $this->bad_request( __( 'operations must not be empty.', 'elementor' ) );
121 + $this->emit_mcp_manage_classes_executed( $started_at, [], $error );
122 + return $error;
116 123 }
117 124
118 125 if ( count( $operations ) > self::MAX_BATCH_SIZE ) {
119 - return new \WP_Error(
126 + $error = new \WP_Error(
120 127 'batch_size_exceeded',
121 128 sprintf(
122 129 /* translators: %d: maximum operations per request */
123 130 __( 'Maximum %d operations per request.', 'elementor' ),
@@ -127,11 +134,15 @@
127 134 'status' => \WP_Http::BAD_REQUEST,
128 135 'max_allowed' => self::MAX_BATCH_SIZE,
129 136 ]
130 137 );
138 + $this->emit_mcp_manage_classes_executed( $started_at, $operations, $error );
139 + return $error;
131 140 }
132 141
133 - return $this->handle_bulk( $operations );
142 + $response = $this->handle_bulk( $operations );
143 + $this->emit_mcp_manage_classes_executed( $started_at, $operations, null, $response );
144 + return $response;
134 145 }
135 146
136 147 private function handle_bulk( array $operations ): array {
137 148 $results = new Bulk_Operations_Result();
@@ -173,8 +184,9 @@
173 184 $new_order
174 185 );
175 186
176 187 $this->clear_cache();
188 + $this->emit_class_created_events( $results );
177 189 }
178 190
179 191 return $results->to_array() + [ 'order' => $new_order ];
180 192 }
@@ -612,6 +624,93 @@
612 624 $experiments = Plugin::$instance->experiments;
613 625
614 626 return $experiments->is_feature_active( Variables_Module::EXPERIMENT_NAME )
615 627 && $experiments->is_feature_active( AtomicWidgetsModule::EXPERIMENT_NAME );
628 + }
629 +
630 + private function emit_class_created_events( Bulk_Operations_Result $results ): void {
631 + foreach ( $results->to_array()['results'] as $row ) {
632 + if ( 'ok' !== ( $row['status'] ?? '' ) || 'create' !== ( $row['action'] ?? '' ) ) {
633 + continue;
634 + }
635 +
636 + Mcp_Event_Dispatcher::emit( 'class_created', [
637 + 'id' => $row['id'] ?? '',
638 + 'name' => $row['label'] ?? '',
639 + ] );
640 + }
641 + }
642 +
643 + private function emit_mcp_manage_classes_executed(
644 + int $started_at,
645 + array $operations,
646 + ?\WP_Error $top_level_error = null,
647 + array $response = []
648 + ): void {
649 + $duration_ms = Tool_Performance_Metrics::duration_ms_since( $started_at );
650 +
651 + [ 'status' => $status, 'error_code' => $error_code ] = Tool_Performance_Metrics::resolve_status( $response, $top_level_error );
652 +
653 + $failed_results = array_filter( $response['results'] ?? [], fn( $r ) => 'error' === ( $r['status'] ?? '' ) );
654 + $failed_count = count( $failed_results );
655 + $failed_codes = array_values( array_unique( array_column( $failed_results, 'code' ) ) );
656 +
657 + $ops_count = count( $operations );
658 + $by_action = [];
659 + $mode_used = null;
660 + $all_css = '';
661 +
662 + foreach ( $operations as $op ) {
663 + $action = $op['action'] ?? '';
664 + if ( is_string( $action ) && '' !== $action ) {
665 + $by_action[ $action ] = ( $by_action[ $action ] ?? 0 ) + 1;
666 + }
667 +
668 + if ( 'update' === $action ) {
669 + $mode_used = $mode_used ?? ( $op['mode'] ?? 'patch' );
670 + }
671 +
672 + if ( isset( $op['css'] ) && is_string( $op['css'] ) ) {
673 + $all_css .= ' ' . $op['css'];
674 + }
675 + }
676 +
677 + $dominant_action = '';
678 + if ( ! empty( $by_action ) ) {
679 + arsort( $by_action );
680 + $dominant_action = (string) array_key_first( $by_action );
681 + }
682 +
683 + $vars_count = 0;
684 + $var_labels = [];
685 + if ( '' !== trim( $all_css ) ) {
686 + preg_match_all( '/var\(--([a-zA-Z0-9_-]+)\)/', $all_css, $matches );
687 + $var_labels = array_values( array_unique( $matches[1] ?? [] ) );
688 + $vars_count = count( $matches[0] ?? [] );
689 + }
690 +
691 + $payload = [
692 + 'tool_name' => $this->get_ability_id(),
693 + 'status' => $status,
694 + 'duration_ms' => $duration_ms,
695 + 'action' => $dominant_action,
696 + 'operations_count' => $ops_count,
697 + 'operations_by_type' => $by_action,
698 + 'failed_operations_count' => $failed_count,
699 + 'failed_operation_codes' => $failed_codes,
700 + 'variables_referenced_count' => $vars_count,
701 + 'variable_labels' => $var_labels,
702 + 'warning_count' => 0,
703 + 'warning_types' => [],
704 + ];
705 +
706 + if ( null !== $mode_used ) {
707 + $payload['mode_used'] = $mode_used;
708 + }
709 +
710 + if ( null !== $error_code ) {
711 + $payload['error_code'] = $error_code;
712 + }
713 +
714 + Mcp_Event_Dispatcher::emit( 'mcp_manage_classes_executed', $payload );
616 715 }
617 716 }