PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.3
Elementor Website Builder – more than just a page builder v4.0.3
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
elementor / modules / pro-free-trial-popup / module.php

module.php in Elementor Website Builder – more than just a page builder 4.0.3, at modules/pro-free-trial-popup/module.php

227 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Pro Free Trial Popup Module
4 *
5 * @package Elementor\Modules\ProFreeTrialPopup
6 * @since 3.32.0
7 */
8
9 namespace Elementor\Modules\ProFreeTrialPopup;
10
11 use Elementor\Core\Base\Module as BaseModule;
12 use Elementor\Core\Experiments\Manager as Experiments_Manager;
13 use Elementor\Core\Utils\Ab_Test;
14 use Elementor\Core\Isolation\Elementor_Adapter;
15 use Elementor\Core\Isolation\Elementor_Adapter_Interface;
16 use Elementor\Includes\EditorAssetsAPI;
17 use Elementor\Modules\ElementorCounter\Module as Elementor_Counter;
18 use Elementor\Utils;
19 use Elementor\Plugin;
20
21
22 if ( ! defined( 'ABSPATH' ) ) {
23 exit; // Exit if accessed directly.
24 }
25
26 class Module extends BaseModule {
27
28 const EXPERIMENT_NAME = 'e_pro_free_trial_popup';
29 const MODULE_NAME = 'pro-free-trial-popup';
30 const POPUP_DISPLAYED_OPTION = '_e_pro_free_trial_popup_displayed';
31 const AB_TEST_NAME = 'pro_free_trial_popup';
32 const REQUIRED_VISIT_COUNT = 4;
33 const EXTERNAL_DATA_URL = 'https://assets.elementor.com/pro-free-trial-popup/v1/pro-free-trial-popup.json';
34 const ACTIVE = 'active';
35
36 private Elementor_Adapter_Interface $elementor_adapter;
37 private array $external_data;
38
39 public function __construct() {
40 parent::__construct();
41
42 if ( ! current_user_can( 'manage_options' ) ) {
43 return;
44 }
45
46 if ( ! Plugin::$instance->experiments->is_feature_active( self::EXPERIMENT_NAME ) ) {
47 return;
48 }
49
50 if ( Utils::has_pro() ) {
51 return;
52 }
53
54 $this->external_data = $this->get_external_data();
55
56 if ( ! EditorAssetsAPI::has_valid_nested_array( $this->external_data, [ self::MODULE_NAME, 0 ] ) ) {
57 return false;
58 }
59
60 $this->elementor_adapter = new Elementor_Adapter();
61
62 add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'maybe_enqueue_popup' ] );
63 }
64
65 public function get_name() {
66 return self::MODULE_NAME;
67 }
68
69 public static function get_experimental_data(): array {
70 return [
71 'name' => self::EXPERIMENT_NAME,
72 'title' => esc_html__( 'Pro Free Trial Popup', 'elementor' ),
73 'description' => esc_html__( 'Show Pro free trial popup on 4th editor visit', 'elementor' ),
74 'hidden' => true,
75 'default' => Experiments_Manager::STATE_INACTIVE,
76 'new_site' => [
77 'default_active' => true,
78 'minimum_installation_version' => '3.32.0',
79 ],
80 ];
81 }
82
83 /**
84 * Check if popup should be enqueued and enqueue if needed
85 */
86 public function maybe_enqueue_popup(): void {
87 if ( ! $this->should_show_popup() ) {
88 return;
89 }
90
91 $this->enqueue_scripts();
92 $this->set_popup_as_displayed();
93 }
94
95 /**
96 * Determine if popup should be shown
97 *
98 * @return bool True if popup should be shown
99 */
100 private function should_show_popup(): bool {
101
102 if ( ! $this->is_feature_enabled() ) {
103 return false;
104 }
105
106 if ( $this->is_before_fourth_visit() ) {
107 return false;
108 }
109
110 if ( $this->has_popup_been_displayed() ) {
111 return false;
112 }
113
114 $result = Ab_Test::should_show_feature( self::AB_TEST_NAME );
115
116 return $result;
117 }
118
119 /**
120 * Check if feature is enabled via external JSON
121 *
122 * @return bool True if feature is enabled
123 */
124 private function is_feature_enabled(): bool {
125 $popup_data = $this->extract_popup_data( $this->external_data );
126
127 $status = $popup_data['status'] ?? '';
128 return ! empty( $status ) && self::ACTIVE === $status;
129 }
130
131 /**
132 * Get external JSON data
133 *
134 * @return array External data or empty array on failure
135 */
136 private function get_external_data(): array {
137 $editor_assets_api = new EditorAssetsAPI( $this->get_api_config() );
138 return $editor_assets_api->get_assets_data();
139 }
140
141 private function get_api_config(): array {
142 return [
143 EditorAssetsAPI::ASSETS_DATA_URL => self::EXTERNAL_DATA_URL,
144 EditorAssetsAPI::ASSETS_DATA_TRANSIENT_KEY => '_elementor_pro_free_trial_data',
145 EditorAssetsAPI::ASSETS_DATA_KEY => self::MODULE_NAME,
146 ];
147 }
148
149 /**
150 * Check if current visit is before the 4th visit
151 *
152 * @return bool True if before 4th visit
153 */
154 private function is_before_fourth_visit(): bool {
155 if ( ! $this->elementor_adapter ) {
156 return true;
157 }
158
159 $editor_visit_count = $this->elementor_adapter->get_count( Elementor_Counter::EDITOR_COUNTER_KEY );
160 return $editor_visit_count < self::REQUIRED_VISIT_COUNT;
161 }
162
163 /**
164 * Check if popup has already been displayed to this user
165 *
166 * @return bool True if already displayed
167 */
168 private function has_popup_been_displayed(): bool {
169 return (bool) get_user_meta( $this->get_current_user_id(), self::POPUP_DISPLAYED_OPTION, true );
170 }
171
172 /**
173 * Mark popup as displayed for current user
174 */
175 private function set_popup_as_displayed(): void {
176 $user_id = $this->get_current_user_id();
177 update_user_meta( $user_id, self::POPUP_DISPLAYED_OPTION, true );
178 }
179
180 /**
181 * Enqueue popup scripts
182 */
183 private function enqueue_scripts(): void {
184 $min_suffix = Utils::is_script_debug() ? '' : '.min';
185 $script_url = ELEMENTOR_ASSETS_URL . 'js/pro-free-trial-popup' . $min_suffix . '.js';
186
187 wp_enqueue_script(
188 self::MODULE_NAME,
189 $script_url,
190 [
191 'react',
192 'react-dom',
193 'elementor-common',
194 'elementor-v2-ui',
195 ],
196 ELEMENTOR_VERSION,
197 true
198 );
199
200 $popup_data = $this->extract_popup_data( $this->external_data );
201
202 wp_localize_script( self::MODULE_NAME, 'elementorProFreeTrialData', $popup_data );
203
204 wp_set_script_translations( self::MODULE_NAME, 'elementor' );
205 }
206
207 /**
208 * Extract popup data from external data
209 *
210 * @param array $external_data The full external data array
211 * @return array Popup data or empty array if not found
212 */
213 private function extract_popup_data( array $external_data ): array {
214 return $external_data[ self::MODULE_NAME ][0];
215 }
216
217 /**
218 * Get current user ID
219 *
220 * @return int Current user ID
221 */
222 private function get_current_user_id(): int {
223 $current_user = wp_get_current_user();
224 return $current_user->ID ?? 0;
225 }
226 }
227