PluginProbe
Elementor Website Builder – more than just a page builder / 3.35.7
Elementor Website Builder – more than just a page builder v3.35.7
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.35.7, at modules/pro-free-trial-popup/module.php

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