admin-bar-menu.php
3 years ago
ajax-pagination.php
2 years ago
class-ecs-core.php
2 months ago
class-ecs-module-base.php
1 month ago
class-ecs-modules-manager.php
2 months ago
dynamic-style.php
3 years ago
ecs-dependencies.php
6 years ago
ecs-notices.php
6 years ago
enqueue-styles.php
2 years ago
pro-features.php
2 months ago
pro-preview.php
6 years ago
class-ecs-modules-manager.php
177 lines
| 1 | <?php |
| 2 | /** |
| 3 | * ECS Modules Manager |
| 4 | * |
| 5 | * Registers all available modules, reads the active-modules option, |
| 6 | * boots active modules, and handles first-run migration logic. |
| 7 | */ |
| 8 | |
| 9 | if ( ! defined( 'ABSPATH' ) ) { |
| 10 | exit; |
| 11 | } |
| 12 | |
| 13 | class ECS_Modules_Manager { |
| 14 | |
| 15 | /** @var ECS_Module_Base[] All registered module instances, keyed by module ID */ |
| 16 | private array $modules = []; |
| 17 | |
| 18 | /** @var string[] IDs of currently active modules */ |
| 19 | private array $active_ids = []; |
| 20 | |
| 21 | const OPTION_KEY = 'ecs_active_modules'; |
| 22 | |
| 23 | public function __construct() { |
| 24 | // 1. Register built-in (free) modules first. |
| 25 | $this->register_core_modules(); |
| 26 | |
| 27 | // 2. Set defaults for free modules before external plugins can modify the option. |
| 28 | $this->maybe_set_defaults(); |
| 29 | |
| 30 | // 3. Let external plugins (e.g. ECS Pro) register their modules. |
| 31 | // Pro's auto-activation merges with the already-set free defaults. |
| 32 | do_action( 'ecs_register_modules', $this ); |
| 33 | |
| 34 | // 4. Read the final active list and boot. |
| 35 | $this->active_ids = (array) get_option( self::OPTION_KEY, [] ); |
| 36 | $this->boot_active_modules(); |
| 37 | } |
| 38 | |
| 39 | // ------------------------------------------------------------------------- |
| 40 | // Registration |
| 41 | // ------------------------------------------------------------------------- |
| 42 | |
| 43 | private function register_core_modules(): void { |
| 44 | $module_files = [ |
| 45 | 'legacy' => ECS_PATH . 'modules/legacy/class-ecs-legacy-module.php', |
| 46 | 'color-scheme' => ECS_PATH . 'modules/color-scheme/class-ecs-color-scheme-module.php', |
| 47 | 'container-layout' => ECS_PATH . 'modules/container-layout/class-ecs-container-layout-module.php', |
| 48 | 'loop-custom-layout' => ECS_PATH . 'modules/loop-custom-layout/class-ecs-loop-custom-layout-module.php', |
| 49 | 'mobile-menu' => ECS_PATH . 'modules/mobile-menu/class-ecs-mobile-menu-module.php', |
| 50 | 'editorial-text' => ECS_PATH . 'modules/editorial-text/class-ecs-editorial-text-module.php', |
| 51 | 'style-templates' => ECS_PATH . 'modules/style-templates/class-ecs-style-templates-module.php', |
| 52 | 'json-poweredit' => ECS_PATH . 'modules/json-poweredit/class-ecs-json-poweredit-module.php', |
| 53 | 'dynamic-repeater' => ECS_PATH . 'modules/dynamic-repeater/class-ecs-dynamic-repeater-module.php', |
| 54 | 'color-wheel' => ECS_PATH . 'modules/color-wheel/class-ecs-colorwheel-module.php', |
| 55 | ]; |
| 56 | |
| 57 | foreach ( $module_files as $file ) { |
| 58 | if ( file_exists( $file ) ) { |
| 59 | require_once $file; |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | $module_classes = [ |
| 64 | 'ECS_Legacy_Module', |
| 65 | 'ECS_Color_Scheme_Module', |
| 66 | 'ECS_Container_Layout_Module', |
| 67 | 'ECS_Loop_Custom_Layout_Module', |
| 68 | 'ECS_Mobile_Menu_Module', |
| 69 | 'ECS_Editorial_Text_Module', |
| 70 | 'ECS_Style_Templates_Module', |
| 71 | 'ECS_JSON_PowerEdit_Module', |
| 72 | 'ECS_Dynamic_Repeater_Module', |
| 73 | 'ECS_Colorwheel_Module', |
| 74 | ]; |
| 75 | |
| 76 | foreach ( $module_classes as $class ) { |
| 77 | if ( class_exists( $class ) ) { |
| 78 | $module = new $class(); |
| 79 | $this->modules[ $module->get_id() ] = $module; |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * Register a single module instance from an external plugin. |
| 86 | * |
| 87 | * @param ECS_Module_Base $module |
| 88 | */ |
| 89 | public function register_module( ECS_Module_Base $module ): void { |
| 90 | $this->modules[ $module->get_id() ] = $module; |
| 91 | } |
| 92 | |
| 93 | // ------------------------------------------------------------------------- |
| 94 | // Migration / first-run defaults |
| 95 | // ------------------------------------------------------------------------- |
| 96 | |
| 97 | /** |
| 98 | * On first run of ECS 4.0, decide which modules are active by default. |
| 99 | * |
| 100 | * - Fresh install → all active EXCEPT legacy |
| 101 | * - Update from ECS 3.x → all active INCLUDING legacy |
| 102 | * (detected by presence of loop templates created with the old ECS) |
| 103 | */ |
| 104 | private function maybe_set_defaults(): void { |
| 105 | if ( false !== get_option( self::OPTION_KEY ) ) { |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | $all_ids = array_keys( $this->modules ); |
| 110 | |
| 111 | // Detect old ECS usage: loop templates in the library. |
| 112 | $has_loop_templates = (bool) get_posts( [ |
| 113 | 'post_type' => 'elementor_library', |
| 114 | 'post_status' => 'publish', |
| 115 | 'meta_key' => '_elementor_template_type', |
| 116 | 'meta_value' => 'loop', |
| 117 | 'posts_per_page' => 1, |
| 118 | 'fields' => 'ids', |
| 119 | ] ); |
| 120 | |
| 121 | if ( $has_loop_templates ) { |
| 122 | // Update from ECS 3.x — activate everything including legacy. |
| 123 | $defaults = $all_ids; |
| 124 | } else { |
| 125 | // Fresh install — activate everything except legacy. |
| 126 | $defaults = array_values( array_filter( $all_ids, fn( $id ) => $id !== 'legacy' ) ); |
| 127 | } |
| 128 | |
| 129 | update_option( self::OPTION_KEY, $defaults ); |
| 130 | } |
| 131 | |
| 132 | // ------------------------------------------------------------------------- |
| 133 | // Booting |
| 134 | // ------------------------------------------------------------------------- |
| 135 | |
| 136 | private function boot_active_modules(): void { |
| 137 | foreach ( $this->modules as $id => $module ) { |
| 138 | if ( ! $this->is_active( $id ) ) { |
| 139 | continue; |
| 140 | } |
| 141 | |
| 142 | $module->boot(); |
| 143 | |
| 144 | add_action( 'elementor/widgets/register', [ $module, 'register_widgets' ] ); |
| 145 | add_action( 'elementor/controls/register', [ $module, 'register_controls' ] ); |
| 146 | add_action( 'wp_enqueue_scripts', [ $module, 'enqueue_frontend_assets' ] ); |
| 147 | add_action( 'elementor/preview/enqueue_styles', [ $module, 'enqueue_frontend_assets' ] ); |
| 148 | add_action( 'elementor/editor/after_enqueue_scripts', [ $module, 'enqueue_editor_assets' ] ); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | // ------------------------------------------------------------------------- |
| 153 | // Public API |
| 154 | // ------------------------------------------------------------------------- |
| 155 | |
| 156 | /** @return ECS_Module_Base[] */ |
| 157 | public function get_all(): array { |
| 158 | return $this->modules; |
| 159 | } |
| 160 | |
| 161 | public function get( string $id ): ?ECS_Module_Base { |
| 162 | return $this->modules[ $id ] ?? null; |
| 163 | } |
| 164 | |
| 165 | public function is_active( string $id ): bool { |
| 166 | return in_array( $id, $this->active_ids, true ); |
| 167 | } |
| 168 | |
| 169 | /** @param string[] $ids */ |
| 170 | public function set_active( array $ids ): void { |
| 171 | $valid = array_keys( $this->modules ); |
| 172 | $ids = array_values( array_intersect( $ids, $valid ) ); |
| 173 | $this->active_ids = $ids; |
| 174 | update_option( self::OPTION_KEY, $ids ); |
| 175 | } |
| 176 | } |
| 177 |