| @@ -2,17 +2,13 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace Elementor\Modules\Checklist; |
| 4 | 4 | |
| 5 | 5 | use Elementor\Core\Base\Module as BaseModule; |
| 6 | -use Elementor\Modules\ElementorCounter\Module as Elementor_Counter; | |
| 6 | +use Elementor\Core\Experiments\Manager; | |
| 7 | 7 | use Elementor\Core\Isolation\Wordpress_Adapter; |
| 8 | 8 | use Elementor\Core\Isolation\Wordpress_Adapter_Interface; |
| 9 | -use Elementor\Core\Isolation\Elementor_Adapter; | |
| 10 | -use Elementor\Core\Isolation\Elementor_Adapter_Interface; | |
| 11 | -use Elementor\Core\Isolation\Elementor_Counter_Adapter_Interface; | |
| 12 | 9 | use Elementor\Plugin; |
| 13 | 10 | use Elementor\Utils; |
| 14 | -use Elementor\Modules\Checklist\Data\Controller; | |
| 15 | 11 | |
| 16 | 12 | if ( ! defined( 'ABSPATH' ) ) { |
| 17 | 13 | exit; // Exit if accessed directly. |
| 18 | 14 | } |
| @@ -17,46 +13,33 @@ | ||
| 17 | 13 | exit; // Exit if accessed directly. |
| 18 | 14 | } |
| 19 | 15 | |
| 20 | 16 | class Module extends BaseModule implements Checklist_Module_Interface { |
| 17 | + const EXPERIMENT_ID = 'launchpad-checklist'; | |
| 21 | 18 | const DB_OPTION_KEY = 'elementor_checklist'; |
| 22 | - const VISIBILITY_SWITCH_ID = 'show_launchpad_checklist'; | |
| 23 | - const FIRST_CLOSED_CHECKLIST_IN_EDITOR = 'first_closed_checklist_in_editor'; | |
| 24 | - const LAST_OPENED_TIMESTAMP = 'last_opened_timestamp'; | |
| 25 | - const SHOULD_OPEN_IN_EDITOR = 'should_open_in_editor'; | |
| 26 | - const IS_POPUP_MINIMIZED_KEY = 'is_popup_minimized'; | |
| 27 | 19 | |
| 20 | + private $user_progress = null; | |
| 28 | 21 | private Steps_Manager $steps_manager; |
| 29 | 22 | private Wordpress_Adapter_Interface $wordpress_adapter; |
| 30 | - private Elementor_Adapter_Interface $elementor_adapter; | |
| 31 | - private Elementor_Counter_Adapter_Interface $counter_adapter; | |
| 32 | - private $user_progress = null; | |
| 33 | 23 | |
| 34 | 24 | /** |
| 35 | 25 | * @param ?Wordpress_Adapter_Interface $wordpress_adapter |
| 36 | - * @param ?Elementor_Adapter_Interface $elementor_adapter | |
| 37 | 26 | * |
| 38 | 27 | * @return void |
| 39 | 28 | */ |
| 40 | - public function __construct( | |
| 41 | - ?Wordpress_Adapter_Interface $wordpress_adapter = null, | |
| 42 | - ?Elementor_Adapter_Interface $elementor_adapter = null | |
| 43 | - ) { | |
| 29 | + public function __construct( ?Wordpress_Adapter_Interface $wordpress_adapter = null ) { | |
| 44 | 30 | $this->wordpress_adapter = $wordpress_adapter ?? new Wordpress_Adapter(); |
| 45 | - $this->elementor_adapter = $elementor_adapter ?? new Elementor_Adapter(); | |
| 46 | - | |
| 47 | 31 | parent::__construct(); |
| 48 | - $this->init_user_progress(); | |
| 49 | 32 | |
| 50 | - Plugin::$instance->data_manager_v2->register_controller( new Controller() ); | |
| 51 | - $this->user_progress = $this->user_progress ?? $this->get_user_progress_from_db(); | |
| 52 | - $this->handle_checklist_visibility_with_kit(); | |
| 53 | - $this->steps_manager = new Steps_Manager( $this ); | |
| 33 | + $this->register_experiment(); | |
| 54 | 34 | |
| 55 | - if ( ! current_user_can( 'manage_options' ) ) { | |
| 35 | + if ( ! $this->is_experiment_active() ) { | |
| 56 | 36 | return; |
| 57 | 37 | } |
| 58 | 38 | |
| 39 | + $this->init_user_progress(); | |
| 40 | + $this->user_progress = $this->user_progress ?? $this->get_user_progress_from_db(); | |
| 41 | + $this->steps_manager = new Steps_Manager( $this ); | |
| 59 | 42 | $this->enqueue_editor_scripts(); |
| 60 | 43 | } |
| 61 | 44 | |
| 62 | 45 | /** |
| @@ -63,13 +46,22 @@ | ||
| 63 | 46 | * Get the module name. |
| 64 | 47 | * |
| 65 | 48 | * @return string |
| 66 | 49 | */ |
| 67 | - public function get_name(): string { | |
| 50 | + public function get_name() : string { | |
| 68 | 51 | return 'e-checklist'; |
| 69 | 52 | } |
| 70 | 53 | |
| 71 | 54 | /** |
| 55 | + * Checks if the experiment is active | |
| 56 | + * | |
| 57 | + * @return bool | |
| 58 | + */ | |
| 59 | + public function is_experiment_active() : bool { | |
| 60 | + return Plugin::$instance->experiments->is_feature_active( self::EXPERIMENT_ID ); | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 72 | 64 | * Gets user's progress from db |
| 73 | 65 | * |
| 74 | 66 | * @return array { |
| 75 | 67 | * @type bool $is_hidden |
| @@ -76,24 +68,15 @@ | ||
| 76 | 68 | * @type int $last_opened_timestamp |
| 77 | 69 | * @type array $steps { |
| 78 | 70 | * @type string $step_id => { |
| 79 | 71 | * @type bool $is_marked_completed |
| 80 | - * @type bool $is_absolute_competed | |
| 81 | - * @type bool $is_immutable_completed | |
| 72 | + * @type bool $is_completed | |
| 82 | 73 | * } |
| 83 | 74 | * } |
| 84 | 75 | * } |
| 85 | 76 | */ |
| 86 | - public function get_user_progress_from_db(): array { | |
| 87 | - $db_progress = json_decode( $this->wordpress_adapter->get_option( self::DB_OPTION_KEY ), true ); | |
| 88 | - $db_progress = is_array( $db_progress ) ? $db_progress : []; | |
| 89 | - | |
| 90 | - $progress = array_merge( $this->get_default_user_progress(), $db_progress ); | |
| 91 | - | |
| 92 | - $editor_visit_count = $this->elementor_adapter->get_count( Elementor_Counter::EDITOR_COUNTER_KEY ); | |
| 93 | - $progress[ self::SHOULD_OPEN_IN_EDITOR ] = 2 === $editor_visit_count && ! $progress[ self::LAST_OPENED_TIMESTAMP ]; | |
| 94 | - | |
| 95 | - return $progress; | |
| 77 | + public function get_user_progress_from_db() : array { | |
| 78 | + return json_decode( $this->wordpress_adapter->get_option( self::DB_OPTION_KEY ), true ); | |
| 96 | 79 | } |
| 97 | 80 | |
| 98 | 81 | /** |
| 99 | 82 | * Using the step's ID, get the progress of the step should it exist |
| @@ -104,9 +87,9 @@ | ||
| 104 | 87 | * @type bool $is_marked_completed |
| 105 | 88 | * @type bool $is_completed |
| 106 | 89 | * } |
| 107 | 90 | */ |
| 108 | - public function get_step_progress( $step_id ): ?array { | |
| 91 | + public function get_step_progress( $step_id ) : ?array { | |
| 109 | 92 | return $this->user_progress['steps'][ $step_id ] ?? null; |
| 110 | 93 | } |
| 111 | 94 | |
| 112 | 95 | /** |
| @@ -116,37 +99,17 @@ | ||
| 116 | 99 | * @param $step_progress |
| 117 | 100 | * |
| 118 | 101 | * @return void |
| 119 | 102 | */ |
| 120 | - public function set_step_progress( $step_id, $step_progress ): void { | |
| 103 | + public function set_step_progress( $step_id, $step_progress ) : void { | |
| 121 | 104 | $this->user_progress['steps'][ $step_id ] = $step_progress; |
| 122 | 105 | $this->update_user_progress_in_db(); |
| 123 | 106 | } |
| 124 | 107 | |
| 125 | - public function update_user_progress( $new_data ): void { | |
| 126 | - $allowed_properties = [ | |
| 127 | - self::FIRST_CLOSED_CHECKLIST_IN_EDITOR => $new_data[ self::FIRST_CLOSED_CHECKLIST_IN_EDITOR ] ?? null, | |
| 128 | - self::LAST_OPENED_TIMESTAMP => $new_data[ self::LAST_OPENED_TIMESTAMP ] ?? null, | |
| 129 | - self::IS_POPUP_MINIMIZED_KEY => $new_data[ self::IS_POPUP_MINIMIZED_KEY ] ?? null, | |
| 130 | - ]; | |
| 131 | - | |
| 132 | - foreach ( $allowed_properties as $key => $value ) { | |
| 133 | - if ( null !== $value ) { | |
| 134 | - $this->user_progress[ $key ] = $this->get_formatted_value( $key, $value ); | |
| 135 | - } | |
| 136 | - } | |
| 137 | - | |
| 138 | - $this->update_user_progress_in_db(); | |
| 139 | - | |
| 140 | - if ( isset( $new_data[ Elementor_Counter::EDITOR_COUNTER_KEY ] ) ) { | |
| 141 | - $this->elementor_adapter->set_count( Elementor_Counter::EDITOR_COUNTER_KEY, $new_data[ Elementor_Counter::EDITOR_COUNTER_KEY ] ); | |
| 142 | - } | |
| 143 | - } | |
| 144 | - | |
| 145 | 108 | /** |
| 146 | 109 | * @return Steps_Manager |
| 147 | 110 | */ |
| 148 | - public function get_steps_manager(): Steps_Manager { | |
| 111 | + public function get_steps_manager() : Steps_Manager { | |
| 149 | 112 | return $this->steps_manager; |
| 150 | 113 | } |
| 151 | 114 | |
| 152 | 115 | /** |
| @@ -151,20 +114,13 @@ | ||
| 151 | 114 | |
| 152 | 115 | /** |
| 153 | 116 | * @return Wordpress_Adapter |
| 154 | 117 | */ |
| 155 | - public function get_wordpress_adapter(): Wordpress_Adapter { | |
| 118 | + public function get_wordpress_adapter() : Wordpress_Adapter { | |
| 156 | 119 | return $this->wordpress_adapter; |
| 157 | 120 | } |
| 158 | 121 | |
| 159 | - /** | |
| 160 | - * @return Elementor_Adapter | |
| 161 | - */ | |
| 162 | - public function get_elementor_adapter(): Elementor_Adapter { | |
| 163 | - return $this->elementor_adapter; | |
| 164 | - } | |
| 165 | - | |
| 166 | - public function enqueue_editor_scripts(): void { | |
| 122 | + public function enqueue_editor_scripts() : void { | |
| 167 | 123 | add_action( 'elementor/editor/before_enqueue_scripts', function () { |
| 168 | 124 | $min_suffix = Utils::is_script_debug() ? '' : '.min'; |
| 169 | 125 | |
| 170 | 126 | wp_enqueue_script( |
| @@ -186,59 +142,28 @@ | ||
| 186 | 142 | wp_set_script_translations( $this->get_name(), 'elementor' ); |
| 187 | 143 | } ); |
| 188 | 144 | } |
| 189 | 145 | |
| 190 | - public function is_preference_switch_on(): bool { | |
| 191 | - if ( $this->should_switch_preferences_off() ) { | |
| 192 | - return false; | |
| 193 | - } | |
| 194 | - | |
| 195 | - $user_preferences = $this->wordpress_adapter->get_user_preferences( self::VISIBILITY_SWITCH_ID ); | |
| 196 | - | |
| 197 | - return 'yes' === $user_preferences || $this->wordpress_adapter->is_new_installation(); | |
| 146 | + private function register_experiment() : void { | |
| 147 | + Plugin::$instance->experiments->add_feature( [ | |
| 148 | + 'name' => self::EXPERIMENT_ID, | |
| 149 | + 'title' => esc_html__( 'Launchpad Checklist', 'elementor' ), | |
| 150 | + 'description' => esc_html__( 'Launchpad Checklist feature to boost productivity and deliver your site faster', 'elementor' ), | |
| 151 | + 'release_status' => Manager::RELEASE_STATUS_ALPHA, | |
| 152 | + 'hidden' => true, | |
| 153 | + ] ); | |
| 198 | 154 | } |
| 199 | 155 | |
| 200 | - public function should_switch_preferences_off(): bool { | |
| 201 | - return ! $this->elementor_adapter->is_active_kit_default() && ! $this->user_progress[ self::LAST_OPENED_TIMESTAMP ] && ! $this->elementor_adapter->get_count( Elementor_Counter::EDITOR_COUNTER_KEY ); | |
| 202 | - } | |
| 156 | + private function init_user_progress() : void { | |
| 157 | + $default_settings = [ | |
| 158 | + 'is_hidden' => false, | |
| 159 | + 'last_opened_timestamp' => time(), | |
| 160 | + 'steps' => [], | |
| 161 | + ]; | |
| 203 | 162 | |
| 204 | - private function init_user_progress(): void { | |
| 205 | - $default_settings = $this->get_default_user_progress(); | |
| 206 | - | |
| 207 | 163 | $this->wordpress_adapter->add_option( self::DB_OPTION_KEY, wp_json_encode( $default_settings ) ); |
| 208 | 164 | } |
| 209 | 165 | |
| 210 | - private function get_default_user_progress(): array { | |
| 211 | - return [ | |
| 212 | - self::LAST_OPENED_TIMESTAMP => null, | |
| 213 | - self::FIRST_CLOSED_CHECKLIST_IN_EDITOR => false, | |
| 214 | - self::IS_POPUP_MINIMIZED_KEY => false, | |
| 215 | - 'steps' => [], | |
| 216 | - ]; | |
| 217 | - } | |
| 218 | - | |
| 219 | - private function update_user_progress_in_db(): void { | |
| 166 | + private function update_user_progress_in_db() : void { | |
| 220 | 167 | $this->wordpress_adapter->update_option( self::DB_OPTION_KEY, wp_json_encode( $this->user_progress ) ); |
| 221 | - } | |
| 222 | - | |
| 223 | - private function get_formatted_value( $key, $value ) { | |
| 224 | - if ( self::LAST_OPENED_TIMESTAMP === $key ) { | |
| 225 | - return $value ? time() : null; | |
| 226 | - } | |
| 227 | - | |
| 228 | - return $value; | |
| 229 | - } | |
| 230 | - | |
| 231 | - private function handle_checklist_visibility_with_kit() { | |
| 232 | - if ( ! $this->should_switch_preferences_off() ) { | |
| 233 | - return; | |
| 234 | - } | |
| 235 | - | |
| 236 | - add_action( 'elementor/editor/init', function () { | |
| 237 | - $this->wordpress_adapter->set_user_preferences( self::VISIBILITY_SWITCH_ID, '' ); | |
| 238 | - }, 11 ); | |
| 239 | - } | |
| 240 | - | |
| 241 | - public static function should_display_checklist_toggle_control(): bool { | |
| 242 | - return current_user_can( 'manage_options' ); | |
| 243 | 168 | } |
| 244 | 169 | } |