PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta1
Elementor Website Builder – more than just a page builder v4.3.0-beta1
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 / app / modules / onboarding / module.php

module.php in Elementor Website Builder – more than just a page builder 4.3.0-beta1, at app/modules/onboarding/module.php

313 lines 9.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\App\Modules\Onboarding;
4
5 use Elementor\App\Modules\Onboarding\Data\Controller;
6 use Elementor\App\Modules\Onboarding\Storage\Entities\User_Choices;
7 use Elementor\App\Modules\Onboarding\Storage\Entities\User_Progress;
8 use Elementor\App\Modules\Onboarding\Storage\Onboarding_Progress_Manager;
9 use Elementor\Core\Base\Module as BaseModule;
10 use Elementor\Core\Settings\Manager as SettingsManager;
11 use Elementor\Includes\EditorAssetsAPI;
12 use Elementor\Plugin;
13 use Elementor\Utils;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit;
17 }
18
19 class Module extends BaseModule {
20
21 const VERSION = '2.0.0';
22 const ASSETS_BASE_URL = 'https://assets.elementor.com/onboarding/v1/strings/';
23 const ONBOARDING_OPTION = 'elementor_onboarded';
24
25 const SUPPORTED_LOCALES = [
26 'de_DE' => 'de',
27 'es_ES' => 'es',
28 'fr_FR' => 'fr',
29 'he_IL' => 'he',
30 'id_ID' => 'id',
31 'it_IT' => 'it',
32 'nl_NL' => 'nl',
33 'pl_PL' => 'pl',
34 'pt_BR' => 'pt',
35 'tr_TR' => 'tr',
36 ];
37
38 private Onboarding_Progress_Manager $progress_manager;
39
40 public function get_name(): string {
41 return 'onboarding';
42 }
43
44 public static function has_user_finished_onboarding(): bool {
45 return (bool) get_option( self::ONBOARDING_OPTION );
46 }
47
48 public function __construct() {
49 $this->progress_manager = Onboarding_Progress_Manager::instance();
50
51 Plugin::instance()->data_manager_v2->register_controller( new Controller() );
52
53 add_action( 'elementor/init', [ $this, 'on_elementor_init' ], 12 );
54 }
55
56 public function on_elementor_init(): void {
57 if ( ! Plugin::instance()->app->is_current() ) {
58 return;
59 }
60
61 $this->set_onboarding_settings();
62 $this->enqueue_fonts();
63 }
64
65 public function enqueue_fonts(): void {
66 wp_enqueue_style(
67 'elementor-onboarding-fonts',
68 'https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap',
69 [],
70 ELEMENTOR_VERSION
71 );
72 }
73
74 public function progress_manager(): Onboarding_Progress_Manager {
75 return $this->progress_manager;
76 }
77
78 private function set_onboarding_settings(): void {
79 if ( ! Plugin::instance()->common ) {
80 return;
81 }
82
83 $progress = $this->progress_manager->get_progress();
84 $choices = $this->progress_manager->get_choices();
85 $steps = $this->get_steps_config();
86
87 // If the user previously selected a theme but it's no longer the active theme,
88 // clear the theme selection so the user can re-select.
89 $this->maybe_invalidate_theme_selection( $progress, $choices );
90
91 $is_connected = $this->is_user_connected();
92
93 Plugin::$instance->app->set_settings( 'onboarding', [
94 'version' => self::VERSION,
95 'restUrl' => rest_url( 'elementor/v1/onboarding/' ),
96 'nonce' => wp_create_nonce( 'wp_rest' ),
97 'progress' => $this->validate_progress_for_steps( $progress, $steps ),
98 'choices' => $choices->to_array(),
99 'hadUnexpectedExit' => $progress->had_unexpected_exit( self::has_user_finished_onboarding() ),
100 'isConnected' => $is_connected,
101 'userName' => $this->get_user_display_name(),
102 'steps' => $steps,
103 'uiTheme' => $this->get_ui_theme_preference(),
104 'translations' => $this->get_translated_strings(),
105 'shouldShowProInstallScreen' => $is_connected ? $this->should_show_pro_install_screen() : false,
106 'isHelloThemeActive' => $this->is_hello_theme_active(),
107 'urls' => [
108 'dashboard' => admin_url(),
109 'editor' => admin_url( 'edit.php?post_type=elementor_library' ),
110 'connect' => $this->get_connect_url(),
111 'signUp' => $this->get_connect_url( 'signup' ),
112 'comparePlans' => 'https://go.elementor.com/go-pro-onboarding-editor-features-step-upgrade/',
113 'createNewPage' => Plugin::$instance->documents->get_create_new_post_url(),
114 'upgradeUrl' => 'https://go.elementor.com/go-pro-onboarding-editor-header-upgrade/',
115 ],
116 ] );
117 }
118
119 private function validate_progress_for_steps( User_Progress $progress, array $steps ): array {
120 $progress_data = $progress->to_array();
121 $step_ids = array_column( $steps, 'id' );
122 $step_count = count( $steps );
123 $fallback_step_id = $steps[0]['id'] ?? 'site_features';
124 $current_step_index = $progress->get_current_step_index() ?? 0;
125 $current_step_id = $progress->get_current_step_id() ?? $fallback_step_id;
126
127 $is_invalid_step_index = $current_step_index < 0 || $current_step_index >= $step_count;
128 $is_invalid_step_id = ! in_array( $current_step_id, $step_ids, true );
129
130 if ( $is_invalid_step_index || $is_invalid_step_id ) {
131 $current_step_id = $fallback_step_id;
132 $current_step_index = 0;
133 }
134
135 $progress_data['current_step_id'] = $current_step_id;
136 $progress_data['current_step_index'] = $current_step_index;
137 $progress_data['completed_steps'] = array_values( array_filter(
138 $progress->get_completed_steps(),
139 static fn( $step_id ) => in_array( $step_id, $step_ids, true )
140 ) );
141
142 return $progress_data;
143 }
144
145 private function is_user_connected(): bool {
146 $library = $this->get_library_app();
147
148 return $library ? $library->is_connected() : false;
149 }
150
151 private function get_connect_url( string $screen_hint = '' ): string {
152 $library = $this->get_library_app();
153
154 if ( ! $library ) {
155 return '';
156 }
157
158 return $library->get_admin_url( 'authorize', [
159 'utm_source' => 'onboarding-wizard',
160 'utm_campaign' => 'connect-account',
161 'utm_medium' => 'wp-dash',
162 'utm_term' => self::VERSION,
163 'source' => 'generic',
164 'screen_hint' => $screen_hint,
165 ] ) ?? '';
166 }
167
168 private function get_library_app() {
169 $connect = Plugin::instance()->common->get_component( 'connect' );
170
171 if ( ! $connect ) {
172 return null;
173 }
174
175 return $connect->get_app( 'library' );
176 }
177
178 public static function should_show_pro_install_screen(): bool {
179 if ( Utils::has_pro() || Utils::is_pro_installed_and_not_active() ) {
180 return false;
181 }
182
183 $connect = Plugin::$instance->common->get_component( 'connect' );
184
185 if ( ! $connect ) {
186 return false;
187 }
188
189 $pro_install_app = $connect->get_app( 'pro-install' );
190
191 if ( ! $pro_install_app || ! $pro_install_app->is_connected() ) {
192 return false;
193 }
194
195 $download_link = $pro_install_app->get_download_link();
196
197 return ! empty( $download_link );
198 }
199
200 private function get_ui_theme_preference(): string {
201 $editor_preferences = SettingsManager::get_settings_managers( 'editorPreferences' );
202
203 $ui_theme = $editor_preferences->get_model()->get_settings( 'ui_theme' );
204
205 return $ui_theme ? $ui_theme : 'auto';
206 }
207
208 private function get_user_display_name(): string {
209 $library = $this->get_library_app();
210
211 if ( ! $library || ! $library->is_connected() ) {
212 return '';
213 }
214
215 $user = $library->get( 'user' );
216
217 return $user->first_name ?? '';
218 }
219
220 private function maybe_invalidate_theme_selection( User_Progress $progress, User_Choices $choices ): void {
221 $selected_theme = $choices->get_theme_selection();
222
223 if ( empty( $selected_theme ) ) {
224 return;
225 }
226
227 $active_theme = get_stylesheet();
228
229 if ( $active_theme !== $selected_theme ) {
230 $completed = $this->filter_out_theme_selection_step( $progress->get_completed_steps() );
231 $progress->set_completed_steps( $completed );
232 $this->progress_manager->save_progress( $progress );
233
234 $choices->set_theme_selection( null );
235 $this->progress_manager->save_choices( $choices );
236 }
237 }
238
239 private function filter_out_theme_selection_step( array $steps ): array {
240 return array_values( array_filter( $steps, function ( $step ) {
241 return 'theme_selection' !== $step;
242 } ) );
243 }
244
245 private function get_translated_strings(): array {
246 $locale = $this->get_onboarding_locale();
247
248 $api = new EditorAssetsAPI( [
249 EditorAssetsAPI::ASSETS_DATA_URL => self::ASSETS_BASE_URL . $locale . '.json',
250 EditorAssetsAPI::ASSETS_DATA_TRANSIENT_KEY => '_elementor_onboarding_strings_' . $locale,
251 EditorAssetsAPI::ASSETS_DATA_KEY => 'translations',
252 ] );
253
254 return $api->get_assets_data();
255 }
256
257 private function get_onboarding_locale(): string {
258 static $flipped_locales = null;
259
260 if ( null === $flipped_locales ) {
261 $flipped_locales = array_flip( self::SUPPORTED_LOCALES );
262 }
263
264 $user_locale = get_user_locale();
265
266 if ( isset( self::SUPPORTED_LOCALES[ $user_locale ] ) ) {
267 return $user_locale;
268 }
269
270 $locale = substr( $user_locale, 0, 2 );
271
272 if ( isset( $flipped_locales[ $locale ] ) ) {
273 return $flipped_locales[ $locale ];
274 }
275
276 return 'en';
277 }
278
279 private function get_steps_config(): array {
280 $steps = [
281 [
282 'id' => 'theme_selection',
283 'label' => __( 'Start with a theme that fits your needs', 'elementor' ),
284 'type' => 'single',
285 ],
286 ];
287
288 if ( ! self::is_elementor_pro_installed() ) {
289 $steps[] = [
290 'id' => 'site_features',
291 'label' => __( 'What do you want to include in your site?', 'elementor' ),
292 'type' => 'multiple',
293 ];
294 }
295
296 return apply_filters( 'elementor/onboarding/steps', $steps );
297 }
298
299 private static function is_elementor_pro_installed(): bool {
300 $is_pro_installed = Utils::has_pro();
301 return (bool) apply_filters( 'elementor/onboarding/is_elementor_pro_installed', $is_pro_installed );
302 }
303
304 private function is_hello_theme_active(): bool {
305 $active_theme = get_stylesheet();
306 $is_active = 0 === strpos( $active_theme, 'hello-' );
307
308 $is_active = (bool) apply_filters( 'elementor/onboarding/is_hello_theme_active', $is_active );
309
310 return (bool) apply_filters( 'elementor/onboarding/is_elementor_theme_active', $is_active );
311 }
312 }
313