PluginProbe
Visual Website Optimizer / 4.14
Visual Website Optimizer v4.14
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
visual-web-optimizer / visual-website-optimizer.php

visual-website-optimizer.php in Visual Website Optimizer 4.14, at visual-website-optimizer.php

969 lines 47.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 *
4 * Plugin Name: VWO (Wingify)
5 * Plugin URI: https://vwo.com/
6 * Description: VWO (Wingify) 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</a> for more details.
7 * Author: VWO
8 * Version: 4.14
9 * visual-website-optimizer.php
10 * Author URI: https://vwo.com/
11 *
12 * @package VWO
13 * @author VWO
14 * @version 4.14
15 **/
16
17 /**
18 * Generate Common Code
19 *
20 * @param integer $vwo_clicks integer. Defaults to 10.
21 */
22 function get_vwo_clhf_script_common_code( $vwo_clicks = 10 ) {
23 ob_start();
24 // @codingStandardsIgnoreStart
25 ?>
26 <!-- Start VWO Common Smartcode -->
27 <script <?php echo vwo_clhf_ignore_js_attr(); ?> type='text/javascript'>
28 var _vwo_clicks = <?php echo esc_html( $vwo_clicks ); ?>;
29 </script>
30 <!-- End VWO Common Smartcode -->
31 <?php
32 // @codingStandardsIgnoreEnd
33 $script_code = ob_get_clean();
34 return $script_code;
35 }
36
37 /**
38 * Get ignore js field setting
39 *
40 * @return bool boolean
41 */
42 function get_vwo_clhf_ignore_js() {
43 $ignore_js = get_option( 'ignore_js' );
44 $ignore_js = ( '1' === $ignore_js ) ? true : false;
45 return $ignore_js;
46 }
47
48 /**
49 * Get ignore js script attribute value
50 *
51 * @return string Returns script attribute value
52 */
53 function vwo_clhf_ignore_js_attr() {
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" nowprocket';
58 }
59 // Always exclude VWO scripts from Jetpack Boost deferral
60 if ( ! empty( $js_attr ) ) {
61 $js_attr .= ' data-jetpack-boost="ignore"';
62 } else {
63 $js_attr = 'data-jetpack-boost="ignore"';
64 }
65 return $js_attr;
66 }
67
68 /**
69 * Generate Synchronous Code
70 *
71 * @param int $vwo_id integer. Defaults to 0.
72 * @return string string for sync script.
73 */
74 function get_vwo_clhf_script_sync_code( $vwo_id = 0 ) {
75 ob_start();
76 // @codingStandardsIgnoreStart
77 ?>
78 <?php if ( vwo_clhf_is_wingify_account() ) : ?>
79 <!-- Start Wingify SmartCode -->
80 <script src="https://edge.wingify.net/lib/<?php echo esc_html( $vwo_id ); ?>.js" referrerpolicy="no-referrer-when-downgrade" <?php echo vwo_clhf_ignore_js_attr(); ?>></script>
81 <!-- End Wingify SmartCode -->
82 <?php else : ?>
83 <!-- Start VWO Smartcode -->
84 <script referrerPolicy="no-referrer-when-downgrade" <?php echo vwo_clhf_ignore_js_attr(); ?> src="https://dev.visualwebsiteoptimizer.com/lib/<?php echo esc_html( $vwo_id ); ?>.js"></script>
85 <!-- End VWO Smartcode -->
86 <?php endif; ?>
87 <?php
88 // @codingStandardsIgnoreEnd
89 $sync_script = ob_get_clean();
90 return $sync_script;
91 }
92
93 /**
94 * Generate Asynchronous Code
95 *
96 * @param int $vwo_id integer.
97 * @param int $settings_tolerance integer.
98 * @param int $library_tolerance integer.
99 * @param bool $use_existing_jquery boolean.
100 * @return string String for async script.
101 */
102 function get_vwo_clhf_script_async_code( $vwo_id, $settings_tolerance, $library_tolerance, $use_existing_jquery ) {
103 ob_start();
104 // @codingStandardsIgnoreStart
105 ?>
106 <?php if ( vwo_clhf_is_wingify_account() ) : ?>
107 <!-- Start Wingify Async SmartCode -->
108 <link rel="preconnect" href="https://edge.wingify.net"/>
109 <script type='text/javascript' id="wingifyCode" <?php echo vwo_clhf_ignore_js_attr(); ?>>
110 window._wingify_code ||
111 (function () {
112 var w=window,
113 d=document;
114 var account_id=<?php echo esc_html( $vwo_id ); ?>,
115 version=2.2,
116 settings_tolerance=<?php echo esc_html( $settings_tolerance ); ?>,
117 hide_element='body',
118 hide_element_style = 'opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important';
119 /* DO NOT EDIT BELOW THIS LINE */
120 var f=0, v;
121 if(f=!1,v=d.currentScript,cc={},-1<d.URL.indexOf('__wingify_disable__')||w._wingify_code)return;try{var e=JSON.parse(localStorage.getItem('_wingify_'+account_id+'_config'));cc=e&&'object'==typeof e?e:{}}catch(e){}function r(t){try{return decodeURIComponent(t)}catch(e){return t}}var s=function(){var e={combination:[],combinationChoose:[],split:[],exclude:[],uuid:null,consent:null,optOut:null},t=d.cookie||'';if(!t)return e;for(var n,i,o=/(?:^|;\s*)(?:(_vis_opt_exp_(\d+)_combi=([^;]*))|(_vis_opt_exp_(\d+)_combi_choose=([^;]*))|(_vis_opt_exp_(\d+)_split=([^:;]*))|(_vis_opt_exp_(\d+)_exclude=[^;]*)|(_vis_opt_out=([^;]*))|(_wingify_global_opt_out=[^;]*)|(_wingify_uuid=([^;]*))|(_wingify_consent=([^;]*)))/g;null!==(n=o.exec(t));)try{n[1]?e.combination.push({id:n[2],value:r(n[3])}):n[4]?e.combinationChoose.push({id:n[5],value:r(n[6])}):n[7]?e.split.push({id:n[8],value:r(n[9])}):n[10]?e.exclude.push({id:n[11]}):n[12]?e.optOut=r(n[13]):n[14]?e.optOut=!0:n[15]?e.uuid=r(n[16]):n[17]&&(i=r(n[18]),e.consent=i&&3<=i.length?i.substring(0,3):null)}catch(e){}return e}();function i(){var e=function(){if(w.Wingify&&Array.isArray(w.Wingify))for(var e=0;e<w.Wingify.length;e++){var t=w.Wingify[e];if(Array.isArray(t)&&('setVisitorId'===t[0]||'setSessionId'===t[0]))return!0}return!1}(),t='a='+account_id+'&u='+encodeURIComponent(w._vis_opt_url||d.URL)+'&vn='+version+'&ph=1'+('undefined'!=typeof platform?'&p='+platform:'')+'&st='+w.performance.now();e||((n=function(){var e,t=[],n={},i=w.Wingify&&w.Wingify.appliedCampaigns||{};for(e in i){var o=i[e]&&i[e].v;o&&(t.push(e+'-'+o+'-1'),n[e]=!0)}if(s&&s.combination)for(var r=0;r<s.combination.length;r++){var a=s.combination[r];n[a.id]||t.push(a.id+'-'+a.value)}return t.join('|')}())&&(t+='&c='+n),(n=function(){var e=[],t={};if(s&&s.combinationChoose)for(var n=0;n<s.combinationChoose.length;n++){var i=s.combinationChoose[n];e.push(i.id+'-'+i.value),t[i.id]=!0}if(s&&s.split)for(var o=0;o<s.split.length;o++)t[(i=s.split[o]).id]||e.push(i.id+'-'+i.value);return e.join('|')}())&&(t+='&cc='+n),(n=function(){var e={},t=[];if(w.Wingify&&Array.isArray(w.Wingify))for(var n=0;n<w.Wingify.length;n++){var i=w.Wingify[n];if(Array.isArray(i)&&'setVariation'===i[0]&&i[1]&&Array.isArray(i[1]))for(var o=0;o<i[1].length;o++){var r,a=i[1][o];a&&'object'==typeof a&&(r=a.e,a=a.v,r&&a&&(e[r]=a))}}for(r in e)t.push(r+'-'+e[r]);return t.join('|')}())&&(t+='&sv='+n)),s&&s.optOut&&(t+='&o='+s.optOut);var n=function(){var e=[],t={};if(s&&s.exclude)for(var n=0;n<s.exclude.length;n++){var i=s.exclude[n];t[i.id]||(e.push(i.id),t[i.id]=!0)}return e.join('|')}();return n&&(t+='&e='+n),s&&s.uuid&&(t+='&id='+s.uuid),s&&s.consent&&(t+='&consent='+s.consent),w.name&&-1<w.name.indexOf('_vis_preview')&&(t+='&pM=true'),w.Wingify&&w.Wingify.ed&&(t+='&ed='+w.Wingify.ed),t}code={script:v,nonce:v&&v.nonce,library_tolerance:function(){return'undefined'!=typeof library_tolerance?library_tolerance:void 0},settings_tolerance:function(){return cc.sT||settings_tolerance},hide_element_style:function(){return'{'+(cc.hES||hide_element_style)+'}'},hide_element:function(){return performance.getEntriesByName('first-contentful-paint')[0]?'':'string'==typeof cc.hE?cc.hE:hide_element},getVersion:function(){return version},finish:function(e){var t;f||(f=!0,(t=d.getElementById('_vis_opt_path_hides'))&&t.parentNode.removeChild(t),e&&((new Image).src='https://edge.wingify.net/ee.gif?a='+account_id+e))},finished:function(){return f},addScript:function(e){var t=d.createElement('script');t.type='text/javascript',e.src?t.src=e.src:t.text=e.text,v&&t.setAttribute('nonce',v.nonce),d.getElementsByTagName('head')[0].appendChild(t)},load:function(e,t){t=t||{};var n=new XMLHttpRequest;n.open('GET',e,!0),n.withCredentials=!t.dSC,n.responseType=t.responseType||'text',n.onload=function(){if(t.onloadCb)return t.onloadCb(n,e);200===n.status?_wingify_code.addScript({text:n.responseText}):_wingify_code.finish('&e=loading_failure:'+e)},n.onerror=function(){if(t.onerrorCb)return t.onerrorCb(e);_wingify_code.finish('&e=loading_failure:'+e)},n.send()},init:function(){var e,t=this.settings_tolerance();w._settings_timer=setTimeout(function(){_wingify_code.finish()},t),'body'!==this.hide_element()?(n=d.createElement('style'),e=(t=this.hide_element())?t+this.hide_element_style():'',t=d.getElementsByTagName('head')[0],n.setAttribute('id','_vis_opt_path_hides'),v&&n.setAttribute('nonce',v.nonce),n.setAttribute('type','text/css'),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(d.createTextNode(e)),t.appendChild(n)):(n=d.getElementsByTagName('head')[0],(e=d.createElement('div')).style.cssText='z-index: 2147483647 !important;position: fixed !important;left: 0 !important;top: 0 !important;width: 100% !important;height: 100% !important;background: white !important;',e.setAttribute('id','_vis_opt_path_hides'),e.classList.add('_vis_hide_layer'),n.parentNode.insertBefore(e,n.nextSibling));var n='https://edge.wingify.net/j.php?'+i();-1!==w.location.search.indexOf('_wingify_xhr')?this.addScript({src:n}):this.load(n+'&x=true',{l:1})}};w._wingify_code=code;code.init();})();
122 </script>
123 <!-- End Wingify Async SmartCode -->
124 <?php endif; ?>
125 <?php if ( ! vwo_clhf_is_wingify_account() ) : ?>
126 <!-- Start VWO Async SmartCode -->
127 <link rel="preconnect" href="https://dev.visualwebsiteoptimizer.com"/>
128 <script type='text/javascript' id="vwoCode" <?php echo vwo_clhf_ignore_js_attr(); ?>>
129 window._vwo_code ||
130 (function () {
131 var w=window,
132 d=document;
133 var account_id=<?php echo esc_html( $vwo_id ); ?>,
134 version=2.2,
135 settings_tolerance=<?php echo esc_html( $settings_tolerance ); ?>,
136 hide_element='body',
137 hide_element_style = 'opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important';
138 /* DO NOT EDIT BELOW THIS LINE */
139 var f=0, v;
140 if(f=!1,v=d.querySelector('#vwoCode'),cc={},-1<d.URL.indexOf('__vwo_disable__')||w._vwo_code)return;try{var e=JSON.parse(localStorage.getItem('_vwo_'+account_id+'_config'));cc=e&&'object'==typeof e?e:{}}catch(e){}function r(t){try{return decodeURIComponent(t)}catch(e){return t}}var s=function(){var e={combination:[],combinationChoose:[],split:[],exclude:[],uuid:null,consent:null,optOut:null},t=d.cookie||'';if(!t)return e;for(var n,i,o=/(?:^|;\s*)(?:(_vis_opt_exp_(\d+)_combi=([^;]*))|(_vis_opt_exp_(\d+)_combi_choose=([^;]*))|(_vis_opt_exp_(\d+)_split=([^:;]*))|(_vis_opt_exp_(\d+)_exclude=[^;]*)|(_vis_opt_out=([^;]*))|(_vwo_global_opt_out=[^;]*)|(_vwo_uuid=([^;]*))|(_vwo_consent=([^;]*)))/g;null!==(n=o.exec(t));)try{n[1]?e.combination.push({id:n[2],value:r(n[3])}):n[4]?e.combinationChoose.push({id:n[5],value:r(n[6])}):n[7]?e.split.push({id:n[8],value:r(n[9])}):n[10]?e.exclude.push({id:n[11]}):n[12]?e.optOut=r(n[13]):n[14]?e.optOut=!0:n[15]?e.uuid=r(n[16]):n[17]&&(i=r(n[18]),e.consent=i&&3<=i.length?i.substring(0,3):null)}catch(e){}return e}();function i(){var e=function(){if(w.VWO&&Array.isArray(w.VWO))for(var e=0;e<w.VWO.length;e++){var t=w.VWO[e];if(Array.isArray(t)&&('setVisitorId'===t[0]||'setSessionId'===t[0]))return!0}return!1}(),t='a='+account_id+'&u='+encodeURIComponent(w._vis_opt_url||d.URL)+'&vn='+version+'&ph=1'+('undefined'!=typeof platform?'&p='+platform:'')+'&st='+w.performance.now();e||((n=function(){var e,t=[],n={},i=w.VWO&&w.VWO.appliedCampaigns||{};for(e in i){var o=i[e]&&i[e].v;o&&(t.push(e+'-'+o+'-1'),n[e]=!0)}if(s&&s.combination)for(var r=0;r<s.combination.length;r++){var a=s.combination[r];n[a.id]||t.push(a.id+'-'+a.value)}return t.join('|')}())&&(t+='&c='+n),(n=function(){var e=[],t={};if(s&&s.combinationChoose)for(var n=0;n<s.combinationChoose.length;n++){var i=s.combinationChoose[n];e.push(i.id+'-'+i.value),t[i.id]=!0}if(s&&s.split)for(var o=0;o<s.split.length;o++)t[(i=s.split[o]).id]||e.push(i.id+'-'+i.value);return e.join('|')}())&&(t+='&cc='+n),(n=function(){var e={},t=[];if(w.VWO&&Array.isArray(w.VWO))for(var n=0;n<w.VWO.length;n++){var i=w.VWO[n];if(Array.isArray(i)&&'setVariation'===i[0]&&i[1]&&Array.isArray(i[1]))for(var o=0;o<i[1].length;o++){var r,a=i[1][o];a&&'object'==typeof a&&(r=a.e,a=a.v,r&&a&&(e[r]=a))}}for(r in e)t.push(r+'-'+e[r]);return t.join('|')}())&&(t+='&sv='+n)),s&&s.optOut&&(t+='&o='+s.optOut);var n=function(){var e=[],t={};if(s&&s.exclude)for(var n=0;n<s.exclude.length;n++){var i=s.exclude[n];t[i.id]||(e.push(i.id),t[i.id]=!0)}return e.join('|')}();return n&&(t+='&e='+n),s&&s.uuid&&(t+='&id='+s.uuid),s&&s.consent&&(t+='&consent='+s.consent),w.name&&-1<w.name.indexOf('_vis_preview')&&(t+='&pM=true'),w.VWO&&w.VWO.ed&&(t+='&ed='+w.VWO.ed),t}code={script:v,nonce:v&&v.nonce,library_tolerance:function(){return'undefined'!=typeof library_tolerance?library_tolerance:void 0},settings_tolerance:function(){return cc.sT||settings_tolerance},hide_element_style:function(){return'{'+(cc.hES||hide_element_style)+'}'},hide_element:function(){return performance.getEntriesByName('first-contentful-paint')[0]?'':'string'==typeof cc.hE?cc.hE:hide_element},getVersion:function(){return version},finish:function(e){var t;f||(f=!0,(t=d.getElementById('_vis_opt_path_hides'))&&t.parentNode.removeChild(t),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',e.src?t.src=e.src:t.text=e.text,v&&t.setAttribute('nonce',v.nonce),d.getElementsByTagName('head')[0].appendChild(t)},load:function(e,t){t=t||{};var n=new XMLHttpRequest;n.open('GET',e,!0),n.withCredentials=!t.dSC,n.responseType=t.responseType||'text',n.onload=function(){if(t.onloadCb)return t.onloadCb(n,e);200===n.status?_vwo_code.addScript({text:n.responseText}):_vwo_code.finish('&e=loading_failure:'+e)},n.onerror=function(){if(t.onerrorCb)return t.onerrorCb(e);_vwo_code.finish('&e=loading_failure:'+e)},n.send()},init:function(){var e,t=this.settings_tolerance();w._vwo_settings_timer=setTimeout(function(){_vwo_code.finish()},t),'body'!==this.hide_element()?(n=d.createElement('style'),e=(t=this.hide_element())?t+this.hide_element_style():'',t=d.getElementsByTagName('head')[0],n.setAttribute('id','_vis_opt_path_hides'),v&&n.setAttribute('nonce',v.nonce),n.setAttribute('type','text/css'),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(d.createTextNode(e)),t.appendChild(n)):(n=d.getElementsByTagName('head')[0],(e=d.createElement('div')).style.cssText='z-index: 2147483647 !important;position: fixed !important;left: 0 !important;top: 0 !important;width: 100% !important;height: 100% !important;background: white !important;',e.setAttribute('id','_vis_opt_path_hides'),e.classList.add('_vis_hide_layer'),n.parentNode.insertBefore(e,n.nextSibling));var n='https://dev.visualwebsiteoptimizer.com/j.php?'+i();-1!==w.location.search.indexOf('_vwo_xhr')?this.addScript({src:n}):this.load(n+'&x=true',{l:1})}};w._vwo_code=code;code.init();})();
141 </script>
142 <!-- End VWO Async SmartCode -->
143
144 <?php endif; ?>
145 <?php
146 // @codingStandardsIgnoreEnd
147 $async_script = ob_get_clean();
148 return $async_script;
149 }
150
151 // ------------------------------------------------------------------------//
152 // ---Hook-----------------------------------------------------------------//
153 // ------------------------------------------------------------------------//
154 add_action( 'wp_head', 'vwo_clhf_headercode', 1 );
155 add_action( 'admin_menu', 'vwo_clhf_plugin_menu' );
156 add_action( 'admin_init', 'vwo_clhf_register_mysettings' );
157 add_action( 'admin_notices', 'vwo_clhf_warn_nosettings' );
158
159
160 // ------------------------------------------------------------------------//
161 // ---Functions------------------------------------------------------------//
162 // ------------------------------------------------------------------------//
163 // options page link
164
165 /**
166 * Generate a function comment for the given function body.
167 *
168 * @throws Exception Description of exception.
169 * @return void
170 */
171 function vwo_clhf_plugin_menu() {
172 add_options_page( 'Visual Website Optimizer', 'VWO', 'create_users', 'clhf_vwo_options', 'vwo_clhf_plugin_options' );
173 }
174
175 /**
176 * Register the settings for the VWO options.
177 *
178 * @return void
179 */
180 function vwo_clhf_register_mysettings() {
181 register_setting('clhf_vwo_options', 'vwo_id', array(
182 'sanitize_callback' => 'vwo_clhf_sanitize_settings',
183 ));
184 register_setting( 'clhf_vwo_options', 'code_type' );
185 register_setting( 'clhf_vwo_options', 'vwo_clicks' );
186 register_setting( 'clhf_vwo_options', 'ignore_js', 'boolval' );
187 register_setting( 'clhf_vwo_options', 'settings_tolerance', 'intval' );
188 register_setting( 'clhf_vwo_options', 'library_tolerance', 'intval' );
189 register_setting( 'clhf_vwo_options', 'use_existing_jquery', 'boolval' );
190 register_setting( 'clhf_vwo_options', 'enable_woocommerce_event_tracking', 'boolval');
191 register_setting( 'clhf_vwo_options', 'track_product_view', 'boolval' );
192 register_setting( 'clhf_vwo_options', 'track_add_to_cart', 'boolval' );
193 register_setting( 'clhf_vwo_options', 'track_remove_from_cart', 'boolval' );
194 register_setting( 'clhf_vwo_options', 'track_checkout', 'boolval' );
195 register_setting( 'clhf_vwo_options', 'track_purchase', 'boolval' );
196 register_setting( 'clhf_vwo_options', 'vwo_server_side_tracking', 'boolval' );
197 }
198
199 // ------------------------------------------------------------------------//
200 // ---Output Functions-----------------------------------------------------//
201 // ------------------------------------------------------------------------//
202
203
204 /**
205 * Generates the action vwo_clhf_headercode function.
206 *
207 * @throws Exception Description of exception.
208 * @return void
209 */
210 function vwo_clhf_headercode() {
211 // Runs in the header.
212 $vwo_id = get_option( 'vwo_id' );
213 $code_type = get_option( 'code_type' );
214
215 if ( $vwo_id ) {
216 if ( null === get_option( 'is_wingify_account', null ) ) {
217 vwo_clhf_fetch_and_save_account_info( $vwo_id );
218 }
219
220 if ( empty( get_option( 'vwo_clicks' ) ) ) {
221 update_option( 'vwo_clicks', '10' );
222 }
223 $vwo_clicks = get_option( 'vwo_clicks' );
224
225 // Common script code.
226 // @codingStandardsIgnoreLine
227 echo get_vwo_clhf_script_common_code( $vwo_clicks );
228
229 if ( 'SYNC' === $code_type ) {
230 // Sync script code.
231 // @codingStandardsIgnoreLine
232 echo get_vwo_clhf_script_sync_code( $vwo_id );
233 } else {
234
235 $settings_tolerance = get_option( 'settings_tolerance' );
236 if ( ! is_numeric( $settings_tolerance ) ) {
237 $settings_tolerance = 2000;
238 }
239
240 $library_tolerance = get_option( 'library_tolerance' );
241 if ( ! is_numeric( $library_tolerance ) ) {
242 $library_tolerance = 2500;
243 }
244
245 $use_existing_jquery = get_option( 'use_existing_jquery' );
246 $use_existing_jquery = ( '1' === $use_existing_jquery ) ? true : false;
247
248 // Async script code.
249 // @codingStandardsIgnoreLine
250 echo get_vwo_clhf_script_async_code( $vwo_id, $settings_tolerance, $library_tolerance, $use_existing_jquery );
251 }
252 }
253 }
254
255 // ------------------------------------------------------------------------//
256 // ---Page Output Functions------------------------------------------------//
257 // ------------------------------------------------------------------------//
258 // options page
259
260
261 /**
262 * Generates the options page for the VWO plugin.
263 *
264 * @throws Exception Description of exception.
265 * @return void
266 */
267 function vwo_clhf_plugin_options() {
268
269 ?>
270 <div class="wrap">
271 <h1 style="margin-bottom: 15px;display: flex; align-items: center; gap:6px;">
272 <svg xmlns="http://www.w3.org/2000/svg" width="200" height="46.212" fill="none" viewBox="0 0 300 46.212"><path fill="#3100BE" d="M232.627 30.085c0 -1.501 0.889 -2.389 2.758 -2.665l4.32 -0.613v1.164c0 2.604 -1.869 4.442 -4.442 4.442 -1.746 0 -2.635 -0.827 -2.635 -2.329M190.961 19.455v-5.667h8.089c2.114 0 2.972 0.827 2.972 2.818 0 1.961 -0.889 2.88 -2.972 2.88zm0 11.274v-6.25h7.936c2.604 0 3.89 0.981 3.89 2.972 0 2.114 -1.348 3.248 -3.89 3.248zm-24.723 -6.739 3.523 -9.742h0.245l3.492 9.742zm107.748 11.764h4.504V31.28h-2.696c-1.103 0 -1.501 -0.398 -1.501 -1.501v-8.273h6.617l5.82 14.645c0.552 1.379 -0.092 2.267 -1.623 2.267h-3.798v4.473h3.92c3.646 0 5.331 -1.133 6.464 -4.32l7.69 -21.507v-0.092h-5.576l-4.074 13.112h-0.245l-4.504 -13.112h-10.722V11.061h-5.27v5.913h-3.095v4.504h3.125v9.25c0 3.677 1.348 5.025 4.963 5.025m-40.317 0.795c2.604 0 4.748 -1.071 6.036 -2.971h0.245c0.552 1.532 2.267 2.605 4.442 2.605 1.838 0 3.217 -0.797 4.075 -2.359 1.93 1.532 4.657 2.389 7.843 2.389 5.698 0 9.344 -2.758 9.344 -7.015 0 -3.248 -2.145 -4.933 -7.292 -5.545l-2.42 -0.276c-1.839 -0.184 -2.39 -0.521 -2.39 -1.287 0 -1.072 1.011 -1.715 2.665 -1.715 1.777 0 3.37 0.827 4.197 2.205l4.718 -2.053c-1.501 -2.604 -4.902 -4.288 -8.945 -4.288 -4.841 0 -7.936 2.389 -7.936 6.127 0 3.217 2.329 5.117 6.955 5.73l2.543 0.367c1.808 0.245 2.604 0.705 2.604 1.623 0 1.133 -1.256 1.992 -3.585 1.992 -2.603 0 -4.503 -1.073 -5.269 -2.972l-2.358 1.502c-0.889 0.582 -1.624 0.827 -2.421 0.858 -1.286 -0.092 -1.777 -0.552 -1.777 -1.685V23.038c0 -4.657 -2.543 -6.74 -8.241 -6.74 -5.178 0 -7.996 1.808 -8.793 5.576l5.361 0.95c0.307 -1.439 1.502 -2.236 3.37 -2.236 2.052 0 3.033 0.858 3.033 2.696v0.183l-6.005 0.889c-3.952 0.582 -6.311 2.911 -6.311 6.372 0 3.492 2.481 5.821 6.311 5.821m-16.513 -0.795h5.821V13.786h9.068v-5.024h-23.161v5.024h8.272zm-31.985 0h15.196c5.3 0 8.394 -2.758 8.394 -7.414 0 -3.523 -1.808 -5.729 -5.208 -6.464v-0.245c2.971 -1.011 4.442 -3.033 4.442 -6.158 0 -4.381 -2.789 -6.709 -8.058 -6.709h-14.767zm-29.043 0h5.882l2.421 -6.74h10.876l2.42 6.74h6.158v-0.092l-10.386 -26.93h-7.015l-10.355 26.93zM155.76 0l-8.272 35.753h-33.516l7.965 3.4 -0.613 2.666h-18.045l4.473 2.053 -0.459 2.083h-9.099l3.339 -14.492h5.3l3.615 -15.409h10.048L124.173 0z"/><path fill="#BF3078" d="M76.678 8.619c-0.564 0 -1.24 0 -1.804 0.111l-3.27 5.695c1.466 -0.893 3.27 -1.339 5.074 -1.339 5.864 0 10.713 4.801 10.713 10.608 0 5.806 -4.849 10.608 -10.713 10.608s-10.599 -4.689 -10.712 -10.496l-3.383 5.695c2.255 5.471 7.78 9.267 13.983 9.267 8.344 0 15.223 -6.811 15.223 -15.073 0.112 -8.263 -6.766 -15.074 -15.111 -15.074"/><path fill="#802050" d="m30.671 24.363 2.593 -4.467 5.864 9.938 6.765 -11.501 6.766 11.5 11.615 -19.54c0.564 -1.005 1.691 -1.675 2.932 -1.675h3.27L52.659 38.767l-6.765 -11.5 -6.766 11.5z"/><path fill="#26134D" d="M35.52 8.619 17.705 38.767 -0.001 8.619h3.27c1.241 0 2.368 0.67 2.932 1.674L17.705 29.946l11.614 -19.652c0.564 -1.005 1.692 -1.675 2.932 -1.675z"/></svg><span>Configuration</span>
273 </h1>
274
275 <form method="post" action="options.php" novalidate>
276 <?php
277 settings_fields('clhf_vwo_options');
278 ?>
279 <div class="vwo-admin-content">
280 <?php vwo_clhf_render_tabs(); ?>
281 <div class="tab-content">
282 <div id="tab-general" class="tab-pane active">
283 <?php vwo_clhf_render_general_settings(); ?>
284 </div>
285 <div id="tab-advanced" class="tab-pane">
286 <?php vwo_clhf_render_advanced_settings(); ?>
287 </div>
288 <div id="tab-woocommerce" class="tab-pane">
289 <?php vwo_clhf_render_woocommerce_settings(); ?>
290 </div>
291 </div>
292 </div>
293 <?php submit_button(); ?>
294 </form>
295 </div>
296 <?php
297 vwo_clhf_render_styles();
298 vwo_clhf_render_scripts();
299 }
300
301 function vwo_clhf_render_tabs() {
302 ?>
303 <h2 class="nav-tab-wrapper">
304 <a href="#tab-general" class="nav-tab nav-tab-active">General Settings</a>
305 <a href="#tab-advanced" class="nav-tab">Advanced Settings</a>
306 <a href="#tab-woocommerce" class="nav-tab">WooCommerce</a>
307 </h2>
308 <?php
309 }
310
311 function vwo_clhf_render_general_settings() {
312 ?>
313 <main class="main-grid">
314 <div class="form-container">
315 <?php
316 vwo_clhf_render_field([
317 'id' => 'vwo_id',
318 'label' => 'Your VWO Account ID',
319 'type' => 'text',
320 'tooltip' => 'Enter your VWO Account ID here',
321 ]);
322 vwo_clhf_render_field([
323 'id' => 'code_type',
324 'label' => 'Code Type',
325 'type' => 'radio',
326 'options' => [
327 [
328 'label' => 'Asynchronous',
329 'value' => 'ASYNC',
330 'sublabel' => 'Loads faster without blocking other elements',
331 ],
332 [
333 'label' => 'Synchronous',
334 'value' => 'SYNC',
335 'sublabel' => 'Executes immediately but may slow down page load',
336 ],
337 ],
338 ]);
339 ?>
340 </div>
341 <div class="main-grid__description" style="width:350px;">
342 <div style="font-size: 18px; font-weight: 700; color: #000000; margin-bottom: 8px;">New to VWO (Wingify)?</div>
343 <div style="font-size: 14px; color: #757575; font-weight: 400; line-height: 20px; margin-bottom: 20px;">Create a free account to start optimising your website, no credit card required.</div>
344 <div>
345 <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" style="text-decoration: none; display: block; width: 162px; background: #fff; color: #2271B1; border: 1px solid #2271B1; padding: 10px 12px; font-size: 14px; font-weight: 600; cursor: pointer; text-align: center; border-radius: 8px;">
346 Get Started for Free</a>
347 <div>
348 <div style="margin-bottom: 28px; margin-top: 20px;">
349 <div style="font-weight: 600; color: #363A42; font-size: 14px; margin-bottom: 8px;">VWO (Wingify) Dashboard?</div>
350 <div style="font-size: 14px; color: #757575; font-weight: 400;">Visit our knowledge base to learn how to use the VWO dashboard.</div>
351 <a href="https://app.wingify.com" target="_blank" style="display: inline-flex; align-items: center; color: #2271B1; border-radius: 8px; padding: 6px 12px; font-size: 12px; font-weight: 600; cursor: pointer; text-decoration: none; margin-top: 10px; border: 1px solid #2271B1;">
352 <span style="margin-right: 4px;">Go to Dashboard</span>
353 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 32 32">
354 <path fill="#2271B1" d="M17.88 1v3.75h5.62l-9.38 9.38 3.76 3.74 9.37-9.37v5.63H31V1H17.87zm9.37 26.25H4.75V4.75h7.5V1H1v30h30V19.75h-3.75v7.5z"/>
355 </svg>
356 </a>
357 </div>
358 <div style="font-size: 13px;">
359 Need help? Visit our <a style="color: inherit;" href="https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress">Knowledge Base</a> for guides and FAQs.
360 </div>
361 </div>
362 </main>
363 <?php
364 }
365
366 function vwo_clhf_render_advanced_settings() {
367 ?>
368 <div class="form-container">
369 <?php
370 vwo_clhf_render_field([
371 'id' => 'vwo_clicks',
372 'label' => 'No. of Heatmap Clicks',
373 'type' => 'number',
374 'tooltip' => 'Set the number of heatmap clicks to record',
375 'min' => 3,
376 'default' => 10,
377 ]);
378 vwo_clhf_render_field([
379 'id' => 'settings_tolerance',
380 'label' => 'Settings Timeout',
381 'type' => 'number',
382 'tooltip' => 'Set the timeout for settings in milliseconds',
383 'default' => 2000,
384 'class' => 'async-option',
385 'suffix' => 'ms',
386 ]);
387 vwo_clhf_render_field([
388 'id' => 'library_tolerance',
389 'label' => 'Library Timeout',
390 'type' => 'number',
391 'tooltip' => 'Set the timeout for library in milliseconds',
392 'default' => 2500,
393 'class' => 'async-option',
394 'suffix' => 'ms',
395 ]);
396 vwo_clhf_render_field([
397 'id' => 'use_existing_jquery',
398 'label' => 'Use Existing jQuery',
399 'type' => 'checkbox',
400 'tooltip' => 'Use the existing jQuery library on your site',
401 'class' => 'async-option',
402 ]);
403 vwo_clhf_render_field([
404 'id' => 'ignore_js',
405 'label' => 'Skip Deferred Execution',
406 'type' => 'checkbox',
407 'tooltip' => 'Skip deferred execution of the VWO script',
408 ]);
409 ?>
410 </div>
411 <?php
412 }
413
414 function vwo_clhf_render_woocommerce_settings() {
415 $value = get_option('enable_woocommerce_event_tracking', false);
416 $vwo_server_side_tracking = get_option('vwo_server_side_tracking', false);
417 ?>
418 <div>
419 <div class="woocommerce-main-header">
420 <div class="checkbox-container">
421 <input type="checkbox" id="enable_woocommerce_event_tracking" name="enable_woocommerce_event_tracking" class="vwo-checkbox" <?php echo checked($value, '1', false) ?>>
422 <label class="vwo-checkbox-label" for="enable_woocommerce_event_tracking">Toggle</label>
423 <label class="form-label form-label--checkbox" for="enable_woocommerce_event_tracking">Enable WooCommerce Event Tracking</label>
424 </div>
425 <p class="form-description form-description--checkbox">Event tracking will not work unless WooCommerce is enabled on your WordPress site.</p>
426 </div>
427 <div class="woocommerce-main-header">
428 <div class="checkbox-container vwo_server_side_tracking">
429 <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) ?>>
430 <label class="vwo-checkbox-label" for="vwo_server_side_tracking">Toggle</label>
431 <label class="form-label form-label--checkbox" for="Enable Server-Side Tracking">Enable Server-Side Tracking</label>
432 </div>
433 <p class="form-description form-description--checkbox">Enable server-side tracking instead of JavaScript-based tracking.</p>
434 </div>
435
436
437 <div class="woocommerce-row woocommerce-row--disabled">
438 <?php
439 vwo_clhf_render_woocommerce_event_tracking([
440 'id' => 'track_product_view',
441 'label' => 'Product Viewed',
442 'description' => 'This event logs an instance where a customer views a product details page.',
443 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
444 ]);
445 vwo_clhf_render_woocommerce_event_tracking([
446 'id' => 'track_add_to_cart',
447 'label' => 'Add To Cart',
448 'description' => 'This event logs an instance where a customer adds a product to their cart.',
449 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
450 ]);
451 vwo_clhf_render_woocommerce_event_tracking([
452 'id' => 'track_remove_from_cart',
453 'label' => 'Product Removed From Cart',
454 'description' => 'This event logs an instance where a customer removes a product from their cart.',
455 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
456 ]);
457 vwo_clhf_render_woocommerce_event_tracking([
458 'id' => 'track_purchase',
459 'label' => 'Purchase Order',
460 'description' => 'This event logs an instance where a customer completes a purchase.',
461 'readmore_link' => 'https://help.vwo.com/hc/en-us/articles/360020745993-Integrating-VWO-With-WordPress'
462 ]);
463 ?>
464 </div>
465 </div>
466 <?php
467 }
468
469 function vwo_clhf_render_woocommerce_event_tracking($field) {
470 $value = get_option($field['id'], isset($field['default']) ? $field['default'] : '');
471 ?>
472 <div class="woocommerce-row-item">
473 <div class="woocommerce-row-item-header">
474 <h3 class="woocommerce-row-item-title"><?php echo esc_html($field['label']); ?></h3>
475 <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">
476 <label for="<?php echo esc_attr($field['id']); ?>" class="vwo-checkbox-label">Toggle</label>
477 </div>
478 <p class="woocommerce-row-item-description">
479 <?php echo esc_html($field['description']); ?>
480 <?php /* if (isset($field['readmore_link'])): ?>
481 <a href="<?php echo esc_url($field['readmore_link']); ?>" target="_blank">Read more</a>
482 <?php endif; */ ?>
483 </p>
484 </div>
485 <?php
486 }
487
488
489 function vwo_clhf_render_field($field) {
490 $isCheckbox = $field['type'] === 'checkbox';
491 $value = get_option($field['id'], isset($field['default']) ? $field['default'] : '');
492
493 echo '<div class="' . esc_attr(isset($field['class'])?$field['class']:"") . '">';
494
495 $label = '<label class="form-label" for="' . esc_attr($field['id']) . '">' . esc_html($field['label']) . '</label>';
496
497 switch ($field['type']) {
498 case 'text':
499 case 'number':
500 echo $label;
501 echo '<input type="' . esc_attr($field['type']) . '" id="' . esc_attr($field['id']) . '" name="' . esc_attr($field['id']) . '" value="' . esc_attr($value) . '"';
502 if (isset($field['min'])) echo ' min="' . esc_attr($field['min']) . '"';
503 echo ' class="form-input" />';
504 if (isset($field['suffix'])) echo ' ' . esc_html($field['suffix']);
505 break;
506 case 'radio':
507 echo $label;
508 foreach ($field['options'] as $options) {
509 echo '<div class="radio-container-wrapper">
510 <div class="radio-container">';
511 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> ';
512 echo '</div>';
513 echo '<p class="radio-sublabel">' . esc_html($options['sublabel']) . '</p>';
514 echo '</div>';
515 }
516 break;
517 case 'checkbox':
518 echo '<div class="checkbox-container">';
519 echo '<input type="checkbox" id="' . esc_attr($field['id']) . '" name="' . esc_attr($field['id']) . '" class="vwo-checkbox" value="1"' . checked($value, '1', false) . ' />';
520 echo '<label class="vwo-checkbox-label" for="' . esc_attr($field['id']) . '">Toggle</label>';
521 echo '<label class="form-label form-label--checkbox" for="' . esc_attr($field['id']) . '">' . esc_html($field['label']) . '</label>';
522 echo '</div>';
523 break;
524 }
525
526 if (isset($field['tooltip'])) {
527 echo '<p class="form-description ' . ($isCheckbox ? 'form-description--checkbox' : '') . '">' . esc_html($field['tooltip']) . '</p>';
528 }
529
530 echo '</div>';
531 }
532
533 function vwo_clhf_render_styles() {
534 ?>
535 <style>
536 input[type="radio"] {
537 margin: 0 !important;
538 }
539 input[type=radio]:checked::before {
540 background-color: #3858E9;
541 }
542 .vwo-admin-content {
543 background: #fff;
544 padding: 20px;
545 border: 1px solid #ccd0d4;
546 box-shadow: 0 1px 1px rgba(0,0,0,.04);
547 margin-top: 20px;
548 }
549 .vwo-admin-content .nav-tab,
550 .vwo-admin-content .nav-tab-active{
551 outline:none;
552 box-shadow: none;
553 }
554 .main-grid {
555 display: flex;
556 justify-content: space-between;
557 }
558 .main-grid__description {
559 background-color: #f9f9f9;
560 padding: 24px;
561 border-radius: 8px;
562 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
563 font-family: 'Segoe UI', sans-serif;
564 height: fit-content;max-width: 650px;
565 border: 1px solid #E0E0E0;
566 margin: 20px;
567 }
568 .main-grid__description h2 {
569 font-weight: 600;
570 margin-bottom: 10px;
571 margin-top: 0;
572 font-size: 20px;
573 color: #333;
574 }
575 .main-grid__description p {
576 font-size: 14px;
577 color: #757575;
578 line-height: 1.6;
579 margin-top: 21px;
580 margin-bottom: 0px;
581 }
582 .main-grid__description a {
583 color: #3858E9;
584 }
585 .form-container {
586 margin-top: 24px;
587 margin-bottom: 30px;
588 display: flex;
589 flex-direction: column;
590 gap: 28px;
591 flex: 1;
592 }
593 .form-label {
594 font-size: 12px;
595 color: #1E1E1E;
596 display: block;
597 margin-bottom: 10px;
598 font-weight: 500;
599 }
600 .form-label--checkbox {
601 cursor: pointer;
602 margin-bottom: 0;
603 }
604 .form-radio-label {
605 display: flex;
606 align-items: center;
607 gap: 10px;
608 margin-bottom: 10px;
609 cursor: pointer;
610 }
611 .form-radio-label:last-child {
612 margin-bottom: 0;
613 }
614 .form-description {
615 color: #757575;
616 margin-top: 10px;
617 margin-bottom: 0;
618 font-size: 12px;
619 }
620 .form-description--checkbox {
621 margin-top: 5px;
622 margin-left: 42px;
623 }
624 .form-input {
625 width: 100%;
626 max-width: 400px;
627 border: 1px solid #949494 !important;
628 border-radius: 2px !important;
629 }
630 .checkbox-container, .radio-container {
631 display: flex;
632 gap: 10px;
633 }
634 .radio-container-wrapper {
635 margin-bottom: 20px;
636 }
637 .radio-container-wrapper:last-child {
638 margin-bottom: 0;
639 }
640 .radio-sublabel {
641 font-size: 12px;
642 color: #757575;
643 margin-top: 5px;
644 margin-bottom: 0;
645 margin-left: 26px;
646 }
647 .checkbox-container .form-description {
648 width: 100%;
649 }
650 .async-option {
651 display: none;
652 }
653 .tab-pane {
654 display: none;
655 }
656 .tab-pane.active {
657 display: block;
658 }
659 .description {
660 max-width: 800px;
661 margin-bottom: 20px;
662 }
663
664 .woocommerce-row {
665 display: grid;
666 grid-template-columns: repeat(3, 1fr);
667 gap: 16px;
668 }
669 .woocommerce-row-item {
670 border: 1px solid rgba(0, 0, 0, 0.10);
671 border-radius: 8px;
672 }
673 .woocommerce-row-item-header {
674 display: flex;
675 justify-content: space-between;
676 align-items: center;
677 gap: 5px;
678 padding: 10px;
679 border-bottom: 1px solid rgba(0, 0, 0, 0.10);
680 }
681 .woocommerce-row-item-title {
682 margin: 0;
683 font-size: 13px;
684 font-weight: 500;
685 color: #1E1E1E;
686 }
687 .woocommerce-row-item-description {
688 margin: 0;
689 font-size: 12px;
690 color: #757575;
691 padding: 10px;
692 }
693 .woocommerce-row-item-description a {
694 color: #3858E9;
695 }
696 .woocommerce-main-header {
697 margin: 30px 0;
698 }
699 .woocommerce-row--disabled {
700 opacity: 0.4;
701 cursor: not-allowed;
702 pointer-events: none;
703 }
704 input[type=checkbox].vwo-checkbox{
705 height: 0;
706 width: 0;
707 visibility: hidden;
708 position: absolute;
709 clip: rect(1px,1px,1px,1px);
710 overflow: hidden;
711 }
712
713 label.vwo-checkbox-label {
714 box-sizing: border-box;
715 cursor: pointer;
716 text-indent: -9999px;
717 width: 32px;
718 height: 18px;
719 border: 1px solid #000;
720 background: #fff;
721 display: block;
722 border-radius: 100px;
723 position: relative;
724 }
725
726 label.vwo-checkbox-label:after {
727 content: '';
728 position: absolute;
729 top: 50%;
730 transform: translateY(-50%);
731 left: 2px;
732 width: 12px;
733 height: 12px;
734 background: #000;
735 border-radius: 90px;
736 transition: 0.3s;
737 }
738
739 input.vwo-checkbox:checked + label.vwo-checkbox-label {
740 background: #3858E9;
741 border-color: #3858E9;
742 }
743
744 input.vwo-checkbox:checked + label.vwo-checkbox-label:after {
745 left: calc(100% - 2px);
746 transform: translateX(-100%) translateY(-50%);
747 background-color: #fff;
748 }
749
750 </style>
751 <?php
752 }
753
754 function vwo_clhf_render_scripts() {
755 ?>
756 <script>
757 jQuery(document).ready(function($) {
758 function toggleAsyncOptions() {
759 var isAsync = $('input[name="code_type"]:checked').val() === 'ASYNC';
760 $('.async-option').toggle(isAsync);
761 }
762 function toggleWooCommerceOptions() {
763 var isWooCommerce = $('input[name="enable_woocommerce_event_tracking"]:checked');
764
765 if(isWooCommerce.length > 0) {
766 $('.woocommerce-row').removeClass('woocommerce-row--disabled');
767 $('.vwo_server_side_tracking').removeClass('woocommerce-row--disabled');
768
769 } else {
770 $('.woocommerce-row').addClass('woocommerce-row--disabled');
771 $('.vwo_server_side_tracking').addClass('woocommerce-row--disabled');
772 }
773 }
774
775 $('input[name="enable_woocommerce_event_tracking"]').change(toggleWooCommerceOptions);
776 $("label[for='enable_woocommerce_event_tracking']").click(toggleWooCommerceOptions);
777 toggleWooCommerceOptions(); // Run on page load
778
779 $('input[name="code_type"]').change(toggleAsyncOptions);
780 toggleAsyncOptions(); // Run on page load
781
782 // Handle tab switching
783 $('.nav-tab-wrapper .nav-tab').on('click', function(e) {
784 e.preventDefault();
785 var targetTab = $(this).attr('href');
786
787 // Update active tab
788 $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active');
789 $(this).addClass('nav-tab-active');
790
791 // Show target tab content
792 $('.tab-pane').removeClass('active').hide();
793 $(targetTab).addClass('active').show();
794 });
795
796 // Ensure the first tab is visible on page load
797 $('#tab-general').show();
798 });
799 </script>
800 <?php
801 }
802
803 function vwo_clhf_enqueue_admin_scripts($hook) {
804 if ('settings_page_clhf_vwo_options' !== $hook) {
805 return;
806 }
807 wp_enqueue_style('wp-admin');
808 }
809 add_action('admin_enqueue_scripts', 'vwo_clhf_enqueue_admin_scripts');
810
811 /**
812 * Displays a warning message if VWO settings are not configured.
813 * 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
814 * the VWO ID option is not set, it displays a warning message.
815 *
816 * @throws Exception Description of exception.
817 * @return void
818 */
819 function vwo_clhf_warn_nosettings() {
820 if ( ! is_admin() ) {
821 return;
822 }
823
824 $clhf_option = get_option( 'vwo_id' );
825 if ( ! $clhf_option || $clhf_option < 1 ) {
826 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>";
827 }
828 }
829
830
831 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'vwo_clhf_add_plugin_page_settings_link' );
832
833 /**
834 * Function to add Settings Links on Plugin page
835 *
836 * @param array $links Array of links.
837 * @return array
838 */
839 function vwo_clhf_add_plugin_page_settings_link( $links ) {
840 $links[] = '<a href="' .
841 admin_url( 'options-general.php?page=clhf_vwo_options' ) .
842 '">' . __( 'Settings' ) . '</a>';
843 return $links;
844 }
845
846 /**
847 * Disables VWO in Divi Builder.
848 *
849 * @throws Exception Description of exception.
850 * @return void
851 */
852 function disable_vwo_in_divi_builder() {
853 if ( has_action( 'wp_head', 'vwo_clhf_headercode' ) && function_exists( 'et_core_is_fb_enabled' ) && et_core_is_fb_enabled() ) {
854 remove_action( 'wp_head', 'vwo_clhf_headercode', 1 );
855 }
856 }
857
858 add_action( 'wp_head', 'disable_vwo_in_divi_builder', 0 );
859
860 // Add this new function to validate settings
861 function vwo_clhf_validate_settings() {
862 $has_errors = false;
863
864 // Validate VWO Account ID
865 $vwo_id = get_option('vwo_id');
866 if (empty($vwo_id) || !is_numeric($vwo_id)) {
867 add_settings_error('vwo_clhf_options', 'vwo_id', 'Please enter a valid VWO Account ID.', 'error');
868 $has_errors = true;
869 }
870
871 // Add more validation for other fields as needed
872
873 return $has_errors;
874 }
875
876 /**
877 * Whether the configured account is a Wingify account.
878 *
879 * @return bool
880 */
881 function vwo_clhf_is_wingify_account() {
882 return '1' === get_option( 'is_wingify_account' );
883 }
884
885 /**
886 * Fetch account info from VWO API and save collUrl and is_wingify_account options.
887 *
888 * @param int|string $vwo_id VWO Account ID.
889 * @return string Collection URL if available, empty string otherwise.
890 */
891 function vwo_clhf_fetch_and_save_account_info( $vwo_id ) {
892 $coll_url = '';
893
894 if ( empty( $vwo_id ) || ! is_numeric( $vwo_id ) ) {
895 return $coll_url;
896 }
897
898 $api_url = 'https://edge.wingify.net/accInfo?a=' . $vwo_id;
899 $response = wp_remote_get(
900 $api_url,
901 array(
902 'timeout' => 15,
903 'sslverify' => false,
904 'headers' => array(
905 'Accept-Encoding' => 'gzip, deflate, br',
906 'User-Agent' => 'vwo-woocommerce-plugin',
907 ),
908 )
909 );
910
911 if ( is_wp_error( $response ) ) {
912 return $coll_url;
913 }
914
915 $body = wp_remote_retrieve_body( $response );
916 if ( empty( $body ) ) {
917 return $coll_url;
918 }
919
920 $data = json_decode( $body, true );
921
922 if ( ! is_array( $data ) ) {
923 return $coll_url;
924 }
925
926 if ( ! empty( $data['collUrl'] ) ) {
927 $coll_url = $data['collUrl'];
928 update_option( 'vwo_coll_url', sanitize_text_field( $data['collUrl'] ) );
929 }
930
931 if ( isset( $data['wd'] ) && $data['wd'] ) {
932 update_option( 'is_wingify_account', '1' );
933 } else {
934 update_option( 'is_wingify_account', '' );
935 }
936
937 return $coll_url;
938 }
939
940 // Add this new function to sanitize and validate settings
941 function vwo_clhf_sanitize_settings($input) {
942 // Sanitize and validate VWO Account ID
943 $vwo_id = sanitize_text_field($input);
944 if (empty($vwo_id) || !is_numeric($vwo_id)) {
945 add_settings_error('vwo_clhf_options', 'vwo_id', 'Please enter a valid VWO Account ID.', 'error');
946 }
947
948 // Add more sanitization and validation for other fields as needed
949 // Check if vwo_id is changed
950 $current_vwo_id = get_option('vwo_id');
951 if ($current_vwo_id !== $vwo_id) {
952 update_option( 'vwo_coll_url', '' );
953 delete_option( 'is_wingify_account' );
954 vwo_clhf_fetch_and_save_account_info( $vwo_id );
955 }
956 return $vwo_id;
957 }
958
959 function enqueue_jquery_script() {
960 wp_enqueue_script('jquery');
961 }
962 add_action('wp_enqueue_scripts', 'enqueue_jquery_script');
963
964 if (file_exists(plugin_dir_path(__FILE__) . 'woocommerce-events.php')) {
965 include_once plugin_dir_path(__FILE__) . 'woocommerce-events.php';
966 }
967
968
969 ?>