PluginProbe
Elementor Website Builder – more than just a page builder / 3.32.0-dev3
Elementor Website Builder – more than just a page builder v3.32.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 / pro-free-trial-popup / module.php

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

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