PluginProbe
Visual Website Optimizer / 4.7
Visual Website Optimizer v4.7
trunk 1.0 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.10 All 37 releases
← All changes | visual-website-optimizer.php +757 -184 3.94.7 View file →
@@ -1,38 +1,36 @@
1 1 <?php
2 -/*
3 -Plugin Name: VWO
4 -Plugin URI: https://vwo.com/
5 -Description: VWO is the all-in-one platform that helps you conduct visitor research, build an optimization roadmap, and run continuous experimentation. Simply enable the plugin and start running tests on your Wordpress website without doing any other code changes. Visit <a href="https://vwo.com/">VWO</a> for more details.
6 -Author: VWO
7 -Version: 3.9
8 -visual-website-optimizer.php
9 -Author URI: https://vwo.com/
2 +/**
3 + *
4 + * Plugin Name: VWO
5 + * Plugin URI: https://vwo.com/
6 + * Description: VWO is the all-in-one platform that helps you conduct visitor research, build an optimization roadmap, and run continuous experimentation. Simply enable the plugin and start running tests on your WordPress website without doing any other code changes. Visit <a href="https://vwo.com/">VWO</a> for more details.
7 + * Author: VWO
8 + * Version: 4.7
9 + * visual-website-optimizer.php
10 + * Author URI: https://vwo.com/
11 + *
12 + * @package VWO
13 + * @author VWO
14 + * @version 4.7
15 + **/
10 16
11 -This relies on the actions being present in the themes header.php and footer.php
12 -* header.php code before the closing </head> tag
13 -* wp_head();
14 -*
15 -*/
16 -
17 -//------------------------------------------------------------------------//
18 -//---Config---------------------------------------------------------------//
19 -//------------------------------------------------------------------------//
20 -
21 17 /**
22 18 * Generate Common Code
23 - * @param type $vwo_id integer
24 - * @return type string
19 + *
20 + * @param integer $vwo_clicks integer. Defaults to 10.
25 21 */
26 -function get_vwo_clhf_script_common_code($vwo_clicks = 10) {
22 +function get_vwo_clhf_script_common_code( $vwo_clicks = 10 ) {
27 23 ob_start();
24 + // @codingStandardsIgnoreStart
28 25 ?>
29 26 <!-- Start VWO Common Smartcode -->
30 27 <script <?php echo vwo_clhf_ignore_js_attr(); ?> type='text/javascript'>
31 - var _vwo_clicks = <?php echo $vwo_clicks ?>;
28 + var _vwo_clicks = <?php echo esc_html( $vwo_clicks ); ?>;
32 29 </script>
33 30 <!-- End VWO Common Smartcode -->
34 31 <?php
32 + // @codingStandardsIgnoreEnd
35 33 $script_code = ob_get_clean();
36 34 return $script_code;
37 35 }
38 36
@@ -37,25 +35,27 @@
37 35 }
38 36
39 37 /**
40 38 * Get ignore js field setting
41 - * @return type boolean
39 + *
40 + * @return bool boolean
42 41 */
43 -function get_vwo_clhf_ignore_js(){
44 - $ignore_js = get_option('ignore_js');
45 - $ignore_js = ($ignore_js == '1') ? true : false;
42 +function get_vwo_clhf_ignore_js() {
43 + $ignore_js = get_option( 'ignore_js' );
44 + $ignore_js = ( '1' === $ignore_js ) ? true : false;
46 45 return $ignore_js;
47 46 }
48 47
49 48 /**
50 49 * Get ignore js script attribute value
51 - * @return type boolean
50 + *
51 + * @return string Returns script attribute value
52 52 */
53 -function vwo_clhf_ignore_js_attr(){
53 +function vwo_clhf_ignore_js_attr() {
54 54 $ignore_js = get_vwo_clhf_ignore_js();
55 - $js_attr = '';
56 - if(function_exists('get_vwo_clhf_ignore_js') && $ignore_js){
57 - $js_attr = 'data-cfasync="false"';
55 + $js_attr = '';
56 + if ( function_exists( 'get_vwo_clhf_ignore_js' ) && $ignore_js ) {
57 + $js_attr = 'data-cfasync="false" nowprocket';
58 58 }
59 59 return $js_attr;
60 60 }
61 61
@@ -60,18 +60,21 @@
60 60 }
61 61
62 62 /**
63 63 * Generate Synchronous Code
64 - * @param type $vwo_id integer
65 - * @return type string
64 + *
65 + * @param int $vwo_id integer. Defaults to 0.
66 + * @return string string for sync script.
66 67 */
67 -function get_vwo_clhf_script_sync_code($vwo_id = 0) {
68 +function get_vwo_clhf_script_sync_code( $vwo_id = 0 ) {
68 69 ob_start();
70 + // @codingStandardsIgnoreStart
69 71 ?>
70 72 <!-- Start VWO Smartcode -->
71 - <script <?php echo vwo_clhf_ignore_js_attr();?> src="https://dev.visualwebsiteoptimizer.com/lib/<?php echo $vwo_id ?>.js"></script>
73 + <script <?php echo vwo_clhf_ignore_js_attr(); ?> src="https://dev.visualwebsiteoptimizer.com/lib/<?php echo esc_html( $vwo_id ); ?>.js"></script>
72 74 <!-- End VWO Smartcode -->
73 75 <?php
76 + // @codingStandardsIgnoreEnd
74 77 $sync_script = ob_get_clean();
75 78 return $sync_script;
76 79 }
77 80
@@ -76,210 +79,780 @@
76 79 }
77 80
78 81 /**
79 82 * Generate Asynchronous Code
80 - * @param type $vwo_id integer
81 - * @param type $settings_tolerance integer
82 - * @param type $library_tolerance integer
83 - * @param type $use_existing_jquery string
84 - * @return type string
83 + *
84 + * @param int $vwo_id integer.
85 + * @param int $settings_tolerance integer.
86 + * @param int $library_tolerance integer.
87 + * @param bool $use_existing_jquery boolean.
88 + * @return string String for async script.
85 89 */
86 -function get_vwo_clhf_script_async_code($vwo_id, $settings_tolerance, $library_tolerance, $use_existing_jquery) {
90 +function get_vwo_clhf_script_async_code( $vwo_id, $settings_tolerance, $library_tolerance, $use_existing_jquery ) {
87 91 ob_start();
88 -?>
89 - <!-- Start VWO Async Smartcode -->
90 - <script <?php echo vwo_clhf_ignore_js_attr(); ?> type='text/javascript'>
91 - /* Fix: wp-rocket (application/ld+json) */
92 - window._vwo_code = window._vwo_code || (function(){
93 - var account_id= <?php echo $vwo_id ?>,
94 - settings_tolerance= <?php echo $settings_tolerance ?>,
95 - library_tolerance= <?php echo $library_tolerance ?>,
96 - use_existing_jquery= <?php echo ($use_existing_jquery) ? 'true' : 'false'; ?>,
97 - is_spa=1,
98 - hide_element='body',
99 - /* DO NOT EDIT BELOW THIS LINE */
100 - f=false,d=document,code={use_existing_jquery:function(){return use_existing_jquery;},library_tolerance:function(){return library_tolerance;},finish:function(){if(!f){f=true;var a=d.getElementById('_vis_opt_path_hides');if(a)a.parentNode.removeChild(a);}},finished:function(){return f;},load:function(a){var b=d.createElement('script');b.src=a;b.type='text/javascript';b.innerText;b.onerror=function(){_vwo_code.finish();};d.getElementsByTagName('head')[0].appendChild(b);},init:function(){
101 - window.settings_timer=setTimeout('_vwo_code.finish()',settings_tolerance);var a=d.createElement('style'),b=hide_element?hide_element+'{opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important;}':'',h=d.getElementsByTagName('head')[0];a.setAttribute('id','_vis_opt_path_hides');a.setAttribute('type','text/css');if(a.styleSheet)a.styleSheet.cssText=b;else a.appendChild(d.createTextNode(b));h.appendChild(a);this.load('https://dev.visualwebsiteoptimizer.com/j.php?a='+account_id+'&u='+encodeURIComponent(d.URL)+'&f='+(+is_spa)+'&r='+Math.random());return settings_timer; }};window._vwo_settings_timer = code.init(); return code; }());
92 + // @codingStandardsIgnoreStart
93 + ?>
94 + <!-- Start VWO Async SmartCode -->
95 + <link rel="preconnect" href="https://dev.visualwebsiteoptimizer.com" />
96 + <script <?php echo vwo_clhf_ignore_js_attr(); ?> type='text/javascript' id='vwoCode'>
97 + /* Fix: wp-rocket (application/ld+json) */
98 + window._vwo_code || (function () {
99 + var account_id=<?php echo esc_html( $vwo_id ); ?>,
100 + version=2.1,
101 + settings_tolerance=<?php echo esc_html( $settings_tolerance ); ?>,
102 + library_tolerance=<?php echo esc_html( $library_tolerance ); ?>,
103 + use_existing_jquery=<?php echo ( $use_existing_jquery ) ? 'true' : 'false'; ?>,
104 + hide_element='body',
105 + hide_element_style = 'opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important;transition:none !important;',
106 + /* DO NOT EDIT BELOW THIS LINE */
107 + f=false,w=window,d=document,v=d.querySelector('#vwoCode'),cK='_vwo_'+account_id+'_settings',cc={};try{var c=JSON.parse(localStorage.getItem('_vwo_'+account_id+'_config'));cc=c&&typeof c==='object'?c:{}}catch(e){}var stT=cc.stT==='session'?w.sessionStorage:w.localStorage;code={use_existing_jquery:function(){return typeof use_existing_jquery!=='undefined'?use_existing_jquery:undefined},library_tolerance:function(){return typeof library_tolerance!=='undefined'?library_tolerance:undefined},settings_tolerance:function(){return cc.sT||settings_tolerance},hide_element_style:function(){return'{'+(cc.hES||hide_element_style)+'}'},hide_element:function(){if(performance.getEntriesByName('first-contentful-paint')[0]){return''}return typeof cc.hE==='string'?cc.hE:hide_element},getVersion:function(){return version},finish:function(e){if(!f){f=true;var t=d.getElementById('_vis_opt_path_hides');if(t)t.parentNode.removeChild(t);if(e)(new Image).src='https://dev.visualwebsiteoptimizer.com/ee.gif?a='+account_id+e}},finished:function(){return f},addScript:function(e){var t=d.createElement('script');t.type='text/javascript';if(e.src){t.src=e.src}else{t.text=e.text}d.getElementsByTagName('head')[0].appendChild(t)},load:function(e,t){var i=this.getSettings(),n=d.createElement('script'),r=this;t=t||{};if(i){n.textContent=i;d.getElementsByTagName('head')[0].appendChild(n);if(!w.VWO||VWO.caE){stT.removeItem(cK);r.load(e)}}else{var o=new XMLHttpRequest;o.open('GET',e,true);o.withCredentials=!t.dSC;o.responseType=t.responseType||'text';o.onload=function(){if(t.onloadCb){return t.onloadCb(o,e)}if(o.status===200||o.status===304){_vwo_code.addScript({text:o.responseText})}else{_vwo_code.finish('&e=loading_failure:'+e)}};o.onerror=function(){if(t.onerrorCb){return t.onerrorCb(e)}_vwo_code.finish('&e=loading_failure:'+e)};o.send()}},getSettings:function(){try{var e=stT.getItem(cK);if(!e){return}e=JSON.parse(e);if(Date.now()>e.e){stT.removeItem(cK);return}return e.s}catch(e){return}},init:function(){if(d.URL.indexOf('__vwo_disable__')>-1)return;var e=this.settings_tolerance();w._vwo_settings_timer=setTimeout(function(){_vwo_code.finish();stT.removeItem(cK)},e);var t;if(this.hide_element()!=='body'){t=d.createElement('style');var i=this.hide_element(),n=i?i+this.hide_element_style():'',r=d.getElementsByTagName('head')[0];t.setAttribute('id','_vis_opt_path_hides');v&&t.setAttribute('nonce',v.nonce);t.setAttribute('type','text/css');if(t.styleSheet)t.styleSheet.cssText=n;else t.appendChild(d.createTextNode(n));r.appendChild(t)}else{t=d.getElementsByTagName('head')[0];var n=d.createElement('div');n.style.cssText='z-index: 2147483647 !important;position: fixed !important;left: 0 !important;top: 0 !important;width: 100% !important;height: 100% !important;background: white !important;';n.setAttribute('id','_vis_opt_path_hides');n.classList.add('_vis_hide_layer');t.parentNode.insertBefore(n,t.nextSibling)}var o='https://dev.visualwebsiteoptimizer.com/j.php?a='+account_id+'&u='+encodeURIComponent(d.URL)+'&vn='+version;if(w.location.search.indexOf('_vwo_xhr')!==-1){this.addScript({src:o})}else{this.load(o+'&x=true')}}};w._vwo_code=code;code.init();})();
102 108 </script>
103 - <!-- End VWO Async Smartcode -->
109 + <!-- End VWO Async SmartCode -->
104 110 <?php
111 + // @codingStandardsIgnoreEnd
105 112 $async_script = ob_get_clean();
106 113 return $async_script;
107 114 }
108 115
109 -//------------------------------------------------------------------------//
110 -//---Hook-----------------------------------------------------------------//
111 -//------------------------------------------------------------------------//
112 -add_action( 'wp_head', 'vwo_clhf_headercode',1 );
116 +// ------------------------------------------------------------------------//
117 +// ---Hook-----------------------------------------------------------------//
118 +// ------------------------------------------------------------------------//
119 +add_action( 'wp_head', 'vwo_clhf_headercode', 1 );
113 120 add_action( 'admin_menu', 'vwo_clhf_plugin_menu' );
114 121 add_action( 'admin_init', 'vwo_clhf_register_mysettings' );
115 -add_action( 'admin_notices','vwo_clhf_warn_nosettings');
122 +add_action( 'admin_notices', 'vwo_clhf_warn_nosettings' );
116 123
117 124
118 -//------------------------------------------------------------------------//
119 -//---Functions------------------------------------------------------------//
120 -//------------------------------------------------------------------------//
125 +// ------------------------------------------------------------------------//
126 +// ---Functions------------------------------------------------------------//
127 +// ------------------------------------------------------------------------//
121 128 // options page link
129 +
130 +/**
131 + * Generate a function comment for the given function body.
132 + *
133 + * @throws Exception Description of exception.
134 + * @return void
135 + */
122 136 function vwo_clhf_plugin_menu() {
123 - add_options_page('Visual Website Optimizer', 'VWO', 'create_users', 'clhf_vwo_options', 'vwo_clhf_plugin_options');
137 + add_options_page( 'Visual Website Optimizer', 'VWO', 'create_users', 'clhf_vwo_options', 'vwo_clhf_plugin_options' );
124 138 }
125 139
126 -// whitelist settings
127 -function vwo_clhf_register_mysettings(){
128 - register_setting('clhf_vwo_options','vwo_id','intval');
129 - register_setting('clhf_vwo_options','code_type');
130 - register_setting('clhf_vwo_options','vwo_clicks');
131 - register_setting('clhf_vwo_options','ignore_js','boolval');
132 - register_setting('clhf_vwo_options','settings_tolerance','intval');
133 - register_setting('clhf_vwo_options','library_tolerance','intval');
134 - register_setting('clhf_vwo_options','use_existing_jquery','boolval');
140 +/**
141 + * Register the settings for the VWO options.
142 + *
143 + * @return void
144 + */
145 +function vwo_clhf_register_mysettings() {
146 + register_setting('clhf_vwo_options', 'vwo_id', array(
147 + 'sanitize_callback' => 'vwo_clhf_sanitize_settings',
148 + ));
149 + register_setting( 'clhf_vwo_options', 'code_type' );
150 + register_setting( 'clhf_vwo_options', 'vwo_clicks' );
151 + register_setting( 'clhf_vwo_options', 'ignore_js', 'boolval' );
152 + register_setting( 'clhf_vwo_options', 'settings_tolerance', 'intval' );
153 + register_setting( 'clhf_vwo_options', 'library_tolerance', 'intval' );
154 + register_setting( 'clhf_vwo_options', 'use_existing_jquery', 'boolval' );
155 + register_setting( 'clhf_vwo_options', 'enable_woocommerce_event_tracking', 'boolval');
156 + register_setting( 'clhf_vwo_options', 'track_product_view', 'boolval' );
157 + register_setting( 'clhf_vwo_options', 'track_add_to_cart', 'boolval' );
158 + register_setting( 'clhf_vwo_options', 'track_remove_from_cart', 'boolval' );
159 + register_setting( 'clhf_vwo_options', 'track_checkout', 'boolval' );
160 + register_setting( 'clhf_vwo_options', 'track_purchase', 'boolval' );
161 + register_setting( 'clhf_vwo_options', 'vwo_server_side_tracking', 'boolval' );
135 162 }
136 163
137 -//------------------------------------------------------------------------//
138 -//---Output Functions-----------------------------------------------------//
139 -//------------------------------------------------------------------------//
164 +// ------------------------------------------------------------------------//
165 +// ---Output Functions-----------------------------------------------------//
166 +// ------------------------------------------------------------------------//
167 +
168 +
169 +/**
170 + * Generates the action vwo_clhf_headercode function.
171 + *
172 + * @throws Exception Description of exception.
173 + * @return void
174 + */
140 175 function vwo_clhf_headercode() {
141 - // runs in the header
142 - $vwo_id = get_option('vwo_id');
143 - $code_type = get_option('code_type');
144 -
145 - if ($vwo_id) {
146 - if(empty(get_option('vwo_clicks'))){
147 - update_option('vwo_clicks', '10' );
176 + // Runs in the header.
177 + $vwo_id = get_option( 'vwo_id' );
178 + $code_type = get_option( 'code_type' );
179 +
180 + if ( $vwo_id ) {
181 + if ( empty( get_option( 'vwo_clicks' ) ) ) {
182 + update_option( 'vwo_clicks', '10' );
148 183 }
149 - $vwo_clicks = get_option('vwo_clicks');
150 - //common script code
151 - echo get_vwo_clhf_script_common_code($vwo_clicks);
152 - if ($code_type == 'SYNC') {
153 - //sync script code
154 - echo get_vwo_clhf_script_sync_code($vwo_id); // only output if options were saved
184 + $vwo_clicks = get_option( 'vwo_clicks' );
185 +
186 + // Common script code.
187 + // @codingStandardsIgnoreLine
188 + echo get_vwo_clhf_script_common_code( $vwo_clicks );
189 +
190 + if ( 'SYNC' === $code_type ) {
191 + // Sync script code.
192 + // @codingStandardsIgnoreLine
193 + echo get_vwo_clhf_script_sync_code( $vwo_id );
155 194 } else {
156 195
157 - $settings_tolerance = get_option('settings_tolerance');
158 - if (!is_numeric($settings_tolerance))
196 + $settings_tolerance = get_option( 'settings_tolerance' );
197 + if ( ! is_numeric( $settings_tolerance ) ) {
159 198 $settings_tolerance = 2000;
199 + }
160 200
161 - $library_tolerance = get_option('library_tolerance');
162 - if (!is_numeric($library_tolerance))
201 + $library_tolerance = get_option( 'library_tolerance' );
202 + if ( ! is_numeric( $library_tolerance ) ) {
163 203 $library_tolerance = 2500;
164 -
165 - $use_existing_jquery = get_option('use_existing_jquery');
166 - $use_existing_jquery = ($use_existing_jquery == 1) ? true : false;
204 + }
167 205
168 - //async script code
169 - echo get_vwo_clhf_script_async_code($vwo_id, $settings_tolerance, $library_tolerance, $use_existing_jquery);
206 + $use_existing_jquery = get_option( 'use_existing_jquery' );
207 + $use_existing_jquery = ( '1' === $use_existing_jquery ) ? true : false;
208 +
209 + // Async script code.
210 + // @codingStandardsIgnoreLine
211 + echo get_vwo_clhf_script_async_code( $vwo_id, $settings_tolerance, $library_tolerance, $use_existing_jquery );
170 212 }
171 213 }
172 214 }
173 215
174 -//------------------------------------------------------------------------//
175 -//---Page Output Functions------------------------------------------------//
176 -//------------------------------------------------------------------------//
216 +// ------------------------------------------------------------------------//
217 +// ---Page Output Functions------------------------------------------------//
218 +// ------------------------------------------------------------------------//
177 219 // options page
220 +
221 +
222 +/**
223 + * Generates the options page for the VWO plugin.
224 + *
225 + * @throws Exception Description of exception.
226 + * @return void
227 + */
178 228 function vwo_clhf_plugin_options() {
179 - //Set value for checkbox by default
180 - $ignore_js_options = get_option('ignore_js');
181 - $show_ignore_js = $ignore_js_options;
182 - if( $ignore_js_options === false ) {
183 - // nothing is set, so apply the default here
184 - $show_ignore_js = 1;
185 - update_option('ignore_js', '1');
229 +
230 + ?>
231 + <div class="wrap">
232 + <h1 style="margin-bottom: 15px;"><img src="https://static.wingify.com/gcp/images/vwo-logo-color.svg" alt="VWO Logo" style="vertical-align: middle; margin-right: 10px; margin-top: -5px; height: 20px;">Configuration</h1>
233 +
234 + <form method="post" action="options.php" novalidate>
235 + <?php
236 + settings_fields('clhf_vwo_options');
237 + ?>
238 + <div class="vwo-admin-content">
239 + <?php vwo_clhf_render_tabs(); ?>
240 + <div class="tab-content">
241 + <div id="tab-general" class="tab-pane active">
242 + <?php vwo_clhf_render_general_settings(); ?>
243 + </div>
244 + <div id="tab-advanced" class="tab-pane">
245 + <?php vwo_clhf_render_advanced_settings(); ?>
246 + </div>
247 + <div id="tab-woocommerce" class="tab-pane">
248 + <?php vwo_clhf_render_woocommerce_settings(); ?>
249 + </div>
250 + </div>
251 + </div>
252 + <?php submit_button(); ?>
253 + </form>
254 + </div>
255 + <?php
256 + vwo_clhf_render_styles();
257 + vwo_clhf_render_scripts();
258 +}
259 +
260 +function vwo_clhf_render_tabs() {
261 + ?>
262 + <h2 class="nav-tab-wrapper">
263 + <a href="#tab-general" class="nav-tab nav-tab-active">General Settings</a>
264 + <a href="#tab-advanced" class="nav-tab">Advanced Settings</a>
265 + <a href="#tab-woocommerce" class="nav-tab">WooCommerce</a>
266 + </h2>
267 + <?php
268 +}
269 +
270 +function vwo_clhf_render_general_settings() {
271 + ?>
272 + <main class="main-grid">
273 + <div class="form-container">
274 + <?php
275 + vwo_clhf_render_field([
276 + 'id' => 'vwo_id',
277 + 'label' => 'Your VWO Account ID',
278 + 'type' => 'text',
279 + 'tooltip' => 'Enter your VWO Account ID here',
280 + ]);
281 + vwo_clhf_render_field([
282 + 'id' => 'code_type',
283 + 'label' => 'Code Type',
284 + 'type' => 'radio',
285 + 'options' => [
286 + [
287 + 'label' => 'Asynchronous',
288 + 'value' => 'ASYNC',
289 + 'sublabel' => 'Loads faster without blocking other elements',
290 + ],
291 + [
292 + 'label' => 'Synchronous',
293 + 'value' => 'SYNC',
294 + 'sublabel' => 'Executes immediately but may slow down page load',
295 + ],
296 + ],
297 + ]);
298 + ?>
299 + </div>
300 + <div class="main-grid__description">
301 + <h2>Get Started Easily</h2>
302 + <p>
303 + Enter your <b>VWO Account ID</b> to begin.
304 + <br>
305 + New to VWO?
306 + <a target="_blank" href="https://vwo.com/free-trial/?utm_source=integration_wordpress&utm_medium=referral&utm_campaign=plugin_page&utm_content=config_screen_banner">Create an account</a> and start optimizing <br/>your website effortlessly.
307 + <br><br><br>
308 + Need help? Visit our <a target="_blank" href="https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress">knowledge base</a>.
309 + </p>
310 + </div>
311 + </main>
312 + <?php
313 +}
314 +
315 +function vwo_clhf_render_advanced_settings() {
316 + ?>
317 + <div class="form-container">
318 + <?php
319 + vwo_clhf_render_field([
320 + 'id' => 'vwo_clicks',
321 + 'label' => 'No. of Heatmap Clicks',
322 + 'type' => 'number',
323 + 'tooltip' => 'Set the number of heatmap clicks to record',
324 + 'min' => 3,
325 + 'default' => 10,
326 + ]);
327 + vwo_clhf_render_field([
328 + 'id' => 'settings_tolerance',
329 + 'label' => 'Settings Timeout',
330 + 'type' => 'number',
331 + 'tooltip' => 'Set the timeout for settings in milliseconds',
332 + 'default' => 2000,
333 + 'class' => 'async-option',
334 + 'suffix' => 'ms',
335 + ]);
336 + vwo_clhf_render_field([
337 + 'id' => 'library_tolerance',
338 + 'label' => 'Library Timeout',
339 + 'type' => 'number',
340 + 'tooltip' => 'Set the timeout for library in milliseconds',
341 + 'default' => 2500,
342 + 'class' => 'async-option',
343 + 'suffix' => 'ms',
344 + ]);
345 + vwo_clhf_render_field([
346 + 'id' => 'use_existing_jquery',
347 + 'label' => 'Use Existing jQuery',
348 + 'type' => 'checkbox',
349 + 'tooltip' => 'Use the existing jQuery library on your site',
350 + 'class' => 'async-option',
351 + ]);
352 + vwo_clhf_render_field([
353 + 'id' => 'ignore_js',
354 + 'label' => 'Skip Deferred Execution',
355 + 'type' => 'checkbox',
356 + 'tooltip' => 'Skip deferred execution of the VWO script',
357 + ]);
358 + ?>
359 + </div>
360 + <?php
361 +}
362 +
363 +function vwo_clhf_render_woocommerce_settings() {
364 + $value = get_option('enable_woocommerce_event_tracking', false);
365 + $vwo_server_side_tracking = get_option('vwo_server_side_tracking', false);
366 + ?>
367 + <div>
368 + <div class="woocommerce-main-header">
369 + <div class="checkbox-container">
370 + <input type="checkbox" id="enable_woocommerce_event_tracking" name="enable_woocommerce_event_tracking" class="vwo-checkbox" <?php echo checked($value, '1', false) ?>>
371 + <label class="vwo-checkbox-label" for="enable_woocommerce_event_tracking">Toggle</label>
372 + <label class="form-label form-label--checkbox" for="enable_woocommerce_event_tracking">Enable WooCommerce Event Tracking</label>
373 + </div>
374 + <p class="form-description form-description--checkbox">Event tracking will not work unless WooCommerce is enabled on your WordPress site.</p>
375 + </div>
376 + <div class="woocommerce-main-header">
377 + <div class="checkbox-container vwo_server_side_tracking">
378 + <input type="checkbox" id="vwo_server_side_tracking" name="vwo_server_side_tracking" class="vwo-checkbox" <?php echo checked($vwo_server_side_tracking, '1', false) ?>>
379 + <label class="vwo-checkbox-label" for="vwo_server_side_tracking">Toggle</label>
380 + <label class="form-label form-label--checkbox" for="Enable Server-Side Tracking">Enable Server-Side Tracking</label>
381 + </div>
382 + <p class="form-description form-description--checkbox">Enable server-side tracking instead of JavaScript-based tracking.</p>
383 + </div>
384 +
385 +
386 + <div class="woocommerce-row woocommerce-row--disabled">
387 + <?php
388 + vwo_clhf_render_woocommerce_event_tracking([
389 + 'id' => 'track_product_view',
390 + 'label' => 'Product Viewed',
391 + 'description' => 'This event logs an instance where a customer views a product details page.',
392 + 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
393 + ]);
394 + vwo_clhf_render_woocommerce_event_tracking([
395 + 'id' => 'track_add_to_cart',
396 + 'label' => 'Add To Cart',
397 + 'description' => 'This event logs an instance where a customer adds a product to their cart.',
398 + 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
399 + ]);
400 + vwo_clhf_render_woocommerce_event_tracking([
401 + 'id' => 'track_remove_from_cart',
402 + 'label' => 'Product Removed From Cart',
403 + 'description' => 'This event logs an instance where a customer removes a product from their cart.',
404 + 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
405 + ]);
406 + // vwo_clhf_render_woocommerce_event_tracking([
407 + // 'id' => 'track_checkout',
408 + // 'label' => 'Checkout Page',
409 + // 'description' => 'This event logs an instance where a customer visits the checkout page.',
410 + // 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
411 + // ]);
412 + vwo_clhf_render_woocommerce_event_tracking([
413 + 'id' => 'track_purchase',
414 + 'label' => 'Purchase Order',
415 + 'description' => 'This event logs an instance where a customer completes a purchase.',
416 + 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
417 + ]);
418 + ?>
419 + </div>
420 + </div>
421 + <?php
422 +}
423 +
424 +function vwo_clhf_render_woocommerce_event_tracking($field) {
425 + $value = get_option($field['id'], isset($field['default']) ? $field['default'] : '');
426 + ?>
427 + <div class="woocommerce-row-item">
428 + <div class="woocommerce-row-item-header">
429 + <h3 class="woocommerce-row-item-title"><?php echo esc_html($field['label']); ?></h3>
430 + <input type="checkbox" name="<?php echo esc_attr($field['id']); ?>" id="<?php echo esc_attr($field['id']); ?>" <?php echo checked($value, '1', false) ?> class="vwo-checkbox">
431 + <label for="<?php echo esc_attr($field['id']); ?>" class="vwo-checkbox-label">Toggle</label>
432 + </div>
433 + <p class="woocommerce-row-item-description">
434 + <?php echo esc_html($field['description']); ?>
435 + <?php /* if (isset($field['readmore_link'])): ?>
436 + <a href="<?php echo esc_url($field['readmore_link']); ?>" target="_blank">Read more</a>
437 + <?php endif; */ ?>
438 + </p>
439 + </div>
440 + <?php
441 +}
442 +
443 +
444 +function vwo_clhf_render_field($field) {
445 + $isCheckbox = $field['type'] === 'checkbox';
446 + $value = get_option($field['id'], isset($field['default']) ? $field['default'] : '');
447 +
448 + echo '<div class="' . esc_attr(isset($field['class'])?$field['class']:"") . '">';
449 +
450 + $label = '<label class="form-label" for="' . esc_attr($field['id']) . '">' . esc_html($field['label']) . '</label>';
451 +
452 + switch ($field['type']) {
453 + case 'text':
454 + case 'number':
455 + echo $label;
456 + echo '<input type="' . esc_attr($field['type']) . '" id="' . esc_attr($field['id']) . '" name="' . esc_attr($field['id']) . '" value="' . esc_attr($value) . '"';
457 + if (isset($field['min'])) echo ' min="' . esc_attr($field['min']) . '"';
458 + echo ' class="form-input" />';
459 + if (isset($field['suffix'])) echo ' ' . esc_html($field['suffix']);
460 + break;
461 + case 'radio':
462 + echo $label;
463 + foreach ($field['options'] as $options) {
464 + echo '<div class="radio-container-wrapper">
465 + <div class="radio-container">';
466 + echo '<label class="form-radio-label"><input type="radio" name="' . esc_attr($field['id']) . '" value="' . esc_attr($options['value']) . '"' . checked($value, $options['value'], false) . ' /> ' . esc_html($options['label']) . '</label> ';
467 + echo '</div>';
468 + echo '<p class="radio-sublabel">' . esc_html($options['sublabel']) . '</p>';
469 + echo '</div>';
470 + }
471 + break;
472 + case 'checkbox':
473 + echo '<div class="checkbox-container">';
474 + echo '<input type="checkbox" id="' . esc_attr($field['id']) . '" name="' . esc_attr($field['id']) . '" class="vwo-checkbox" value="1"' . checked($value, '1', false) . ' />';
475 + echo '<label class="vwo-checkbox-label" for="' . esc_attr($field['id']) . '">Toggle</label>';
476 + echo '<label class="form-label form-label--checkbox" for="' . esc_attr($field['id']) . '">' . esc_html($field['label']) . '</label>';
477 + echo '</div>';
478 + break;
186 479 }
187 480
188 - echo '<div class="wrap">';?>
189 - <h2>VWO</h2>
190 - <p>You need to have a <a href="https://vwo.com/">VWO</a> account in order to use this plugin. This plugin inserts the neccessary code into your Wordpress site automatically without you having to touch anything. In order to use the plugin, you need to enter your VWO Account ID:</p>
191 - <form method="post" action="options.php">
192 - <?php settings_fields( 'clhf_vwo_options' ); ?>
193 - <table class="form-table">
194 - <tr valign="top">
195 - <th scope="row">Your VWO Account ID</th>
196 - <td><input type="text" name="vwo_id" value="<?php echo get_option('vwo_id'); ?>" /></td>
197 - </tr>
198 - <tr valign="top">
199 - <th scope="row">No. of Heatmap Clicks</th>
200 - <td><input type="number" name="vwo_clicks" value="<?php echo get_option('vwo_clicks') ? get_option('vwo_clicks'):10 ; ?>" min="3"/></td>
201 - </tr>
202 - <tr valign="top">
203 - <th scope="row">Code (default: Asynchronous)</th>
204 - <td>
205 - <input style="vertical-align: text-top;" type="radio" onclick="selectCodeType();" name="code_type" id="code_type_async" value="ASYNC" <?php if(get_option('code_type')!='SYNC') echo "checked"; ?> /> Asynchronous&nbsp;&nbsp;&nbsp;
206 - <input style="vertical-align: text-top;" type="radio" onclick="selectCodeType();" name="code_type" id="code_type_sync" value="SYNC" <?php if(get_option('code_type')=='SYNC') echo "checked"; ?> /> Synchronous
207 - &nbsp;<a href="https://vwo.com/blog/asynchronous-code" target="_blank">[Help]</a>
208 - </td>
209 - </tr>
210 - <tr valign="top" id='asyncOnly1' <?php if(get_option('code_type')=='SYNC') echo "style='display:none;'" ?>>
211 - <th scope="row">Settings Timeout</th>
212 - <td style="vertical-align: middle;"><input type="text" name="settings_tolerance" value="<?php echo get_option('settings_tolerance')?get_option('settings_tolerance'):2000; ?>" />ms (default: 2000)</td>
213 - </tr>
214 - <tr valign="top" id='asyncOnly2' <?php if(get_option('code_type')=='SYNC') echo "style='display:none;'" ?>>
215 - <th scope="row">Library Timeout</th>
216 - <td style="vertical-align: middle;"><input type="text" name="library_tolerance" value="<?php echo get_option('library_tolerance')?get_option('library_tolerance'):2500; ?>" />ms (default: 2500)</td>
217 - </tr>
218 - <tr valign="top" id='asyncOnly3' <?php if(get_option('code_type')=='SYNC') echo "style='display:none;'" ?>>
219 - <th scope="row">Use Existing jQuery</th>
220 - <td style="vertical-align: middle;"><input type="checkbox" name="use_existing_jquery" value="1" <?php if(get_option('use_existing_jquery') == true) echo "checked"; ?>/>Yes</td>
221 - </tr>
222 - <tr valign="top">
223 - <th scope="row">Skip Deferred Execution</th>
224 - <td style="vertical-align: middle;"><input type="checkbox" name="ignore_js" value="1" <?php if($show_ignore_js == true) echo "checked"; ?>/>Yes</td>
225 - </tr>
226 - </table>
481 + if (isset($field['tooltip'])) {
482 + echo '<p class="form-description ' . ($isCheckbox ? 'form-description--checkbox' : '') . '">' . esc_html($field['tooltip']) . '</p>';
483 + }
227 484
228 - <script type="text/javascript">
229 - function selectCodeType() {
230 - var code_type = 'ASYNC';
231 - if(document.getElementById('code_type_sync').checked)
232 - code_type = 'SYNC';
485 + echo '</div>';
486 +}
233 487
234 - if(code_type == 'ASYNC') {
235 - document.getElementById('asyncOnly1').style.display = 'table-row';
236 - document.getElementById('asyncOnly2').style.display = 'table-row';
237 - document.getElementById('asyncOnly3').style.display = 'table-row';
238 - }
239 - else {
240 - document.getElementById('asyncOnly1').style.display = 'none';
241 - document.getElementById('asyncOnly2').style.display = 'none';
242 - document.getElementById('asyncOnly3').style.display = 'none';
243 - }
244 - }
245 - </script>
246 - <p class="submit"><input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" /></p>
247 - <p>Your Account ID (a number) can be found in <i>Settings</i> area (top-right) after you <a href="https://app.vwo.com">login</a> into your VWO account.</p>
248 -<?php
249 - echo '</div>';
488 +function vwo_clhf_render_styles() {
489 + ?>
490 + <style>
491 + input[type="radio"] {
492 + margin: 0 !important;
493 + }
494 + input[type=radio]:checked::before {
495 + background-color: #3858E9;
496 + }
497 + .vwo-admin-content {
498 + background: #fff;
499 + padding: 20px;
500 + border: 1px solid #ccd0d4;
501 + box-shadow: 0 1px 1px rgba(0,0,0,.04);
502 + margin-top: 20px;
503 + }
504 + .vwo-admin-content .nav-tab,
505 + .vwo-admin-content .nav-tab-active{
506 + outline:none;
507 + box-shadow: none;
508 + }
509 + .main-grid {
510 + display: flex;
511 + justify-content: space-between;
512 + }
513 + .main-grid__description {
514 + background-color: #f9f9f9;
515 + padding: 24px;
516 + border-radius: 8px;
517 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
518 + font-family: 'Segoe UI', sans-serif;
519 + height: fit-content;max-width: 650px;
520 + border: 1px solid #E0E0E0;
521 + margin: 20px;
522 + }
523 + .main-grid__description h2 {
524 + font-weight: 600;
525 + margin-bottom: 10px;
526 + margin-top: 0;
527 + font-size: 20px;
528 + color: #333;
529 + }
530 + .main-grid__description p {
531 + font-size: 14px;
532 + color: #757575;
533 + line-height: 1.6;
534 + margin-top: 21px;
535 + margin-bottom: 0px;
536 + }
537 + .main-grid__description a {
538 + color: #3858E9;
539 + }
540 + .form-container {
541 + margin-top: 24px;
542 + margin-bottom: 30px;
543 + display: flex;
544 + flex-direction: column;
545 + gap: 28px;
546 + flex: 1;
547 + }
548 + .form-label {
549 + font-size: 12px;
550 + color: #1E1E1E;
551 + display: block;
552 + margin-bottom: 10px;
553 + font-weight: 500;
554 + }
555 + .form-label--checkbox {
556 + cursor: pointer;
557 + margin-bottom: 0;
558 + }
559 + .form-radio-label {
560 + display: flex;
561 + align-items: center;
562 + gap: 10px;
563 + margin-bottom: 10px;
564 + cursor: pointer;
565 + }
566 + .form-radio-label:last-child {
567 + margin-bottom: 0;
568 + }
569 + .form-description {
570 + color: #757575;
571 + margin-top: 10px;
572 + margin-bottom: 0;
573 + font-size: 12px;
574 + }
575 + .form-description--checkbox {
576 + margin-top: 5px;
577 + margin-left: 42px;
578 + }
579 + .form-input {
580 + width: 100%;
581 + max-width: 400px;
582 + border: 1px solid #949494 !important;
583 + border-radius: 2px !important;
584 + }
585 + .checkbox-container, .radio-container {
586 + display: flex;
587 + gap: 10px;
588 + }
589 + .radio-container-wrapper {
590 + margin-bottom: 20px;
591 + }
592 + .radio-container-wrapper:last-child {
593 + margin-bottom: 0;
594 + }
595 + .radio-sublabel {
596 + font-size: 12px;
597 + color: #757575;
598 + margin-top: 5px;
599 + margin-bottom: 0;
600 + margin-left: 26px;
601 + }
602 + .checkbox-container .form-description {
603 + width: 100%;
604 + }
605 + .async-option {
606 + display: none;
607 + }
608 + .tab-pane {
609 + display: none;
610 + }
611 + .tab-pane.active {
612 + display: block;
613 + }
614 + .description {
615 + max-width: 800px;
616 + margin-bottom: 20px;
617 + }
618 +
619 + .woocommerce-row {
620 + display: grid;
621 + grid-template-columns: repeat(3, 1fr);
622 + gap: 16px;
623 + }
624 + .woocommerce-row-item {
625 + border: 1px solid rgba(0, 0, 0, 0.10);
626 + border-radius: 8px;
627 + }
628 + .woocommerce-row-item-header {
629 + display: flex;
630 + justify-content: space-between;
631 + align-items: center;
632 + gap: 5px;
633 + padding: 10px;
634 + border-bottom: 1px solid rgba(0, 0, 0, 0.10);
635 + }
636 + .woocommerce-row-item-title {
637 + margin: 0;
638 + font-size: 13px;
639 + font-weight: 500;
640 + color: #1E1E1E;
641 + }
642 + .woocommerce-row-item-description {
643 + margin: 0;
644 + font-size: 12px;
645 + color: #757575;
646 + padding: 10px;
647 + }
648 + .woocommerce-row-item-description a {
649 + color: #3858E9;
650 + }
651 + .woocommerce-main-header {
652 + margin: 30px 0;
653 + }
654 + .woocommerce-row--disabled {
655 + opacity: 0.4;
656 + cursor: not-allowed;
657 + pointer-events: none;
658 + }
659 + input[type=checkbox].vwo-checkbox{
660 + height: 0;
661 + width: 0;
662 + visibility: hidden;
663 + position: absolute;
664 + clip: rect(1px,1px,1px,1px);
665 + overflow: hidden;
666 + }
667 +
668 + label.vwo-checkbox-label {
669 + box-sizing: border-box;
670 + cursor: pointer;
671 + text-indent: -9999px;
672 + width: 32px;
673 + height: 18px;
674 + border: 1px solid #000;
675 + background: #fff;
676 + display: block;
677 + border-radius: 100px;
678 + position: relative;
679 + }
680 +
681 + label.vwo-checkbox-label:after {
682 + content: '';
683 + position: absolute;
684 + top: 50%;
685 + transform: translateY(-50%);
686 + left: 2px;
687 + width: 12px;
688 + height: 12px;
689 + background: #000;
690 + border-radius: 90px;
691 + transition: 0.3s;
692 + }
693 +
694 + input.vwo-checkbox:checked + label.vwo-checkbox-label {
695 + background: #3858E9;
696 + border-color: #3858E9;
697 + }
698 +
699 + input.vwo-checkbox:checked + label.vwo-checkbox-label:after {
700 + left: calc(100% - 2px);
701 + transform: translateX(-100%) translateY(-50%);
702 + background-color: #fff;
703 + }
704 +
705 + </style>
706 + <?php
250 707 }
251 708
252 -function vwo_clhf_warn_nosettings(){
253 - if (!is_admin())
709 +function vwo_clhf_render_scripts() {
710 + ?>
711 + <script>
712 + jQuery(document).ready(function($) {
713 + function toggleAsyncOptions() {
714 + var isAsync = $('input[name="code_type"]:checked').val() === 'ASYNC';
715 + $('.async-option').toggle(isAsync);
716 + }
717 + function toggleWooCommerceOptions() {
718 + var isWooCommerce = $('input[name="enable_woocommerce_event_tracking"]:checked');
719 +
720 + if(isWooCommerce.length > 0) {
721 + $('.woocommerce-row').removeClass('woocommerce-row--disabled');
722 + $('.vwo_server_side_tracking').removeClass('woocommerce-row--disabled');
723 +
724 + } else {
725 + $('.woocommerce-row').addClass('woocommerce-row--disabled');
726 + $('.vwo_server_side_tracking').addClass('woocommerce-row--disabled');
727 + }
728 + }
729 +
730 + $('input[name="enable_woocommerce_event_tracking"]').change(toggleWooCommerceOptions);
731 + $("label[for='enable_woocommerce_event_tracking']").click(toggleWooCommerceOptions);
732 + toggleWooCommerceOptions(); // Run on page load
733 +
734 + $('input[name="code_type"]').change(toggleAsyncOptions);
735 + toggleAsyncOptions(); // Run on page load
736 +
737 + // Handle tab switching
738 + $('.nav-tab-wrapper .nav-tab').on('click', function(e) {
739 + e.preventDefault();
740 + var targetTab = $(this).attr('href');
741 +
742 + // Update active tab
743 + $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active');
744 + $(this).addClass('nav-tab-active');
745 +
746 + // Show target tab content
747 + $('.tab-pane').removeClass('active').hide();
748 + $(targetTab).addClass('active').show();
749 + });
750 +
751 + // Ensure the first tab is visible on page load
752 + $('#tab-general').show();
753 + });
754 + </script>
755 + <?php
756 +}
757 +
758 +function vwo_clhf_enqueue_admin_scripts($hook) {
759 + if ('settings_page_clhf_vwo_options' !== $hook) {
254 760 return;
761 + }
762 + wp_enqueue_style('wp-admin');
763 +}
764 +add_action('admin_enqueue_scripts', 'vwo_clhf_enqueue_admin_scripts');
255 765
256 - $clhf_option = get_option("vwo_id");
257 - if (!$clhf_option || $clhf_option < 1){
258 - echo "<div id='vwo-warning' class='updated fade'><p><strong>VWO is almost ready.</strong> You must <a href=\"options-general.php?page=clhf_vwo_options\">enter your Account ID</a> for it to work.</p></div>";
259 - }
766 +/**
767 + * Displays a warning message if VWO settings are not configured.
768 + * This function checks if the user is an admin and if the VWO ID option is set. If the user is not an admin or
769 + * the VWO ID option is not set, it displays a warning message.
770 + *
771 + * @throws Exception Description of exception.
772 + * @return void
773 + */
774 +function vwo_clhf_warn_nosettings() {
775 + if ( ! is_admin() ) {
776 + return;
777 + }
778 +
779 + $clhf_option = get_option( 'vwo_id' );
780 + if ( ! $clhf_option || $clhf_option < 1 ) {
781 + echo "<div id='vwo-warning' class='updated fade'><p><strong>VWO is almost ready.</strong> You must <a href=\"options-general.php?page=clhf_vwo_options\">enter your Account ID</a> for it to work.</p></div>";
782 + }
260 783 }
261 784
262 785
263 -add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'vwo_clhf_add_plugin_page_settings_link');
786 +add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'vwo_clhf_add_plugin_page_settings_link' );
787 +
264 788 /**
265 789 * Function to add Settings Links on Plugin page
266 - * @param array $links
267 - * @return string
790 + *
791 + * @param array $links Array of links.
792 + * @return array
268 793 */
269 794 function vwo_clhf_add_plugin_page_settings_link( $links ) {
270 795 $links[] = '<a href="' .
271 796 admin_url( 'options-general.php?page=clhf_vwo_options' ) .
272 - '">' . __('Settings') . '</a>';
797 + '">' . __( 'Settings' ) . '</a>';
273 798 return $links;
274 799 }
275 800
276 -function disable_vwo_in_divi_builder(){
277 - if (has_action('wp_head', 'vwo_clhf_headercode') && function_exists('et_core_is_fb_enabled') && et_core_is_fb_enabled()){
278 - remove_action('wp_head', 'vwo_clhf_headercode', 1);
801 +/**
802 + * Disables VWO in Divi Builder.
803 + *
804 + * @throws Exception Description of exception.
805 + * @return void
806 + */
807 +function disable_vwo_in_divi_builder() {
808 + if ( has_action( 'wp_head', 'vwo_clhf_headercode' ) && function_exists( 'et_core_is_fb_enabled' ) && et_core_is_fb_enabled() ) {
809 + remove_action( 'wp_head', 'vwo_clhf_headercode', 1 );
279 810 }
280 - return;
281 811 }
282 812
283 -add_action('wp_head', 'disable_vwo_in_divi_builder', 0);
813 +add_action( 'wp_head', 'disable_vwo_in_divi_builder', 0 );
814 +
815 +// Add this new function to validate settings
816 +function vwo_clhf_validate_settings() {
817 + $has_errors = false;
818 +
819 + // Validate VWO Account ID
820 + $vwo_id = get_option('vwo_id');
821 + if (empty($vwo_id) || !is_numeric($vwo_id)) {
822 + add_settings_error('vwo_clhf_options', 'vwo_id', 'Please enter a valid VWO Account ID.', 'error');
823 + $has_errors = true;
824 + }
825 +
826 + // Add more validation for other fields as needed
827 +
828 + return $has_errors;
829 +}
830 +
831 +// Add this new function to sanitize and validate settings
832 +function vwo_clhf_sanitize_settings($input) {
833 + // Sanitize and validate VWO Account ID
834 + $vwo_id = sanitize_text_field($input);
835 + if (empty($vwo_id) || !is_numeric($vwo_id)) {
836 + add_settings_error('vwo_clhf_options', 'vwo_id', 'Please enter a valid VWO Account ID.', 'error');
837 + }
838 +
839 + // Add more sanitization and validation for other fields as needed
840 + // Check if vwo_id is changed
841 + $current_vwo_id = get_option('vwo_id');
842 + if ($current_vwo_id !== $vwo_id) {
843 + update_option('vwo_coll_url','');
844 + }
845 + return $vwo_id;
846 +}
847 +
848 +function enqueue_jquery_script() {
849 + wp_enqueue_script('jquery');
850 +}
851 +add_action('wp_enqueue_scripts', 'enqueue_jquery_script');
852 +
853 +if (file_exists(plugin_dir_path(__FILE__) . 'woocommerce-events.php')) {
854 + include_once plugin_dir_path(__FILE__) . 'woocommerce-events.php';
855 +}
856 +
284 857
285 858 ?>