PluginProbe
Elementor Website Builder – more than just a page builder / 3.25.0-dev3
Elementor Website Builder – more than just a page builder v3.25.0-dev3
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 4.0.7 All 451 releases
elementor / modules / checklist / module.php

module.php in Elementor Website Builder – more than just a page builder 3.25.0-dev3, at modules/checklist/module.php

266 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\Checklist;
4
5 use Elementor\Core\Base\Module as BaseModule;
6 use Elementor\Core\Experiments\Manager;
7 use Elementor\Core\Upgrade\Manager as Upgrade_Manager;
8 use Elementor\Core\Settings\Manager as SettingsManager;
9 use Elementor\Core\Isolation\Wordpress_Adapter;
10 use Elementor\Core\Isolation\Wordpress_Adapter_Interface;
11 use Elementor\Core\Isolation\Kit_Adapter;
12 use Elementor\Core\Isolation\Kit_Adapter_Interface;
13 use Elementor\Plugin;
14 use Elementor\Utils;
15 use Elementor\Modules\Checklist\Data\Controller;
16 use Elementor\Modules\EditorAppBar\Module as AppBarModule;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit; // Exit if accessed directly.
20 }
21
22 class Module extends BaseModule implements Checklist_Module_Interface {
23 const EXPERIMENT_ID = 'launchpad-checklist';
24 const DB_OPTION_KEY = 'elementor_checklist';
25 const VISIBILITY_SWITCH_ID = 'show_launchpad_checklist';
26 const FIRST_CLOSED_CHECKLIST_IN_EDITOR = 'first_closed_checklist_in_editor';
27 const LAST_OPENED_TIMESTAMP = 'last_opened_timestamp';
28 const IS_POPUP_MINIMIZED_KEY = 'is_popup_minimized';
29 const EDITOR_VISIT_COUNT = 'editor_visit_count';
30
31 private Steps_Manager $steps_manager;
32 private Wordpress_Adapter_Interface $wordpress_adapter;
33 private Kit_Adapter_Interface $kit_adapter;
34 private $user_progress = null;
35
36 /**
37 * @param ?Wordpress_Adapter_Interface $wordpress_adapter
38 * @param ?Kit_Adapter_Interface $kit_adapter
39 *
40 * @return void
41 */
42 public function __construct( ?Wordpress_Adapter_Interface $wordpress_adapter = null, ?Kit_Adapter_Interface $kit_adapter = null ) {
43 $this->wordpress_adapter = $wordpress_adapter ?? new Wordpress_Adapter();
44 $this->kit_adapter = $kit_adapter ?? new Kit_Adapter();
45 parent::__construct();
46
47 $this->register_experiment();
48 $this->init_user_progress();
49
50 if ( ! $this->is_experiment_active() ) {
51 return;
52 }
53
54 add_action( 'elementor/editor/init', [ $this, 'monitor_editor_visits' ] );
55
56 Plugin::$instance->data_manager_v2->register_controller( new Controller() );
57 $this->user_progress = $this->user_progress ?? $this->get_user_progress_from_db();
58 $this->steps_manager = new Steps_Manager( $this );
59
60 if ( ! current_user_can( 'manage_options' ) ) {
61 return;
62 }
63
64 $this->enqueue_editor_scripts();
65 }
66
67 /**
68 * Get the module name.
69 *
70 * @return string
71 */
72 public function get_name() : string {
73 return 'e-checklist';
74 }
75
76 /**
77 * Checks if the experiment is active
78 *
79 * @return bool
80 */
81 public function is_experiment_active() : bool {
82 return Plugin::$instance->experiments->is_feature_active( self::EXPERIMENT_ID );
83 }
84
85 /**
86 * Gets user's progress from db
87 *
88 * @return array {
89 * @type bool $is_hidden
90 * @type int $last_opened_timestamp
91 * @type array $steps {
92 * @type string $step_id => {
93 * @type bool $is_marked_completed
94 * @type bool $is_absolute_competed
95 * @type bool $is_immutable_completed
96 * }
97 * }
98 * }
99 */
100 public function get_user_progress_from_db() : array {
101 return array_merge(
102 $this->get_default_user_progress(),
103 json_decode( $this->wordpress_adapter->get_option( self::DB_OPTION_KEY ), true )
104 );
105 }
106
107 /**
108 * Using the step's ID, get the progress of the step should it exist
109 *
110 * @param $step_id
111 *
112 * @return null|array {
113 * @type bool $is_marked_completed
114 * @type bool $is_completed
115 * }
116 */
117 public function get_step_progress( $step_id ) : ?array {
118 return $this->user_progress['steps'][ $step_id ] ?? null;
119 }
120
121 /**
122 * Update the progress of a step
123 *
124 * @param $step_id
125 * @param $step_progress
126 *
127 * @return void
128 */
129 public function set_step_progress( $step_id, $step_progress ) : void {
130 $this->user_progress['steps'][ $step_id ] = $step_progress;
131 $this->update_user_progress_in_db();
132 }
133
134 public function update_user_progress( $new_data ) : void {
135 $allowed_properties = [
136 self::FIRST_CLOSED_CHECKLIST_IN_EDITOR => $new_data[ self::FIRST_CLOSED_CHECKLIST_IN_EDITOR ] ?? null,
137 self::LAST_OPENED_TIMESTAMP => $new_data[ self::LAST_OPENED_TIMESTAMP ] ?? null,
138 self::IS_POPUP_MINIMIZED_KEY => $new_data[ self::IS_POPUP_MINIMIZED_KEY ] ?? null,
139 self::EDITOR_VISIT_COUNT => $new_data[ self::EDITOR_VISIT_COUNT ] ?? null,
140 ];
141
142 foreach ( $allowed_properties as $key => $value ) {
143 if ( null !== $value ) {
144 $this->user_progress[ $key ] = $value;
145 }
146 }
147
148 $this->update_user_progress_in_db();
149 }
150
151 /**
152 * @return Steps_Manager
153 */
154 public function get_steps_manager() : Steps_Manager {
155 return $this->steps_manager;
156 }
157
158 /**
159 * @return Wordpress_Adapter
160 */
161 public function get_wordpress_adapter() : Wordpress_Adapter {
162 return $this->wordpress_adapter;
163 }
164
165 /**
166 * @return Kit_Adapter
167 */
168 public function get_kit_adapter() : Kit_Adapter {
169 return $this->kit_adapter;
170 }
171
172 public function enqueue_editor_scripts() : void {
173 add_action( 'elementor/editor/before_enqueue_scripts', function () {
174 $min_suffix = Utils::is_script_debug() ? '' : '.min';
175
176 wp_enqueue_script(
177 $this->get_name(),
178 ELEMENTOR_ASSETS_URL . 'js/checklist' . $min_suffix . '.js',
179 [
180 'react',
181 'react-dom',
182 'elementor-common',
183 'elementor-v2-ui',
184 'elementor-v2-icons',
185 'elementor-v2-editor-app-bar',
186 'elementor-web-cli',
187 ],
188 ELEMENTOR_VERSION,
189 true
190 );
191
192 wp_set_script_translations( $this->get_name(), 'elementor' );
193 } );
194 }
195
196 public static function is_preference_switch_on() : bool {
197 $user_preferences = SettingsManager::get_settings_managers( 'editorPreferences' )
198 ->get_model()
199 ->get_settings( self::VISIBILITY_SWITCH_ID );
200 $is_new_installation = Upgrade_Manager::is_new_installation() ? 'yes' : '';
201 $is_preference_switch_on = $user_preferences ?? $is_new_installation;
202
203 return 'yes' === $is_preference_switch_on;
204 }
205
206 public function monitor_editor_visits() {
207 if ( ! $this->is_experiment_active() || ! self::is_preference_switch_on() ) {
208 return;
209 }
210
211 $progress = $this->get_user_progress_from_db();
212 $progress[ self::EDITOR_VISIT_COUNT ] = $progress[ self::EDITOR_VISIT_COUNT ] ?? 0;
213
214 if ( -1 === $progress[ self::EDITOR_VISIT_COUNT ] ) {
215 return;
216 }
217
218 if ( 2 < ++$progress[ self::EDITOR_VISIT_COUNT ] ) {
219 $progress[ self::EDITOR_VISIT_COUNT ] = -1;
220 }
221
222 $this->user_progress = $progress;
223 $this->update_user_progress_in_db();
224 }
225
226 private function register_experiment() : void {
227 Plugin::$instance->experiments->add_feature( [
228 'name' => self::EXPERIMENT_ID,
229 'title' => esc_html__( 'Launchpad Checklist', 'elementor' ),
230 'description' => esc_html__( 'Launchpad Checklist feature to boost productivity and deliver your site faster', 'elementor' ),
231 'release_status' => Manager::RELEASE_STATUS_ALPHA,
232 'hidden' => true,
233 'new_site' => [
234 'default_active' => true,
235 'minimum_installation_version' => '3.25.0',
236 ],
237 ] );
238 }
239
240 private function init_user_progress() : void {
241 $default_settings = $this->get_default_user_progress();
242
243 $this->wordpress_adapter->add_option( self::DB_OPTION_KEY, wp_json_encode( $default_settings ) );
244 }
245
246 private function get_default_user_progress() : array {
247 return [
248 self::LAST_OPENED_TIMESTAMP => -1,
249 self::FIRST_CLOSED_CHECKLIST_IN_EDITOR => false,
250 self::IS_POPUP_MINIMIZED_KEY => false,
251 self::EDITOR_VISIT_COUNT => 0,
252 'steps' => [],
253 ];
254 }
255
256 private function update_user_progress_in_db() : void {
257 $this->wordpress_adapter->update_option( self::DB_OPTION_KEY, wp_json_encode( $this->user_progress ) );
258 }
259
260 public static function should_display_checklist_toggle_control() : bool {
261 return Plugin::$instance->experiments->is_feature_active( self::EXPERIMENT_ID ) &&
262 Plugin::$instance->experiments->is_feature_active( AppBarModule::EXPERIMENT_NAME ) &&
263 current_user_can( 'manage_options' );
264 }
265 }
266