PluginProbe
Wingify / 4.15
Wingify v4.15
4.15 4.16 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 All 39 releases
visual-web-optimizer / visual-website-optimizer.php

visual-website-optimizer.php in Wingify 4.15, at visual-website-optimizer.php

970 lines 49.9 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: Wingify
5 * Plugin URI: https://wingify.com/
6 * Description: Wingify (formerly VWO & AB Tasty) 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://wingify.com/">Wingify</a> for more details.
7 * Author: Wingify
8 * Version: 4.15
9 * visual-website-optimizer.php
10 * Author URI: https://wingify.com/
11 *
12 * @package Wingify
13 * @author Wingify
14 * @version 4.15
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 Wingify 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 Wingify 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 Wingify 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 Wingify 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 Wingify 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 Wingify 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 Wingify 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( 'Wingify', 'Wingify', 'create_users', 'clhf_vwo_options', 'vwo_clhf_plugin_options' );
173 }
174
175 /**
176 * Register the settings for the Wingify 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 wingify_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" xmlns:xlink="http://www.w3.org/1999/xlink" width="158.594" height="50" viewBox="0 0 158.594 50" fill="none"><svg x="0.01" y="0" width="158.571" height="50" viewBox="0 0 86.719 27.344" preserveAspectRatio="xMidYMid meet" overflow="visible"><path fill-rule="evenodd" clip-rule="evenodd" d="M56.674 5.457h-5.383c-0.015 0 -0.032 0.013 -0.032 0.038 0 0.063 0.089 0.085 0.089 0.085 3.02 0.655 5.652 2.813 5.652 5.974 0 3.506 -2.717 6.393 -6.869 6.393 -0.906 0 -1.551 -0.131 -1.996 -0.259 -0.806 1.51 -0.914 1.794 -0.914 1.955 0 0.242 0.297 0.351 0.722 0.351h8.78l-2.289 4.832H45.979c-1.484 0 -2.617 -0.702 -2.617 -1.969 -0.025 -1.241 0.78 -2.266 3.322 -5.612 -2.24 -1.025 -3.623 -3.075 -3.623 -5.53s1.133 -5.098 6.039 -6.906l7.573 -2.805zm-8.623 1.328a0.07 0.07 0 0 0 -0.084 0.035c-0.125 0.238 -0.62 1.293 -0.59 2.954 0.106 5.73 4.184 6.423 4.603 6.479a0.063 0.063 0 0 0 0.059 -0.024c0.113 -0.148 0.594 -0.898 0.594 -2.977 0 -4.922 -4.059 -6.309 -4.582 -6.467" fill="#212326"/><path d="m73.68 3.131 -3.87 -0.984a0.078 0.078 0 0 0 -0.095 0.089l0.594 3.175h7.55l3.346 10.873 1.61 -10.873h3.397l-6.089 19.415h-5.531l4.756 -4.76h-2.018L73.162 7.992h-2.325v12.075H65.578V7.991h-1.56l1.56 -2.605C67.641 1.829 69.151 0.3 73.68 0z" fill="#212326"/><path d="M15.866 12.14a0.077 0.077 0 0 0 0.144 -0.02l1.402 -6.709h3.472l-6.266 15.031 -4.126 -7.69 -4.252 7.69L0 5.411h5.888l2.464 6.759c0.023 0.063 0.108 0.069 0.141 0.011l3.795 -6.795z" fill="#212326"/><path d="M26.622 20.066h-5.284V5.411h5.284z" fill="#212326"/><path d="M38.834 5.162c2.148 0.041 3.293 1.388 3.293 3.656v11.248H36.844V9.781c0 -1.102 -0.319 -1.754 -1.401 -1.754 -0.703 0 -1.52 0.558 -2.021 0.891v11.148h-5.284V5.411h5.284v1.679c1.963 -1.078 3.749 -1.93 5.309 -1.93z" fill="#212326"/><path d="M63.349 20.066h-5.284V5.411h5.284z" fill="#212326"/><path d="M26.622 3.532h-5.284V0.15h5.284z" fill="#212326"/><path d="M63.349 3.532h-5.284V0.15h5.284z" fill="#212326"/><path d="m8.859 24.231 -0.248 -0.081v-0.082h0.552v0.086l-0.166 0.066 -0.783 2.111c-0.067 0.177 -0.177 0.298 -0.351 0.298a0.206 0.206 0 0 1 -0.209 -0.205c0 -0.113 0.092 -0.202 0.202 -0.202 0.099 0 0.156 0.07 0.213 0.138l0.011 0.01 0.191 -0.506 -0.634 -1.658 -0.152 -0.053v-0.085h0.702v0.086l-0.177 0.063 0.432 1.18z" fill="#212326"/><path d="M6.367 25.799c-0.159 0 -0.307 -0.035 -0.399 -0.074l-0.131 -0.053V23.406l-0.22 -0.096v-0.042l0.552 -0.166v1.201c0.081 -0.092 0.277 -0.28 0.549 -0.28 0.326 0 0.652 0.23 0.652 0.794 0 0.527 -0.51 0.984 -1.002 0.984m-0.198 -0.294c0.011 0.014 0.138 0.148 0.365 0.148 0.255 0 0.5 -0.219 0.5 -0.726 0 -0.404 -0.241 -0.702 -0.507 -0.702a0.531 0.531 0 0 0 -0.358 0.152z" fill="#212326"/><path d="M34.082 24.97c0 -0.154 0.091 -0.245 0.284 -0.273l0.445 -0.063v0.12a0.44 0.44 0 0 1 -0.457 0.457c-0.18 0 -0.271 -0.086 -0.271 -0.24m-4.285 -1.094v-0.582h0.832c0.217 0 0.305 0.085 0.305 0.289 0 0.202 -0.091 0.297 -0.305 0.297zm0 1.16v-0.643h0.816q0.401 0 0.4 0.306c0 0.217 -0.139 0.334 -0.4 0.334zm-2.542 -0.693 0.362 -1.002h0.026l0.359 1.002zm11.081 1.21h0.463v-0.461h-0.277c-0.113 0 -0.155 -0.041 -0.155 -0.154v-0.851h0.68l0.599 1.506c0.056 0.141 -0.009 0.233 -0.167 0.233h-0.391v0.461h0.403c0.375 0 0.548 -0.117 0.665 -0.445l0.791 -2.211v-0.01h-0.573l-0.419 1.348h-0.025l-0.463 -1.348h-1.103v-0.608h-0.541v0.608h-0.319v0.463h0.322v0.952c0 0.378 0.138 0.517 0.51 0.517m-4.147 0.081c0.268 0 0.489 -0.109 0.621 -0.305h0.025c0.057 0.156 0.234 0.267 0.457 0.267a0.445 0.445 0 0 0 0.419 -0.242c0.198 0.157 0.48 0.245 0.807 0.245 0.586 0 0.961 -0.284 0.961 -0.722 0 -0.334 -0.22 -0.507 -0.75 -0.57l-0.249 -0.028c-0.189 -0.019 -0.245 -0.054 -0.245 -0.133 0 -0.109 0.104 -0.176 0.273 -0.176 0.184 0 0.347 0.085 0.432 0.227l0.485 -0.211c-0.154 -0.268 -0.504 -0.441 -0.92 -0.441 -0.498 0 -0.816 0.246 -0.816 0.63q0.001 0.496 0.716 0.589l0.261 0.038c0.186 0.025 0.268 0.072 0.268 0.166 0 0.117 -0.129 0.205 -0.369 0.205 -0.267 0 -0.463 -0.111 -0.541 -0.306l-0.242 0.155a0.469 0.469 0 0 1 -0.25 0.088c-0.132 -0.009 -0.182 -0.057 -0.182 -0.173v-0.693c0 -0.479 -0.262 -0.694 -0.848 -0.694 -0.533 0 -0.823 0.186 -0.905 0.573l0.552 0.098c0.031 -0.148 0.154 -0.23 0.347 -0.23 0.211 0 0.312 0.088 0.312 0.277v0.019l-0.617 0.091c-0.406 0.06 -0.649 0.299 -0.649 0.655 0 0.359 0.255 0.598 0.648 0.598m-1.698 -0.081h0.598v-2.259h0.933v-0.517h-2.383v0.517h0.852zm-3.29 0h1.563c0.545 0 0.863 -0.284 0.863 -0.763 0 -0.362 -0.186 -0.589 -0.535 -0.664v-0.026c0.305 -0.104 0.457 -0.313 0.457 -0.633 0 -0.451 -0.287 -0.691 -0.829 -0.691h-1.519zm-2.988 0h0.605l0.249 -0.694h1.118l0.249 0.694h0.633v-0.01l-1.068 -2.77h-0.721l-1.066 2.77zM26.177 21.875l-0.851 3.677h-3.447l0.82 0.349 -0.063 0.274h-1.856l0.461 0.211 -0.048 0.214h-0.936l0.344 -1.49h0.545l0.372 -1.585h1.034l0.378 -1.651z" fill="#212326"/><path d="M18.043 22.762c-0.059 0 -0.128 0 -0.186 0.012l-0.336 0.586c0.151 -0.092 0.336 -0.138 0.522 -0.138 0.603 0 1.102 0.494 1.102 1.091 0 0.598 -0.498 1.091 -1.102 1.091a1.102 1.102 0 0 1 -1.102 -1.08l-0.348 0.586a1.563 1.563 0 0 0 1.438 0.953c0.859 0 1.566 -0.701 1.566 -1.551 0.012 -0.849 -0.695 -1.55 -1.555 -1.55" fill="#212326"/><path d="m13.311 24.381 0.266 -0.459 0.603 1.022 0.695 -1.183 0.697 1.183 1.195 -2.009a0.344 0.344 0 0 1 0.302 -0.172h0.336l-1.832 3.1 -0.696 -1.183 -0.695 1.183z" fill="#212326"/><path d="m13.809 22.762 -1.832 3.101L10.156 22.762h0.336c0.127 0 0.244 0.069 0.302 0.172l1.183 2.022 1.195 -2.021a0.344 0.344 0 0 1 0.302 -0.172z" fill="#212326"/></svg></svg>
273 <span>Configuration</span>
274 </h1>
275
276 <form method="post" action="options.php" novalidate>
277 <?php
278 settings_fields('clhf_vwo_options');
279 ?>
280 <div class="vwo-admin-content">
281 <?php vwo_clhf_render_tabs(); ?>
282 <div class="tab-content">
283 <div id="tab-general" class="tab-pane active">
284 <?php vwo_clhf_render_general_settings(); ?>
285 </div>
286 <div id="tab-advanced" class="tab-pane">
287 <?php vwo_clhf_render_advanced_settings(); ?>
288 </div>
289 <div id="tab-woocommerce" class="tab-pane">
290 <?php vwo_clhf_render_woocommerce_settings(); ?>
291 </div>
292 </div>
293 </div>
294 <?php submit_button(); ?>
295 </form>
296 </div>
297 <?php
298 vwo_clhf_render_styles();
299 vwo_clhf_render_scripts();
300 }
301
302 function vwo_clhf_render_tabs() {
303 ?>
304 <h2 class="nav-tab-wrapper">
305 <a href="#tab-general" class="nav-tab nav-tab-active">General Settings</a>
306 <a href="#tab-advanced" class="nav-tab">Advanced Settings</a>
307 <a href="#tab-woocommerce" class="nav-tab">WooCommerce</a>
308 </h2>
309 <?php
310 }
311
312 function vwo_clhf_render_general_settings() {
313 ?>
314 <main class="main-grid">
315 <div class="form-container">
316 <?php
317 vwo_clhf_render_field([
318 'id' => 'vwo_id',
319 'label' => 'Your Wingify Account ID',
320 'type' => 'text',
321 'tooltip' => 'Enter your Wingify Account ID here',
322 ]);
323 vwo_clhf_render_field([
324 'id' => 'code_type',
325 'label' => 'Code Type',
326 'type' => 'radio',
327 'options' => [
328 [
329 'label' => 'Asynchronous',
330 'value' => 'ASYNC',
331 'sublabel' => 'Loads faster without blocking other elements',
332 ],
333 [
334 'label' => 'Synchronous',
335 'value' => 'SYNC',
336 'sublabel' => 'Executes immediately but may slow down page load',
337 ],
338 ],
339 ]);
340 ?>
341 </div>
342 <div class="main-grid__description" style="width:350px;">
343 <div style="font-size: 18px; font-weight: 700; color: #000000; margin-bottom: 8px;">New to Wingify?</div>
344 <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>
345 <div>
346 <a target="_blank" href="https://wingify.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;">
347 Get Started for Free</a>
348 <div>
349 <div style="margin-bottom: 28px; margin-top: 20px;">
350 <div style="font-weight: 600; color: #363A42; font-size: 14px; margin-bottom: 8px;">Wingify Dashboard?</div>
351 <div style="font-size: 14px; color: #757575; font-weight: 400;">Visit our knowledge base to learn how to use the Wingify dashboard.</div>
352 <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;">
353 <span style="margin-right: 4px;">Go to Dashboard</span>
354 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 32 32">
355 <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"/>
356 </svg>
357 </a>
358 </div>
359 <div style="font-size: 13px;">
360 Need help? Visit our <a style="color: inherit;" href="https://help.wingify.com/hc/en-us/articles/59247859917465-Integrate-Wingify-with-WordPress">Knowledge Base</a> for guides and FAQs.
361 </div>
362 </div>
363 </main>
364 <?php
365 }
366
367 function vwo_clhf_render_advanced_settings() {
368 ?>
369 <div class="form-container">
370 <?php
371 vwo_clhf_render_field([
372 'id' => 'vwo_clicks',
373 'label' => 'No. of Heatmap Clicks',
374 'type' => 'number',
375 'tooltip' => 'Set the number of heatmap clicks to record',
376 'min' => 3,
377 'default' => 10,
378 ]);
379 vwo_clhf_render_field([
380 'id' => 'settings_tolerance',
381 'label' => 'Settings Timeout',
382 'type' => 'number',
383 'tooltip' => 'Set the timeout for settings in milliseconds',
384 'default' => 2000,
385 'class' => 'async-option',
386 'suffix' => 'ms',
387 ]);
388 vwo_clhf_render_field([
389 'id' => 'library_tolerance',
390 'label' => 'Library Timeout',
391 'type' => 'number',
392 'tooltip' => 'Set the timeout for library in milliseconds',
393 'default' => 2500,
394 'class' => 'async-option',
395 'suffix' => 'ms',
396 ]);
397 vwo_clhf_render_field([
398 'id' => 'use_existing_jquery',
399 'label' => 'Use Existing jQuery',
400 'type' => 'checkbox',
401 'tooltip' => 'Use the existing jQuery library on your site',
402 'class' => 'async-option',
403 ]);
404 vwo_clhf_render_field([
405 'id' => 'ignore_js',
406 'label' => 'Skip Deferred Execution',
407 'type' => 'checkbox',
408 'tooltip' => 'Skip deferred execution of the Wingify script',
409 ]);
410 ?>
411 </div>
412 <?php
413 }
414
415 function vwo_clhf_render_woocommerce_settings() {
416 $value = get_option('enable_woocommerce_event_tracking', false);
417 $vwo_server_side_tracking = get_option('vwo_server_side_tracking', false);
418 ?>
419 <div>
420 <div class="woocommerce-main-header">
421 <div class="checkbox-container">
422 <input type="checkbox" id="enable_woocommerce_event_tracking" name="enable_woocommerce_event_tracking" class="vwo-checkbox" <?php echo checked($value, '1', false) ?>>
423 <label class="vwo-checkbox-label" for="enable_woocommerce_event_tracking">Toggle</label>
424 <label class="form-label form-label--checkbox" for="enable_woocommerce_event_tracking">Enable WooCommerce Event Tracking</label>
425 </div>
426 <p class="form-description form-description--checkbox">Event tracking will not work unless WooCommerce is enabled on your WordPress site.</p>
427 </div>
428 <div class="woocommerce-main-header">
429 <div class="checkbox-container vwo_server_side_tracking">
430 <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) ?>>
431 <label class="vwo-checkbox-label" for="vwo_server_side_tracking">Toggle</label>
432 <label class="form-label form-label--checkbox" for="Enable Server-Side Tracking">Enable Server-Side Tracking</label>
433 </div>
434 <p class="form-description form-description--checkbox">Enable server-side tracking instead of JavaScript-based tracking.</p>
435 </div>
436
437
438 <div class="woocommerce-row woocommerce-row--disabled">
439 <?php
440 vwo_clhf_render_woocommerce_event_tracking([
441 'id' => 'track_product_view',
442 'label' => 'Product Viewed',
443 'description' => 'This event logs an instance where a customer views a product details page.',
444 'readmore_link' => 'https://help.wingify.com/hc/en-us/articles/59247859917465-Integrate-Wingify-with-WordPress'
445 ]);
446 vwo_clhf_render_woocommerce_event_tracking([
447 'id' => 'track_add_to_cart',
448 'label' => 'Add To Cart',
449 'description' => 'This event logs an instance where a customer adds a product to their cart.',
450 'readmore_link' => 'https://help.wingify.com/hc/en-us/articles/59247859917465-Integrate-Wingify-with-WordPress'
451 ]);
452 vwo_clhf_render_woocommerce_event_tracking([
453 'id' => 'track_remove_from_cart',
454 'label' => 'Product Removed From Cart',
455 'description' => 'This event logs an instance where a customer removes a product from their cart.',
456 'readmore_link' => 'https://help.wingify.com/hc/en-us/articles/59247859917465-Integrate-Wingify-with-WordPress'
457 ]);
458 vwo_clhf_render_woocommerce_event_tracking([
459 'id' => 'track_purchase',
460 'label' => 'Purchase Order',
461 'description' => 'This event logs an instance where a customer completes a purchase.',
462 'readmore_link' => 'https://help.wingify.com/hc/en-us/articles/59247859917465-Integrate-Wingify-with-WordPress'
463 ]);
464 ?>
465 </div>
466 </div>
467 <?php
468 }
469
470 function vwo_clhf_render_woocommerce_event_tracking($field) {
471 $value = get_option($field['id'], isset($field['default']) ? $field['default'] : '');
472 ?>
473 <div class="woocommerce-row-item">
474 <div class="woocommerce-row-item-header">
475 <h3 class="woocommerce-row-item-title"><?php echo esc_html($field['label']); ?></h3>
476 <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">
477 <label for="<?php echo esc_attr($field['id']); ?>" class="vwo-checkbox-label">Toggle</label>
478 </div>
479 <p class="woocommerce-row-item-description">
480 <?php echo esc_html($field['description']); ?>
481 <?php /* if (isset($field['readmore_link'])): ?>
482 <a href="<?php echo esc_url($field['readmore_link']); ?>" target="_blank">Read more</a>
483 <?php endif; */ ?>
484 </p>
485 </div>
486 <?php
487 }
488
489
490 function vwo_clhf_render_field($field) {
491 $isCheckbox = $field['type'] === 'checkbox';
492 $value = get_option($field['id'], isset($field['default']) ? $field['default'] : '');
493
494 echo '<div class="' . esc_attr(isset($field['class'])?$field['class']:"") . '">';
495
496 $label = '<label class="form-label" for="' . esc_attr($field['id']) . '">' . esc_html($field['label']) . '</label>';
497
498 switch ($field['type']) {
499 case 'text':
500 case 'number':
501 echo $label;
502 echo '<input type="' . esc_attr($field['type']) . '" id="' . esc_attr($field['id']) . '" name="' . esc_attr($field['id']) . '" value="' . esc_attr($value) . '"';
503 if (isset($field['min'])) echo ' min="' . esc_attr($field['min']) . '"';
504 echo ' class="form-input" />';
505 if (isset($field['suffix'])) echo ' ' . esc_html($field['suffix']);
506 break;
507 case 'radio':
508 echo $label;
509 foreach ($field['options'] as $options) {
510 echo '<div class="radio-container-wrapper">
511 <div class="radio-container">';
512 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> ';
513 echo '</div>';
514 echo '<p class="radio-sublabel">' . esc_html($options['sublabel']) . '</p>';
515 echo '</div>';
516 }
517 break;
518 case 'checkbox':
519 echo '<div class="checkbox-container">';
520 echo '<input type="checkbox" id="' . esc_attr($field['id']) . '" name="' . esc_attr($field['id']) . '" class="vwo-checkbox" value="1"' . checked($value, '1', false) . ' />';
521 echo '<label class="vwo-checkbox-label" for="' . esc_attr($field['id']) . '">Toggle</label>';
522 echo '<label class="form-label form-label--checkbox" for="' . esc_attr($field['id']) . '">' . esc_html($field['label']) . '</label>';
523 echo '</div>';
524 break;
525 }
526
527 if (isset($field['tooltip'])) {
528 echo '<p class="form-description ' . ($isCheckbox ? 'form-description--checkbox' : '') . '">' . esc_html($field['tooltip']) . '</p>';
529 }
530
531 echo '</div>';
532 }
533
534 function vwo_clhf_render_styles() {
535 ?>
536 <style>
537 input[type="radio"] {
538 margin: 0 !important;
539 }
540 input[type=radio]:checked::before {
541 background-color: #3858E9;
542 }
543 .vwo-admin-content {
544 background: #fff;
545 padding: 20px;
546 border: 1px solid #ccd0d4;
547 box-shadow: 0 1px 1px rgba(0,0,0,.04);
548 margin-top: 20px;
549 }
550 .vwo-admin-content .nav-tab,
551 .vwo-admin-content .nav-tab-active{
552 outline:none;
553 box-shadow: none;
554 }
555 .main-grid {
556 display: flex;
557 justify-content: space-between;
558 }
559 .main-grid__description {
560 background-color: #f9f9f9;
561 padding: 24px;
562 border-radius: 8px;
563 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
564 font-family: 'Segoe UI', sans-serif;
565 height: fit-content;max-width: 650px;
566 border: 1px solid #E0E0E0;
567 margin: 20px;
568 }
569 .main-grid__description h2 {
570 font-weight: 600;
571 margin-bottom: 10px;
572 margin-top: 0;
573 font-size: 20px;
574 color: #333;
575 }
576 .main-grid__description p {
577 font-size: 14px;
578 color: #757575;
579 line-height: 1.6;
580 margin-top: 21px;
581 margin-bottom: 0px;
582 }
583 .main-grid__description a {
584 color: #3858E9;
585 }
586 .form-container {
587 margin-top: 24px;
588 margin-bottom: 30px;
589 display: flex;
590 flex-direction: column;
591 gap: 28px;
592 flex: 1;
593 }
594 .form-label {
595 font-size: 12px;
596 color: #1E1E1E;
597 display: block;
598 margin-bottom: 10px;
599 font-weight: 500;
600 }
601 .form-label--checkbox {
602 cursor: pointer;
603 margin-bottom: 0;
604 }
605 .form-radio-label {
606 display: flex;
607 align-items: center;
608 gap: 10px;
609 margin-bottom: 10px;
610 cursor: pointer;
611 }
612 .form-radio-label:last-child {
613 margin-bottom: 0;
614 }
615 .form-description {
616 color: #757575;
617 margin-top: 10px;
618 margin-bottom: 0;
619 font-size: 12px;
620 }
621 .form-description--checkbox {
622 margin-top: 5px;
623 margin-left: 42px;
624 }
625 .form-input {
626 width: 100%;
627 max-width: 400px;
628 border: 1px solid #949494 !important;
629 border-radius: 2px !important;
630 }
631 .checkbox-container, .radio-container {
632 display: flex;
633 gap: 10px;
634 }
635 .radio-container-wrapper {
636 margin-bottom: 20px;
637 }
638 .radio-container-wrapper:last-child {
639 margin-bottom: 0;
640 }
641 .radio-sublabel {
642 font-size: 12px;
643 color: #757575;
644 margin-top: 5px;
645 margin-bottom: 0;
646 margin-left: 26px;
647 }
648 .checkbox-container .form-description {
649 width: 100%;
650 }
651 .async-option {
652 display: none;
653 }
654 .tab-pane {
655 display: none;
656 }
657 .tab-pane.active {
658 display: block;
659 }
660 .description {
661 max-width: 800px;
662 margin-bottom: 20px;
663 }
664
665 .woocommerce-row {
666 display: grid;
667 grid-template-columns: repeat(3, 1fr);
668 gap: 16px;
669 }
670 .woocommerce-row-item {
671 border: 1px solid rgba(0, 0, 0, 0.10);
672 border-radius: 8px;
673 }
674 .woocommerce-row-item-header {
675 display: flex;
676 justify-content: space-between;
677 align-items: center;
678 gap: 5px;
679 padding: 10px;
680 border-bottom: 1px solid rgba(0, 0, 0, 0.10);
681 }
682 .woocommerce-row-item-title {
683 margin: 0;
684 font-size: 13px;
685 font-weight: 500;
686 color: #1E1E1E;
687 }
688 .woocommerce-row-item-description {
689 margin: 0;
690 font-size: 12px;
691 color: #757575;
692 padding: 10px;
693 }
694 .woocommerce-row-item-description a {
695 color: #3858E9;
696 }
697 .woocommerce-main-header {
698 margin: 30px 0;
699 }
700 .woocommerce-row--disabled {
701 opacity: 0.4;
702 cursor: not-allowed;
703 pointer-events: none;
704 }
705 input[type=checkbox].vwo-checkbox{
706 height: 0;
707 width: 0;
708 visibility: hidden;
709 position: absolute;
710 clip: rect(1px,1px,1px,1px);
711 overflow: hidden;
712 }
713
714 label.vwo-checkbox-label {
715 box-sizing: border-box;
716 cursor: pointer;
717 text-indent: -9999px;
718 width: 32px;
719 height: 18px;
720 border: 1px solid #000;
721 background: #fff;
722 display: block;
723 border-radius: 100px;
724 position: relative;
725 }
726
727 label.vwo-checkbox-label:after {
728 content: '';
729 position: absolute;
730 top: 50%;
731 transform: translateY(-50%);
732 left: 2px;
733 width: 12px;
734 height: 12px;
735 background: #000;
736 border-radius: 90px;
737 transition: 0.3s;
738 }
739
740 input.vwo-checkbox:checked + label.vwo-checkbox-label {
741 background: #3858E9;
742 border-color: #3858E9;
743 }
744
745 input.vwo-checkbox:checked + label.vwo-checkbox-label:after {
746 left: calc(100% - 2px);
747 transform: translateX(-100%) translateY(-50%);
748 background-color: #fff;
749 }
750
751 </style>
752 <?php
753 }
754
755 function vwo_clhf_render_scripts() {
756 ?>
757 <script>
758 jQuery(document).ready(function($) {
759 function toggleAsyncOptions() {
760 var isAsync = $('input[name="code_type"]:checked').val() === 'ASYNC';
761 $('.async-option').toggle(isAsync);
762 }
763 function toggleWooCommerceOptions() {
764 var isWooCommerce = $('input[name="enable_woocommerce_event_tracking"]:checked');
765
766 if(isWooCommerce.length > 0) {
767 $('.woocommerce-row').removeClass('woocommerce-row--disabled');
768 $('.vwo_server_side_tracking').removeClass('woocommerce-row--disabled');
769
770 } else {
771 $('.woocommerce-row').addClass('woocommerce-row--disabled');
772 $('.vwo_server_side_tracking').addClass('woocommerce-row--disabled');
773 }
774 }
775
776 $('input[name="enable_woocommerce_event_tracking"]').change(toggleWooCommerceOptions);
777 $("label[for='enable_woocommerce_event_tracking']").click(toggleWooCommerceOptions);
778 toggleWooCommerceOptions(); // Run on page load
779
780 $('input[name="code_type"]').change(toggleAsyncOptions);
781 toggleAsyncOptions(); // Run on page load
782
783 // Handle tab switching
784 $('.nav-tab-wrapper .nav-tab').on('click', function(e) {
785 e.preventDefault();
786 var targetTab = $(this).attr('href');
787
788 // Update active tab
789 $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active');
790 $(this).addClass('nav-tab-active');
791
792 // Show target tab content
793 $('.tab-pane').removeClass('active').hide();
794 $(targetTab).addClass('active').show();
795 });
796
797 // Ensure the first tab is visible on page load
798 $('#tab-general').show();
799 });
800 </script>
801 <?php
802 }
803
804 function vwo_clhf_enqueue_admin_scripts($hook) {
805 if ('settings_page_clhf_vwo_options' !== $hook) {
806 return;
807 }
808 wp_enqueue_style('wp-admin');
809 }
810 add_action('admin_enqueue_scripts', 'vwo_clhf_enqueue_admin_scripts');
811
812 /**
813 * Displays a warning message if VWO settings are not configured.
814 * 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
815 * the VWO ID option is not set, it displays a warning message.
816 *
817 * @throws Exception Description of exception.
818 * @return void
819 */
820 function vwo_clhf_warn_nosettings() {
821 if ( ! is_admin() ) {
822 return;
823 }
824
825 $clhf_option = get_option( 'vwo_id' );
826 if ( ! $clhf_option || $clhf_option < 1 ) {
827 echo "<div id='vwo-warning' class='updated fade'><p><strong>Wingify 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>";
828 }
829 }
830
831
832 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'vwo_clhf_add_plugin_page_settings_link' );
833
834 /**
835 * Function to add Settings Links on Plugin page
836 *
837 * @param array $links Array of links.
838 * @return array
839 */
840 function vwo_clhf_add_plugin_page_settings_link( $links ) {
841 $links[] = '<a href="' .
842 admin_url( 'options-general.php?page=clhf_vwo_options' ) .
843 '">' . __( 'Settings' ) . '</a>';
844 return $links;
845 }
846
847 /**
848 * Disables VWO in Divi Builder.
849 *
850 * @throws Exception Description of exception.
851 * @return void
852 */
853 function disable_vwo_in_divi_builder() {
854 if ( has_action( 'wp_head', 'vwo_clhf_headercode' ) && function_exists( 'et_core_is_fb_enabled' ) && et_core_is_fb_enabled() ) {
855 remove_action( 'wp_head', 'vwo_clhf_headercode', 1 );
856 }
857 }
858
859 add_action( 'wp_head', 'disable_vwo_in_divi_builder', 0 );
860
861 // Add this new function to validate settings
862 function vwo_clhf_validate_settings() {
863 $has_errors = false;
864
865 // Validate VWO Account ID
866 $vwo_id = get_option('vwo_id');
867 if (empty($vwo_id) || !is_numeric($vwo_id)) {
868 add_settings_error('vwo_clhf_options', 'vwo_id', 'Please enter a valid Wingify Account ID.', 'error');
869 $has_errors = true;
870 }
871
872 // Add more validation for other fields as needed
873
874 return $has_errors;
875 }
876
877 /**
878 * Whether the configured account is a Wingify account.
879 *
880 * @return bool
881 */
882 function vwo_clhf_is_wingify_account() {
883 return '1' === get_option( 'is_wingify_account' );
884 }
885
886 /**
887 * Fetch account info from VWO API and save collUrl and is_wingify_account options.
888 *
889 * @param int|string $vwo_id VWO Account ID.
890 * @return string Collection URL if available, empty string otherwise.
891 */
892 function vwo_clhf_fetch_and_save_account_info( $vwo_id ) {
893 $coll_url = '';
894
895 if ( empty( $vwo_id ) || ! is_numeric( $vwo_id ) ) {
896 return $coll_url;
897 }
898
899 $api_url = 'https://edge.wingify.net/accInfo?a=' . $vwo_id;
900 $response = wp_remote_get(
901 $api_url,
902 array(
903 'timeout' => 15,
904 'sslverify' => false,
905 'headers' => array(
906 'Accept-Encoding' => 'gzip, deflate, br',
907 'User-Agent' => 'vwo-woocommerce-plugin',
908 ),
909 )
910 );
911
912 if ( is_wp_error( $response ) ) {
913 return $coll_url;
914 }
915
916 $body = wp_remote_retrieve_body( $response );
917 if ( empty( $body ) ) {
918 return $coll_url;
919 }
920
921 $data = json_decode( $body, true );
922
923 if ( ! is_array( $data ) ) {
924 return $coll_url;
925 }
926
927 if ( ! empty( $data['collUrl'] ) ) {
928 $coll_url = $data['collUrl'];
929 update_option( 'vwo_coll_url', sanitize_text_field( $data['collUrl'] ) );
930 }
931
932 if ( isset( $data['wd'] ) && $data['wd'] ) {
933 update_option( 'is_wingify_account', '1' );
934 } else {
935 update_option( 'is_wingify_account', '' );
936 }
937
938 return $coll_url;
939 }
940
941 // Add this new function to sanitize and validate settings
942 function vwo_clhf_sanitize_settings($input) {
943 // Sanitize and validate VWO Account ID
944 $vwo_id = sanitize_text_field($input);
945 if (empty($vwo_id) || !is_numeric($vwo_id)) {
946 add_settings_error('vwo_clhf_options', 'vwo_id', 'Please enter a valid Wingify Account ID.', 'error');
947 }
948
949 // Add more sanitization and validation for other fields as needed
950 // Check if vwo_id is changed
951 $current_vwo_id = get_option('vwo_id');
952 if ($current_vwo_id !== $vwo_id) {
953 update_option( 'vwo_coll_url', '' );
954 delete_option( 'is_wingify_account' );
955 vwo_clhf_fetch_and_save_account_info( $vwo_id );
956 }
957 return $vwo_id;
958 }
959
960 function enqueue_jquery_script() {
961 wp_enqueue_script('jquery');
962 }
963 add_action('wp_enqueue_scripts', 'enqueue_jquery_script');
964
965 if (file_exists(plugin_dir_path(__FILE__) . 'woocommerce-events.php')) {
966 include_once plugin_dir_path(__FILE__) . 'woocommerce-events.php';
967 }
968
969
970 ?>