PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.3.0
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.3.0
2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 1.8.1 All 42 releases
sellkit / includes / elementor / modules / optin / module.php

module.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 2.3.0, at includes/elementor/modules/optin/module.php

318 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined( 'ABSPATH' ) || die();
4
5 use Elementor\Plugin as Elementor;
6 use Elementor\Icons_Manager as Icon_Manager;
7 use Elementor\Utils as Utils;
8
9 class Sellkit_Elementor_Optin_Module extends Sellkit_Elementor_Base_Module {
10
11 public static $field_types = [];
12
13 public static $action_types = [];
14
15 public static $messages = [];
16
17 public function __construct() {
18 parent::__construct();
19
20 $this->load_controls();
21 $this->register_field_types();
22 $this->register_action_types();
23 $this->set_messages();
24 $this->localize_editor_nonce();
25 $this->localize_validation_translations();
26
27 if ( is_admin() ) {
28 sellkit()->load_files( [
29 'elementor/controls/file-uploader',
30 ] );
31
32 add_action( 'wp_ajax_sellkit_control_file_upload', [ Sellkit_Elementor_Controls_File_Uploader::class, 'handle_file_upload' ] );
33 }
34 }
35
36 public function get_widgets() {
37 return [ 'optin' ];
38 }
39
40 /**
41 * Load files in "controls" directory which hold the control adding methods.
42 *
43 * @access private
44 * @since 1.5.0
45 */
46 private function load_controls() {
47 sellkit()->load_files( [
48 'elementor/modules/optin/controls/tab-content',
49 'elementor/modules/optin/controls/tab-style',
50 ] );
51 }
52
53 /**
54 * Get types of Optin form fields available.
55 *
56 * @return array
57 *
58 * @access public
59 * @static
60 * @since 1.5.0
61 */
62 public static function get_field_types() {
63 return [
64 'text' => esc_html__( 'Text', 'sellkit' ),
65 'number' => esc_html__( 'Number', 'sellkit' ),
66 'email' => esc_html__( 'Email', 'sellkit' ),
67 'tel' => esc_html__( 'Tel', 'sellkit' ),
68 'textarea' => esc_html__( 'Textarea', 'sellkit' ),
69 'date' => esc_html__( 'Date', 'sellkit' ),
70 'time' => esc_html__( 'Time', 'sellkit' ),
71 'checkbox' => esc_html__( 'Checkbox', 'sellkit' ),
72 'radio' => esc_html__( 'Radio', 'sellkit' ),
73 'select' => esc_html__( 'Select', 'sellkit' ),
74 'address' => esc_html__( 'Address', 'sellkit' ),
75 'acceptance' => esc_html__( 'Acceptance', 'sellkit' ),
76 'hidden' => esc_html__( 'Hidden', 'sellkit' ),
77 ];
78 }
79
80 /**
81 * Registers the field types defined in the get_field_types by creating
82 * instance from their classes.\
83 * Also loads Field_Base class.
84 *
85 * @access private
86 * @since 1.5.0
87 */
88 private function register_field_types() {
89 // Register base class of fields.
90 sellkit()->load_files( [ 'elementor/modules/optin/fields/field-base' ] );
91
92 // Register fields.
93 foreach ( self::get_field_types() as $field_key => $field_label ) {
94 $class_path = "elementor/modules/optin/fields/{$field_key}";
95 sellkit()->load_files( [ $class_path ] );
96
97 $class_name = 'Sellkit_Elementor_Optin_Field_' . ucfirst( $field_key );
98
99 self::$field_types[ $field_key ] = new $class_name();
100 }
101 }
102
103 /**
104 * Get types of available Optin actions.
105 *
106 * @return array
107 *
108 * @access public
109 * @static
110 * @since 1.5.0
111 */
112 public static function get_action_types() {
113 return [
114 'growmatik' => esc_html__( 'Growmatik', 'sellkit' ),
115 'activecampaign' => esc_html__( 'ActiveCampaign', 'sellkit' ),
116 'convertkit' => esc_html__( 'ConvertKit', 'sellkit' ),
117 'drip' => esc_html__( 'Drip', 'sellkit' ),
118 'getresponse' => esc_html__( 'GetResponse', 'sellkit' ),
119 'mailchimp' => esc_html__( 'MailChimp', 'sellkit' ),
120 'mailerlite' => esc_html__( 'MailerLite', 'sellkit' ),
121 'webhook' => esc_html__( 'WebHook', 'sellkit' ),
122 ];
123 }
124
125 /**
126 * Registers the actions defined in the get_action_types by creating
127 * instance from their classes.\
128 * Also loades of Action_Base class, CRM actions trait and creates instance of Download action.
129 *
130 * @access private
131 * @since 1.5.0
132 */
133 private function register_action_types() {
134 // Register base class of actions, AJAX handler and CRM integration trait.
135 sellkit()->load_files(
136 [
137 'elementor/modules/optin/actions/utils/action-base',
138 'elementor/modules/optin/actions/utils/ajax-handler',
139 'elementor/modules/optin/actions/utils/crm-trait',
140 ]
141 );
142
143 // Create AJAX handler instance to register its hooks.
144 new Sellkit_Elementor_Optin_Ajaxhandler();
145
146 // Register every single action.
147 foreach ( self::get_action_types() as $action_key => $action_label ) {
148 $class_path = "elementor/modules/optin/actions/{$action_key}";
149 sellkit()->load_files( [ $class_path ] );
150
151 $class_name = 'Sellkit_Elementor_Optin_Action_' . ucfirst( $action_key );
152
153 self::$action_types[ $action_key ] = new $class_name();
154 }
155
156 // Add Download and Redirect action separately as it should be always
157 // available and not be in the list above.
158 sellkit()->load_files( [ 'elementor/modules/optin/actions/download-redirect' ] );
159
160 new Sellkit_Elementor_Optin_Action_Download_Redirect();
161 }
162
163 /**
164 * Set $messages array propery.
165 *
166 * @access public
167 * @since 1.5.0
168 */
169 public function set_messages() {
170 self::$messages = [
171 'success' => esc_html__( 'The form was sent successfully!', 'sellkit' ),
172 'error' => esc_html__( 'Please check the errors.', 'sellkit' ),
173 'required' => esc_html__( 'Required', 'sellkit' ),
174 ];
175 }
176
177 /**
178 * Renders form field.
179 *
180 * Calls the "render_content" method in the corresponding field class.
181 *
182 * @param object $widget Widget instance.
183 * @param array $field Field settings.
184 *
185 * @access public
186 * @static
187 * @since 1.5.0
188 */
189 public static function render_field( $widget, $field ) {
190 self::$field_types[ $field['type'] ]->render( $widget, $field );
191 }
192
193 /**
194 * Render icon based on settings.
195 *
196 * @param Array $icon_data including "library" and "value".
197 *
198 * @access public
199 * @static
200 * @since 1.5.0
201 * @SuppressWarnings(PHPMD.NPathComplexity)
202 */
203 public static function render_icon( $icon_data ) {
204 // Scenario 1: if font icon experimental feature is activated, it's preferred.
205 if ( Elementor::$instance->experiments->is_feature_active( 'e_font_icon_svg' ) && $icon_data['value'] ) {
206 if ( 'svg' === $icon_data['library'] ) {
207 $font_icon = Icon_Manager::render_uploaded_svg_icon( $icon_data['value'] );
208 } else {
209 $font_icon = Icon_Manager::render_font_icon( $icon_data );
210 }
211
212 if ( ! empty( $font_icon ) ) {
213 Utils::print_unescaped_internal_string( $font_icon );
214
215 return;
216 }
217 }
218
219 // Scenario 2: Otherwise, when the user has used font awesome option.
220 if ( 'svg' !== $icon_data['library'] && ! empty( $icon_data['value'] ) ) {
221 echo '<i class="' . esc_attr( $icon_data['value'] ) . '"></i>';
222 return;
223 }
224
225 // Scenario 3: Otherwise, when the user has used upload svg option.
226 if ( 'svg' === $icon_data['library'] && $icon_data['value'] && ! empty( $icon_data['value']['url'] ) ) {
227 echo '<object type="image/svg+xml" data="' . esc_attr( $icon_data['value']['url'] ) . '"></object>';
228 }
229 }
230
231 /**
232 * Get active breakpoint of the Elementor.
233 *
234 * @return array Active Elementor breakpoints and their sizes.
235 * @access public
236 * @static
237 * @since 1.5.0
238 */
239 public static function get_active_breakpoints() {
240 $breakpoints = Elementor::$instance->breakpoints->get_breakpoints_config();
241 $result = [ 'desktop' => '' ];
242
243 foreach ( $breakpoints as $device => $config ) {
244 if ( $config['is_enabled'] ) {
245 $result[ $device ] = $config['value'];
246 }
247 }
248
249 return $result;
250 }
251
252 /**
253 * Localize a nonce for AJAX calls inside editor panel.
254 *
255 * @access private
256 * @since 1.5.0
257 */
258 private function localize_editor_nonce() {
259 add_action( 'elementor/editor/after_enqueue_scripts', function() {
260 wp_localize_script(
261 'sellkit-editor',
262 'sellkitNonceEditorOptin',
263 [ wp_create_nonce( 'sellkit_optin_editor' ) ]
264 );
265 }, 20 );
266 }
267
268 /**
269 * Localize the translation strings needed by JS to render validation errors
270 *
271 * @access private
272 * @since 1.5.0
273 */
274 private function localize_validation_translations() {
275 $translations = [
276 'general' => [
277 'errorExists' => self::$messages['error'],
278 'required' => self::$messages['required'],
279 'invalidEmail' => esc_html__( 'Invalid Email address.', 'sellkit' ),
280 'invalidPhone' => esc_html__( 'The value should only consist numbers and phone characters (-, +, (), etc).', 'sellkit' ),
281 'invalidNumber' => esc_html__( 'Invalid number.', 'sellkit' ),
282 'invalidMaxValue' => esc_html__( 'Value must be less than or equal to MAX_VALUE.', 'sellkit' ),
283 'invalidMinValue' => esc_html__( 'Value must be greater than or equal to MIN_VALUE.', 'sellkit' ),
284 ],
285 // Validation messages specific to Intelligent Tel Input plugin.
286 'itiValidation' => [
287 'invalidCountryCode' => esc_html__( 'Invalid country code.', 'sellkit' ),
288 'tooShort' => esc_html__( 'Phone number is too short.', 'sellkit' ),
289 'tooLong' => esc_html__( 'Phone number is too long.', 'sellkit' ),
290 'areaCodeMissing' => esc_html__( 'Area code is required..', 'sellkit' ),
291 'invalidLength' => esc_html__( 'Phone number has an invalid length.', 'sellkit' ),
292 'invalidGeneral' => esc_html__( 'Invalid phone number.', 'sellkit' ),
293 'typeMismatch' => [
294 '0' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Fixed Line', 'sellkit' ) . '.',
295 '1' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Mobile', 'sellkit' ) . '.',
296 '2' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Fixed Line or Mobile', 'sellkit' ) . '.',
297 '3' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Toll Free', 'sellkit' ) . '.',
298 '4' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Premium Rate', 'sellkit' ) . '.',
299 '5' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Shared Cost', 'sellkit' ) . '.',
300 '6' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'VOIP', 'sellkit' ) . '.',
301 '7' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Personal Number', 'sellkit' ) . '.',
302 '8' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Pager', 'sellkit' ) . '.',
303 '9' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'UAN', 'sellkit' ) . '.',
304 '10' => esc_html__( 'Phone number must be of type: ', 'sellkit' ) . esc_html__( 'Voicemail', 'sellkit' ) . '.',
305 ],
306 ],
307 ];
308
309 add_action( 'elementor/frontend/after_enqueue_scripts', function() use ( $translations ) {
310 wp_localize_script(
311 'sellkit-initialize-widgets',
312 'sellkitOptinValidationsTranslations',
313 $translations
314 );
315 }, 20 );
316 }
317 }
318