PluginProbe
Elementor Website Builder – more than just a page builder / 3.30.1
Elementor Website Builder – more than just a page builder v3.30.1
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 4.1.0-beta1 4.1.0-dev1 All 452 releases
← All changes | modules/global-classes/usage/applied-global-classes-usage.php +57 -88 4.1.0-dev23.30.1 View file →
@@ -1,9 +1,14 @@
1 1 <?php
2 2
3 -namespace Elementor\Modules\GlobalClasses\Usage;
3 +namespace Elementor\Modules\Global_Classes\Usage;
4 4
5 +use Elementor\Core\Base\Document;
6 +use Elementor\Core\Utils\Collection;
7 +use Elementor\Modules\AtomicWidgets\Elements\Atomic_Element_Base;
8 +use Elementor\Modules\AtomicWidgets\Elements\Atomic_Widget_Base;
5 9 use Elementor\Modules\GlobalClasses\Global_Classes_Repository;
10 +use Elementor\Modules\GlobalClasses\Utils\Atomic_Elements_Utils;
6 11 use Elementor\Plugin;
7 12
8 13 if ( ! defined( 'ABSPATH' ) ) {
9 14 exit; // Exit if accessed directly.
@@ -8,116 +13,80 @@
8 13 if ( ! defined( 'ABSPATH' ) ) {
9 14 exit; // Exit if accessed directly.
10 15 }
11 16
12 -/**
13 - * Collects and exposes usage data for all global CSS classes across Elementor documents.
14 - */
15 17 class Applied_Global_Classes_Usage {
16 -
17 18 /**
18 - * Document types that should be excluded from usage reporting.
19 + * Get data about how global classes are applied across Elementor elements.
19 20 *
20 - * @var string[]
21 + * @return array<string, int> Statistics about applied global classes per global class
21 22 */
22 - private array $excluded_types = [ 'e-flexbox', 'template' ];
23 + public function get() {
24 + $total_count_per_class_id = [];
25 + $global_class_ids = Global_Classes_Repository::make()->all()->get_items()->keys()->all();
23 26
24 - /**
25 - * Tracks usage for each global class.
26 - *
27 - * @var array<string, Css_Class_Usage>
28 - */
29 - private array $class_usages = [];
27 + if ( empty( $global_class_ids ) ) {
28 + return [];
29 + }
30 30
31 - /**
32 - * Returns the total usage count per class ID (excluding template-only classes).
33 - *
34 - * @return array<string, int>
35 - */
36 - public function get(): array {
37 - $this->build_class_usages();
31 + Plugin::$instance->db->iterate_elementor_documents( function( $document, $elements_data ) use ( &$total_count_per_class_id, $global_class_ids ) {
32 + $count_per_global_class = $this->get_classes_count_per_class( $elements_data, $global_class_ids );
38 33
39 - $result = [];
40 - foreach ( $this->class_usages as $class_id => $usage ) {
41 - if ( $usage->get_total_usage() > 0 ) {
42 - $result[ $class_id ] = $usage->get_total_usage();
43 - }
34 + $total_count_per_class_id = Collection::make( $count_per_global_class )->reduce( function( $carry, $count, $class_id ) {
35 + $carry[ $class_id ] ??= 0;
36 + $carry[ $class_id ] += $count;
37 +
38 + return $carry;
39 + }, $total_count_per_class_id );
40 + });
41 +
42 + foreach ( $global_class_ids as $global_class_id ) {
43 + $total_count_per_class_id[ $global_class_id ] ??= 0;
44 44 }
45 45
46 - return $result;
46 + return $total_count_per_class_id;
47 47 }
48 48
49 - /**
50 - * Returns detailed usage information per class ID.
51 - * Each class ID maps to a list of document usages (excluding excluded types).
52 - *
53 - * @return array<string, array{
54 - * pageId: int,
55 - * title: string,
56 - * type: string,
57 - * total: int,
58 - * elements: string[]
59 - * }>
60 - */
61 - public function get_detailed_usage(): array {
62 - $this->build_class_usages();
49 + private function get_classes_count_per_class( $elements_data, $global_class_ids ) {
50 + $count_per_class = [];
63 51
64 - $result = [];
52 + Plugin::$instance->db->iterate_data( $elements_data, function( $element_data ) use ( $global_class_ids, &$count_per_class ) {
53 + $element_type = Atomic_Elements_Utils::get_element_type( $element_data );
54 + $element_instance = Atomic_Elements_Utils::get_element_instance( $element_type );
65 55
66 - foreach ( $this->class_usages as $class_id => $usage ) {
67 - $pages = $usage->get_pages();
56 + if ( ! Atomic_Elements_Utils::is_atomic_element( $element_instance ) ) {
57 + return;
58 + }
68 59
69 - $filtered_pages = array_filter(
70 - $pages,
71 - fn( $page_data ) => ! in_array( $page_data['type'], $this->excluded_types, true )
72 - );
60 + /** @var Atomic_Element_Base | Atomic_Widget_Base $element_instance */
61 + $applied_classes_per_element = $this->get_applied_global_classes_per_element( $element_instance->get_props_schema(), $element_data, $global_class_ids );
73 62
74 - if ( empty( $filtered_pages ) ) {
75 - continue;
63 + foreach ( $applied_classes_per_element as $global_class_id => $count ) {
64 + $count_per_class[ $global_class_id ] ??= 0;
65 + $count_per_class[ $global_class_id ] += $count;
76 66 }
67 + });
77 68
78 - foreach ( $filtered_pages as $page_id => $page_data ) {
79 - $result[ $class_id ][] = [
80 - 'pageId' => $page_id,
81 - 'title' => $page_data['title'],
82 - 'type' => $page_data['type'],
83 - 'total' => $page_data['total'],
84 - 'elements' => $page_data['elements'],
85 - ];
86 - }
87 - }
88 -
89 - return $result;
69 + return $count_per_class;
90 70 }
91 71
92 - /**
93 - * Builds the internal usage map from all Elementor documents.
94 - *
95 - * This method initializes and aggregates class usage from all relevant documents,
96 - * merging duplicate class IDs found in multiple pages.
97 - */
98 - private function build_class_usages(): void {
99 - $this->class_usages = [];
72 + private function get_applied_global_classes_per_element( $atomic_props_schema, $atomic_element_data, $global_class_ids ) {
73 + return Collection::make( $atomic_props_schema )->reduce( function( $carry, $prop_value, $prop_name ) use ( $atomic_element_data, $global_class_ids ) {
74 + if ( ! Atomic_Elements_Utils::is_classes_prop( $prop_value ) ) {
75 + return $carry;
76 + }
100 77
101 - $class_ids = array_keys( Global_Classes_Repository::make()->all_labels() );
102 - $class_id_set = array_fill_keys( $class_ids, true );
78 + $prop_applied_global_class_ids = $this->get_applied_global_classes( $atomic_element_data['settings'][ $prop_name ]['value'] ?? [], $global_class_ids );
103 79
104 - Plugin::$instance->db->iterate_elementor_documents(
105 - function ( $document ) use ( $class_id_set ) {
106 - $usage = new Document_Usage( $document, $class_id_set );
107 - $usage->analyze();
80 + foreach ( $prop_applied_global_class_ids as $global_class_id ) {
81 + $carry[ $global_class_id ] ??= 0;
82 + $carry[ $global_class_id ] += 1;
83 + }
108 84
109 - foreach ( $usage->get_usages() as $class_id => $class_usage ) {
110 - if ( ! isset( $class_id_set[ $class_id ] ) ) {
111 - continue;
112 - }
85 + return $carry;
86 + }, [] );
87 + }
113 88
114 - if ( ! isset( $this->class_usages[ $class_id ] ) ) {
115 - $this->class_usages[ $class_id ] = $class_usage;
116 - } else {
117 - $this->class_usages[ $class_id ]->merge( $class_usage );
118 - }
119 - }
120 - }
121 - );
89 + private function get_applied_global_classes( $prop, $global_class_ids ) {
90 + return array_intersect( $prop, $global_class_ids );
122 91 }
123 92 }