diff --git a/assets/src/js/admin/main.js b/assets/src/js/admin/main.js index 2c96ae6e..e1f81155 100644 --- a/assets/src/js/admin/main.js +++ b/assets/src/js/admin/main.js @@ -79,19 +79,6 @@ document.addEventListener('DOMContentLoaded', () => { this.showMessages(); }, - toggleSection: function (target) { - let section = document.getElementById(target + '_content'); - let chevron = document.getElementById(target + '_chevron'); - - if (section.className.indexOf('hidden') !== -1) { - section.className = 'block'; - chevron.classList.add('rotate-180'); - } else { - section.className = 'hidden'; - chevron.classList.remove('rotate-180'); - } - }, - /** * Toggle Option and store in DB. * @@ -132,6 +119,10 @@ document.addEventListener('DOMContentLoaded', () => { toggleStatus = 'on'; } + if (button.dataset.addtlOpts === '1') { + plausible.toggleSection(button.value.replace('-', '_')); + } + const form = new FormData(); form.append('action', 'plausible_analytics_toggle_option'); form.append('option_name', button.name); @@ -150,6 +141,91 @@ document.addEventListener('DOMContentLoaded', () => { plausible.maybeDisableOptions(data.capabilities); }, + /** + * Adds an input node. + * + * @param target + */ + addField: function (target) { + let clone = document.getElementsByClassName(target.replace('_', '-') + '-field')[0].cloneNode(true); + let rows = document.getElementsByClassName(target.replace('_', '-') + '-field'); + let current_row = rows.length; + let input = clone.querySelector('input'); + let trash = clone.querySelector('a'); + + input.value = ''; + input.setAttribute('id', target + '[' + current_row + ']'); + input.setAttribute('name', target + '[' + current_row + ']'); + trash.setAttribute('onclick', 'plausibleRemoveField("' + target + '[' + current_row + ']")'); + trash.classList.remove('hidden'); + + document.getElementById(target + '_list').appendChild(clone); + }, + + /** + * Removes an input node. + * + * @param target + */ + removeField: function (target) { + let rowClass = target.replace(/\[[0-9]+]/, '').replace('_', '-'); + let rows = document.getElementsByClassName(rowClass + '-field'); + let input = document.getElementById(target); + let listItem = input.closest('.' + rowClass + '-field'); + + listItem.remove(); + + plausible.resetListItems(rows, target.replace(/\[[0-9]+]/, '')); + }, + + /** + * Make sure all items in a list have properly incremented id, name and onclick attributes. + * + * @param listItems + * @param list + */ + resetListItems: function (listItems, list) { + if (listItems === null || listItems === undefined || listItems.length === 0) { + return; + } + + for (let i = 0; i < listItems.length; i++) { + let item = listItems[i]; + let input = item.querySelector('input'); + let trash = item.querySelector('a'); + + input.setAttribute('id', list + '[' + i + ']'); + input.setAttribute('name', list + '[' + i + ']'); + trash.setAttribute('onclick', 'plausibleRemoveField("' + list + '[' + i + ']")'); + } + }, + + /** + * Toggles a collapsable section and rotates a chevron if it exists. + * + * @param target + */ + toggleSection: function (target) { + let section = document.getElementById(target + '_content'); + let chevron = document.getElementById(target + '_chevron'); + + if (section.className.indexOf('hidden') !== -1) { + section.classList.add('block'); + section.classList.remove('hidden'); + + if (chevron !== null) { + chevron.classList.add('rotate-180'); + } + } else { + section.classList.add('hidden'); + section.classList.remove('block'); + + if (chevron !== null) { + chevron.classList.remove('rotate-180'); + } + } + }, + /** * Save value of input or text area to DB. * @@ -160,7 +236,7 @@ document.addEventListener('DOMContentLoaded', () => { const section = button.closest('.plausible-analytics-section'); const inputs = section.querySelectorAll('input, textarea'); const form = new FormData(); - const options = []; + let options = []; inputs.forEach(function (input) { input = plausible.validateInput(input); @@ -577,6 +653,8 @@ document.addEventListener('DOMContentLoaded', () => { } plausibleToggleSection = plausible.toggleSection; + plausibleAddField = plausible.addField; + plausibleRemoveField = plausible.removeField; plausible.init(); }); diff --git a/assets/src/js/admin/main.min.js b/assets/src/js/admin/main.min.js index d67c74f4..b57714ba 100644 --- a/assets/src/js/admin/main.min.js +++ b/assets/src/js/admin/main.min.js @@ -1 +1 @@ -document.addEventListener("DOMContentLoaded",()=>{if(!document.location.href.includes("plausible_analytics")){return}let plausible={nonceElem:document.getElementById("_wpnonce"),nonce:"",showWizardElem:document.getElementById("show_wizard"),domainNameElem:document.getElementById("domain_name"),apiTokenElem:document.getElementById("api_token"),createAPITokenElems:document.getElementsByClassName("plausible-create-api-token"),buttonElems:document.getElementsByClassName("plausible-analytics-button"),stepElems:document.getElementsByClassName("plausible-analytics-wizard-next-step"),init:function(){if(document.location.hash===""&&document.getElementById("plausible-analytics-wizard")!==null){document.location.hash="#welcome_slide"}if(this.nonceElem!==null){this.nonce=this.nonceElem.value}this.toggleWizardStep();window.addEventListener("hashchange",this.toggleWizardStep);if(this.showWizardElem!==null){this.showWizardElem.addEventListener("click",this.showWizard)}if(this.domainNameElem!==null){this.domainNameElem.addEventListener("keyup",this.disableConnectButton)}if(this.apiTokenElem!==null){this.apiTokenElem.addEventListener("keyup",this.disableConnectButton)}if(this.createAPITokenElems.length>0){for(let i=0;i0){for(let i=0;i0){for(let i=0;i0){button.children[0].classList.remove("hidden")}button.setAttribute("disabled","disabled");plausible.ajax(form,button)},maybeDisableOptions:function(capabilities){let options=document.querySelectorAll("button[data-caps]");options.forEach(function(option){let caps=option.dataset.caps.split(",");let disable=false;caps.forEach(function(cap){if(capabilities[cap]===false){disable=true}});if(disable===true){if(option.dataset.status==="on"){option.dispatchEvent(new Event("click",{bubbles:true}))}}})},validateInput:function(input){if(input.name==="domain_name"&&input.value.match(/^(https?:\/\/)?(www.)?/).length>0){input.value=input.value.replace(/^(https?:\/\/)?(www.)?/,"")}return input},saveOptionOnNext:function(e){let hash=document.location.hash.replace("#","");if(hash!=="api_token_slide"&&hash!=="domain_name_slide"){return}let form=e.target.closest(".plausible-analytics-wizard-step-section");let inputs=form.getElementsByTagName("INPUT");let options=[];for(let input of inputs){input=plausible.validateInput(input);options.push({name:input.name,value:input.value})}let data=new FormData;data.append("action","plausible_analytics_save_options");data.append("options",JSON.stringify(options));data.append("_nonce",plausible.nonce);plausible.ajax(data).then(response=>{if(hash==="api_token_slide"&&response.success===true){let stats_button=document.getElementById("enable_analytics_dashboard_view_stats_in_wordpress");stats_button.removeAttribute("disabled")}})},disableConnectButton:function(e){let target=e.target;let button=document.getElementById("connect_plausible_analytics");let buttonIsHref=false;if(button===null){let slide_id=document.location.hash;button=document.querySelector(slide_id+" .plausible-analytics-wizard-next-step");buttonIsHref=true}if(button===null){return}if(target.value!==""){if(!buttonIsHref){button.disabled=false}else{button.classList.remove("pointer-events-none");button.classList.replace("bg-gray-200","bg-indigo-600")}return}if(!buttonIsHref){button.disabled=true;button.innerHTML=button.innerHTML.replace("Connected","Connect")}else{button.classList+=" pointer-events-none";button.classList.replace("bg-indigo-600","bg-gray-200")}},createAPIToken:function(e){e.preventDefault();let domain=document.getElementById("domain_name").value;domain=domain.replaceAll("/","%2F");window.open(`${plausible_analytics_hosted_domain}/${domain}/settings/integrations?new_token=WordPress`,"_blank","location=yes,height=768,width=1024,scrollbars=yes,status=no")},showWizard:function(e){let data=new FormData;data.append("action","plausible_analytics_show_wizard");data.append("_nonce",e.target.dataset.nonce);plausible.ajax(data)},toggleWizardStep:function(){if(document.getElementById("plausible-analytics-wizard")===null){return}const hash=document.location.hash.substring(1).replace("_slide","");let allSteps=document.querySelectorAll(".plausible-analytics-wizard-step");let activeSteps=document.querySelectorAll(".plausible-analytics-wizard-active-step");let completedSteps=document.querySelectorAll(".plausible-analytics-wizard-completed-step");for(let i=0;in);if(currentlyCompletedSteps.length<1){return}currentlyCompletedSteps.forEach(function(step){let completedStep=document.getElementById("completed-step-"+step);let inactiveStep=document.getElementById("step-"+step);completedStep.classList.remove("hidden");inactiveStep.classList+=" hidden"})},ajax:function(data,button=null,showMessages=true){return fetch(ajaxurl,{method:"POST",body:data}).then(response=>{if(button){if(button.children.length>0){button.children[0].classList+=" hidden"}if(button.id==="connect_plausible_analytics"&&response.status===200){button.innerText=plausible_analytics_i18n.connected}else{button.removeAttribute("disabled")}}if(response.status===200||response.status===402){return response.json()}return false}).then(response=>{if(showMessages===true){plausible.showMessages()}let event=new CustomEvent("plausibleAjaxDone",{detail:response});document.dispatchEvent(event);if(response.data!==undefined){return response.data}else{return response}})},showMessages:function(){let messages=plausible.fetchMessages();messages.then(function(messages){if(messages.error!==false){plausible.showMessage(messages.error,"error")}else if(messages.notice!==false){plausible.showMessage(messages.notice,"notice")}else if(messages.success!==false){plausible.showMessage(messages.success,"success")}if(messages.additional.length===0||document.getElementById("plausible-analytics-wizard")!==null){return}if(messages.additional.id!==undefined&&messages.additional.message){plausible.showAdditionalMessage(messages.additional.message,messages.additional.id)}else if(messages.additional.id!==undefined&&messages.additional.message===""){plausible.removeAdditionalMessage(messages.additional.id)}})},fetchMessages:function(){let data=new FormData;data.append("action","plausible_analytics_messages");let result=plausible.ajax(data,null,false);return result.then(function(response){return response})},showMessage:function(message,type="success"){if(type==="error"){document.getElementById("icon-error").classList.remove("hidden");document.getElementById("icon-success").classList.add("hidden");document.getElementById("icon-notice").classList.add("hidden")}else if(type==="notice"){document.getElementById("icon-notice").classList.remove("hidden");document.getElementById("icon-error").classList.add("hidden");document.getElementById("icon-success").classList.add("hidden")}else{document.getElementById("icon-success").classList.remove("hidden");document.getElementById("icon-error").classList.add("hidden");document.getElementById("icon-notice").classList.add("hidden")}let notice=document.getElementById("plausible-analytics-notice");document.getElementById("plausible-analytics-notice-text").innerHTML=message;notice.classList.remove("hidden");setTimeout(function(){notice.classList.replace("opacity-0","opacity-100")},200);if(type!=="error"){setTimeout(function(){notice.classList.replace("opacity-100","opacity-0");setTimeout(function(){notice.classList+=" hidden"},200)},2e3)}},showAdditionalMessage:function(html,target){let targetElem=document.querySelector(`[name='${target}']`);let container=targetElem.closest(".plausible-analytics-group");if(container.children.length>0){for(let i=0;i0){for(let i=0;i{if(!document.location.href.includes("plausible_analytics")){return}let plausible={nonceElem:document.getElementById("_wpnonce"),nonce:"",showWizardElem:document.getElementById("show_wizard"),domainNameElem:document.getElementById("domain_name"),apiTokenElem:document.getElementById("api_token"),createAPITokenElems:document.getElementsByClassName("plausible-create-api-token"),buttonElems:document.getElementsByClassName("plausible-analytics-button"),stepElems:document.getElementsByClassName("plausible-analytics-wizard-next-step"),init:function(){if(document.location.hash===""&&document.getElementById("plausible-analytics-wizard")!==null){document.location.hash="#welcome_slide"}if(this.nonceElem!==null){this.nonce=this.nonceElem.value}this.toggleWizardStep();window.addEventListener("hashchange",this.toggleWizardStep);if(this.showWizardElem!==null){this.showWizardElem.addEventListener("click",this.showWizard)}if(this.domainNameElem!==null){this.domainNameElem.addEventListener("keyup",this.disableConnectButton)}if(this.apiTokenElem!==null){this.apiTokenElem.addEventListener("keyup",this.disableConnectButton)}if(this.createAPITokenElems.length>0){for(let i=0;i0){for(let i=0;i0){for(let i=0;i0){button.children[0].classList.remove("hidden")}button.setAttribute("disabled","disabled");plausible.ajax(form,button)},maybeDisableOptions:function(capabilities){let options=document.querySelectorAll("button[data-caps]");options.forEach(function(option){let caps=option.dataset.caps.split(",");let disable=false;caps.forEach(function(cap){if(capabilities[cap]===false){disable=true}});if(disable===true){if(option.dataset.status==="on"){option.dispatchEvent(new Event("click",{bubbles:true}))}}})},validateInput:function(input){if(input.name==="domain_name"&&input.value.match(/^(https?:\/\/)?(www.)?/).length>0){input.value=input.value.replace(/^(https?:\/\/)?(www.)?/,"")}return input},saveOptionOnNext:function(e){let hash=document.location.hash.replace("#","");if(hash!=="api_token_slide"&&hash!=="domain_name_slide"){return}let form=e.target.closest(".plausible-analytics-wizard-step-section");let inputs=form.getElementsByTagName("INPUT");let options=[];for(let input of inputs){input=plausible.validateInput(input);options.push({name:input.name,value:input.value})}let data=new FormData;data.append("action","plausible_analytics_save_options");data.append("options",JSON.stringify(options));data.append("_nonce",plausible.nonce);plausible.ajax(data).then(response=>{if(hash==="api_token_slide"&&response.success===true){let stats_button=document.getElementById("enable_analytics_dashboard_view_stats_in_wordpress");stats_button.removeAttribute("disabled")}})},disableConnectButton:function(e){let target=e.target;let button=document.getElementById("connect_plausible_analytics");let buttonIsHref=false;if(button===null){let slide_id=document.location.hash;button=document.querySelector(slide_id+" .plausible-analytics-wizard-next-step");buttonIsHref=true}if(button===null){return}if(target.value!==""){if(!buttonIsHref){button.disabled=false}else{button.classList.remove("pointer-events-none");button.classList.replace("bg-gray-200","bg-indigo-600")}return}if(!buttonIsHref){button.disabled=true;button.innerHTML=button.innerHTML.replace("Connected","Connect")}else{button.classList+=" pointer-events-none";button.classList.replace("bg-indigo-600","bg-gray-200")}},createAPIToken:function(e){e.preventDefault();let domain=document.getElementById("domain_name").value;domain=domain.replaceAll("/","%2F");window.open(`${plausible_analytics_hosted_domain}/${domain}/settings/integrations?new_token=WordPress`,"_blank","location=yes,height=768,width=1024,scrollbars=yes,status=no")},showWizard:function(e){let data=new FormData;data.append("action","plausible_analytics_show_wizard");data.append("_nonce",e.target.dataset.nonce);plausible.ajax(data)},toggleWizardStep:function(){if(document.getElementById("plausible-analytics-wizard")===null){return}const hash=document.location.hash.substring(1).replace("_slide","");let allSteps=document.querySelectorAll(".plausible-analytics-wizard-step");let activeSteps=document.querySelectorAll(".plausible-analytics-wizard-active-step");let completedSteps=document.querySelectorAll(".plausible-analytics-wizard-completed-step");for(let i=0;in);if(currentlyCompletedSteps.length<1){return}currentlyCompletedSteps.forEach(function(step){let completedStep=document.getElementById("completed-step-"+step);let inactiveStep=document.getElementById("step-"+step);completedStep.classList.remove("hidden");inactiveStep.classList+=" hidden"})},ajax:function(data,button=null,showMessages=true){return fetch(ajaxurl,{method:"POST",body:data}).then(response=>{if(button){if(button.children.length>0){button.children[0].classList+=" hidden"}if(button.id==="connect_plausible_analytics"&&response.status===200){button.innerText=plausible_analytics_i18n.connected}else{button.removeAttribute("disabled")}}if(response.status===200||response.status===402){return response.json()}return false}).then(response=>{if(showMessages===true){plausible.showMessages()}let event=new CustomEvent("plausibleAjaxDone",{detail:response});document.dispatchEvent(event);if(response.data!==undefined){return response.data}else{return response}})},showMessages:function(){let messages=plausible.fetchMessages();messages.then(function(messages){if(messages.error!==false){plausible.showMessage(messages.error,"error")}else if(messages.notice!==false){plausible.showMessage(messages.notice,"notice")}else if(messages.success!==false){plausible.showMessage(messages.success,"success")}if(messages.additional.length===0||document.getElementById("plausible-analytics-wizard")!==null){return}if(messages.additional.id!==undefined&&messages.additional.message){plausible.showAdditionalMessage(messages.additional.message,messages.additional.id)}else if(messages.additional.id!==undefined&&messages.additional.message===""){plausible.removeAdditionalMessage(messages.additional.id)}})},fetchMessages:function(){let data=new FormData;data.append("action","plausible_analytics_messages");let result=plausible.ajax(data,null,false);return result.then(function(response){return response})},showMessage:function(message,type="success"){if(type==="error"){document.getElementById("icon-error").classList.remove("hidden");document.getElementById("icon-success").classList.add("hidden");document.getElementById("icon-notice").classList.add("hidden")}else if(type==="notice"){document.getElementById("icon-notice").classList.remove("hidden");document.getElementById("icon-error").classList.add("hidden");document.getElementById("icon-success").classList.add("hidden")}else{document.getElementById("icon-success").classList.remove("hidden");document.getElementById("icon-error").classList.add("hidden");document.getElementById("icon-notice").classList.add("hidden")}let notice=document.getElementById("plausible-analytics-notice");document.getElementById("plausible-analytics-notice-text").innerHTML=message;notice.classList.remove("hidden");setTimeout(function(){notice.classList.replace("opacity-0","opacity-100")},200);if(type!=="error"){setTimeout(function(){notice.classList.replace("opacity-100","opacity-0");setTimeout(function(){notice.classList+=" hidden"},200)},2e3)}},showAdditionalMessage:function(html,target){let targetElem=document.querySelector(`[name='${target}']`);let container=targetElem.closest(".plausible-analytics-group");if(container.children.length>0){for(let i=0;i0){for(let i=0;i { + plausibleLinksTracking.bindEvents(); + }, + + /** + * Bind Events. + */ + bindEvents: () => { + document.addEventListener('click', plausibleLinksTracking.handleLinkClick); + document.addEventListener('auxclick', plausibleLinksTracking.handleLinkClick); + }, + + /** + * Handle Link Clicks. + * + * @param e + */ + handleLinkClick: (e) => { + if (e.type === 'auxclick' && e.button !== plausibleLinksTracking.middleMouseButton) { + return; + } + + var link = plausibleLinksTracking.getLinkEl(e.target); + + if (link && plausibleLinksTracking.shouldTrackLink(link)) { + var eventName = 'Cloaked Link: Click'; + var eventProps = {url: link.href}; + + return plausibleLinksTracking.sendLinkClickEvent(e, link, eventName, eventProps); + } + }, + + /** + * Retrieves a link element from an event target. + * + * @param link + * + * @returns {{href}|*} + */ + getLinkEl: (link) => { + while (link && (typeof link.tagName === 'undefined' || link.tagName.toLowerCase() !== 'a' || !link.href)) { + link = link.parentNode; + } + + return link; + }, + + /** + * Should we track this link? + * + * @param link + * @returns {boolean} + */ + shouldTrackLink: (link) => { + let affiliateLinks = plausibleAffiliateLinks; + + let foundMatch = affiliateLinks.filter((affiliateLink) => { + return link.href.match(affiliateLink); + }); + + return foundMatch.length > 0; + }, + + /** + * Sends the click event to the Plausible API. + * + * @param event + * @param link + * @param eventName + * @param eventProps + */ + sendLinkClickEvent: (event, link, eventName, eventProps) => { + var followedLink = false; + + function followLink() { + if (!followedLink) { + followedLink = true; + window.location = link.href; + } + } + + if (plausibleLinksTracking.shouldFollowLink(event, link)) { + plausible(eventName, {props: eventProps, callback: followLink}); + setTimeout(followLink, 5000); + event.preventDefault(); + } else { + plausible(eventName, {props: eventProps}); + } + }, + + /** + * + * @param event + * @param link + * @returns {*|boolean} + */ + shouldFollowLink: (event, link) => { + // If default has been prevented by an external script, Plausible should not intercept navigation. + if (event.defaultPrevented) { + return false; + } + + var targetsCurrentWindow = !link.target || link.target.match(/^_(self|parent|top)$/i); + var isRegularClick = !(event.ctrlKey || event.metaKey || event.shiftKey) && event.type === 'click'; + + return targetsCurrentWindow && isRegularClick; + } +} + +plausibleLinksTracking.init(); diff --git a/languages/plausible-analytics.pot b/languages/plausible-analytics.pot index 1da8d6fe..5b9e64a3 100644 --- a/languages/plausible-analytics.pot +++ b/languages/plausible-analytics.pot @@ -1,4 +1,4 @@ -# Copyright (C) 2024 Plausible Analytics +# Copyright (C) 2025 Plausible Analytics # This file is distributed under the same license as the Plausible Analytics package. msgid "" msgstr "" @@ -7,7 +7,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language-Team: Plausible Analytics Team \n" -"POT-Creation-Date: 2024-08-08 18:11+0000\n" +"POT-Creation-Date: 2025-05-08 11:11+0000\n" "Report-Msgid-Bugs-To: https://github.com/plausible/wordpress/issues/new\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n" @@ -16,15 +16,15 @@ msgstr "" "X-Poedit-SourceCharset: UTF-8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/Actions.php:135 +#: src/Actions.php:168 msgid "View Analytics" msgstr "" -#: src/Actions.php:152 +#: src/Actions.php:180 msgid "View Page Analytics" msgstr "" -#: src/Actions.php:162, src/Admin/Filters.php:63, src/Admin/Settings/API.php:449 +#: src/Actions.php:195, src/Admin/Filters.php:63, src/Admin/Settings/API.php:462 msgid "Settings" msgstr "" @@ -32,59 +32,63 @@ msgstr "" msgid "Not allowed" msgstr "" -#: src/Ajax.php:161, src/Ajax.php:185, src/Ajax.php:273 +#: src/Ajax.php:161, src/Ajax.php:185, src/Ajax.php:275 msgid "Not allowed." msgstr "" -#: src/Ajax.php:217 +#: src/Ajax.php:219 msgid "enabled" msgstr "" -#: src/Ajax.php:217 +#: src/Ajax.php:219 msgid "disabled" msgstr "" -#: src/Ajax.php:281 +#: src/Ajax.php:283 msgid "No options found to save." msgstr "" -#: src/Ajax.php:302 +#: src/Ajax.php:333 msgid "Settings saved." msgstr "" -#: src/Ajax.php:325 +#: src/Ajax.php:356 msgid "Oops! The Plugin Token you used is invalid. Please create a new token. Read more" msgstr "" -#: src/Client.php:145 +#: src/Client.php:187 msgid "Something went wrong while creating Shared Link: %s" msgstr "" -#: src/Client.php:187 +#: src/Client.php:229 msgid "Something went wrong, try again later." msgstr "" -#: src/Client.php:231 +#: src/Client.php:275 msgid "Something went wrong while creating Custom Event Goal: %s" msgstr "" -#: src/Client.php:248 +#: src/Client.php:292 msgid "Something went wrong while creating Funnel: %s" msgstr "" -#: src/Client.php:265 +#: src/Client.php:309 msgid "Something went wrong while deleting a Custom Event Goal: %s" msgstr "" -#: src/Client.php:288 +#: src/Client.php:332 msgid "Something went wrong while enabling Pageview Properties: %s" msgstr "" -#: src/ClientFactory.php:49 +#: src/ClientFactory.php:57 msgid "cURL is not enabled on this server, which means API provisioning will not work. Please contact your hosting provider to enable the cURL module or allow_url_fopen." msgstr "" -#: src/Admin/Actions.php:54, src/Admin/Settings/Page.php:123 +#: src/Filters.php:137 +msgid "no" +msgstr "" + +#: src/Admin/Actions.php:54, src/Admin/Settings/Page.php:129 msgid "Connected" msgstr "" @@ -113,43 +117,59 @@ msgstr "" msgid "Plausible's proxy couldn't be enabled, because the WordPress API is inaccessible. This might be due to a conflicting setting in a (security) plugin or server firewall. Make sure you whitelist requests to the Proxy's endpoint: %1$s. Contact support if you need help locating the issue." msgstr "" -#: src/Admin/Provisioning.php:71 +#: src/Admin/Provisioning.php:88 msgid "404" msgstr "" -#: src/Admin/Provisioning.php:72 +#: src/Admin/Provisioning.php:89 msgid "Outbound Link: Click" msgstr "" -#: src/Admin/Provisioning.php:73 +#: src/Admin/Provisioning.php:90 msgid "File Download" msgstr "" -#: src/Admin/Provisioning.php:74 +#: src/Admin/Provisioning.php:91 msgid "WP Search Queries" msgstr "" -#: src/Admin/Provisioning.php:247 -msgid "Woo Purchase Funnel" +#: src/Admin/Provisioning.php:92, src/Integrations/FormSubmit.php:62, src/Integrations/FormSubmit.php:106 +msgid "WP Form Completions" +msgstr "" + +#: src/Integrations/EDD.php:36, src/Integrations/WooCommerce.php:39 +msgid "Visit %s*" msgstr "" -#: src/Integrations/WooCommerce.php:50 -msgid "Visit /product*" +#: src/Integrations/EDD.php:37 +msgid "EDD Add to Cart" msgstr "" -#: src/Integrations/WooCommerce.php:51 +#: src/Integrations/EDD.php:38 +msgid "EDD Remove from Cart" +msgstr "" + +#: src/Integrations/EDD.php:39 +msgid "EDD Start Checkout" +msgstr "" + +#: src/Integrations/EDD.php:40 +msgid "EDD Complete Purchase" +msgstr "" + +#: src/Integrations/WooCommerce.php:40 msgid "Woo Add to Cart" msgstr "" -#: src/Integrations/WooCommerce.php:52 +#: src/Integrations/WooCommerce.php:41 msgid "Woo Remove from Cart" msgstr "" -#: src/Integrations/WooCommerce.php:53 +#: src/Integrations/WooCommerce.php:42 msgid "Woo Start Checkout" msgstr "" -#: src/Integrations/WooCommerce.php:54 +#: src/Integrations/WooCommerce.php:43 msgid "Woo Complete Purchase" msgstr "" @@ -169,11 +189,11 @@ msgstr "" msgid "View the stats in your WP dashboard" msgstr "" -#: src/Admin/Settings/API.php:67, src/Admin/Settings/Page.php:134 +#: src/Admin/Settings/API.php:67, src/Admin/Settings/Page.php:137 msgid "Enhanced measurements" msgstr "" -#: src/Admin/Settings/API.php:68, src/Admin/Settings/Page.php:236 +#: src/Admin/Settings/API.php:68, src/Admin/Settings/Page.php:291 msgid "Enable proxy" msgstr "" @@ -209,42 +229,50 @@ msgstr "" msgid "

Congrats! Your traffic is now being counted without compromising the user experience and privacy of your visitors. You can now check out your intuitive, fast-loading and privacy-friendly dashboard.

Note that visits from logged in users aren't tracked. If you want to track visits for certain user roles, then please specify them in the plugin's settings.

Need help? Our documentation is the best place to find most answers right away.

Still haven't found the answer you're looking for? We're here to help. Please contact our support.

" msgstr "" -#: src/Admin/Settings/API.php:113 +#: src/Admin/Settings/API.php:111 msgid "

Congrats! Your traffic is now being counted without compromising the user experience and privacy of your visitors.

Note that visits from logged in users aren't tracked. If you want to track visits for certain user roles, then please specify them in the plugin's settings.

Need help? Our documentation is the best place to find most answers right away.

Still haven't found the answer you're looking for? We're here to help. Please contact our support.

" msgstr "" -#: src/Admin/Settings/API.php:198 +#: src/Admin/Settings/API.php:195 msgid "Plausible Analytics Getting Started Guide" msgstr "" -#: src/Admin/Settings/API.php:271 +#: src/Admin/Settings/API.php:275 msgid "Visit plugin settings" msgstr "" -#: src/Admin/Settings/API.php:250 +#: src/Admin/Settings/API.php:254 msgid "Next" msgstr "" -#: src/Admin/Settings/API.php:256 +#: src/Admin/Settings/API.php:260 msgid "Setup later" msgstr "" -#: src/Admin/Settings/API.php:263, src/Admin/Settings/API.php:454 +#: src/Admin/Settings/API.php:267, src/Admin/Settings/API.php:467 msgid "Community Edition" msgstr "" -#: src/Admin/Settings/API.php:512 +#: src/Admin/Settings/API.php:525 msgid "Getting Started Guide" msgstr "" -#: src/Admin/Settings/API.php:519 +#: src/Admin/Settings/API.php:532 msgid "Documentation" msgstr "" -#: src/Admin/Settings/API.php:525 +#: src/Admin/Settings/API.php:538 msgid "Contact Support" msgstr "" +#: src/Admin/Settings/API.php:642, src/Admin/Settings/Page.php:344, src/Admin/Settings/Page.php:416, src/Admin/Settings/Page.php:451 +msgid "Save" +msgstr "" + +#: src/Admin/Settings/API.php:644 +msgid "Add More" +msgstr "" + #: src/Admin/Settings/Hooks.php:59 msgid "Proxy disabled." msgstr "" @@ -277,195 +305,219 @@ msgstr "" msgid "Please create a Plugin Token and insert it into the Plugin Token field above to enable this option." msgstr "" -#: src/Admin/Settings/Page.php:91 +#: src/Admin/Settings/Page.php:97 msgid "Connect your website with Plausible Analytics" msgstr "" -#: src/Admin/Settings/Page.php:96 +#: src/Admin/Settings/Page.php:102 msgid "Ensure your domain name matches the one in your Plausible account, then create a Plugin Token (link opens in a new window) and paste it into the 'Plugin Token' field." msgstr "" -#: src/Admin/Settings/Page.php:106, src/Admin/Settings/Page.php:359 +#: src/Admin/Settings/Page.php:112, src/Admin/Settings/Page.php:408 msgid "Domain name" msgstr "" -#: src/Admin/Settings/Page.php:112 +#: src/Admin/Settings/Page.php:118 msgid "Plugin Token" msgstr "" -#: src/Admin/Settings/Page.php:115 +#: src/Admin/Settings/Page.php:121 msgid "Create Token" msgstr "" -#: src/Admin/Settings/Page.php:123 +#: src/Admin/Settings/Page.php:128 msgid "Connect" msgstr "" #. translators: %1$s replaced with outbound-links. -#: src/Admin/Settings/Page.php:138 +#: src/Admin/Settings/Page.php:141 msgid "Enable enhanced measurements that you'd like to track." msgstr "" -#: src/Admin/Settings/Page.php:144 +#: src/Admin/Settings/Page.php:147 msgid "404 error pages" msgstr "" -#: src/Admin/Settings/Page.php:151 +#: src/Admin/Settings/Page.php:155 +msgid "File downloads" +msgstr "" + +#: src/Admin/Settings/Page.php:163 msgid "Outbound links" msgstr "" -#: src/Admin/Settings/Page.php:158 -msgid "File downloads" +#: src/Admin/Settings/Page.php:171 +msgid "Authors and categories" msgstr "" -#: src/Admin/Settings/Page.php:165 -msgid "Search queries" +#: src/Admin/Settings/Page.php:179 +msgid "Cloaked affiliate links" msgstr "" -#: src/Admin/Settings/Page.php:172 -msgid "Custom events" +#: src/Admin/Settings/Page.php:190 +msgid "Enter the (partial) URLs you want to track (e.g. enter /recommends/ if you want to track %s)" msgstr "" -#: src/Admin/Settings/Page.php:179 +#: src/Admin/Settings/Page.php:201 msgid "Ecommerce revenue" msgstr "" -#: src/Admin/Settings/Page.php:187 -msgid "Authors and categories" +#: src/Admin/Settings/Page.php:209 +msgid "Form completions" +msgstr "" + +#: src/Admin/Settings/Page.php:217 +msgid "Logged-in user status" msgstr "" -#: src/Admin/Settings/Page.php:194 +#: src/Admin/Settings/Page.php:225 +msgid "Search queries" +msgstr "" + +#: src/Admin/Settings/Page.php:233 +msgid "Advanced options" +msgstr "" + +#: src/Admin/Settings/Page.php:238 +msgid "Custom events" +msgstr "" + +#: src/Admin/Settings/Page.php:246 msgid "Hash-based routing" msgstr "" -#: src/Admin/Settings/Page.php:201 +#: src/Admin/Settings/Page.php:254 msgid "IE compatibility" msgstr "" -#: src/Admin/Settings/Page.php:210 +#: src/Admin/Settings/Page.php:266 msgid "Bypass ad blockers" msgstr "" -#: src/Admin/Settings/Page.php:215 +#: src/Admin/Settings/Page.php:271 msgid "Concerned about ad blockers? You can run the Plausible script as a first-party connection from your domain name to count visitors who use ad blockers. The proxy uses WordPress' API with a randomly generated endpoint, starting with %1$s and %2$s. Learn more »" msgstr "" -#: src/Admin/Settings/Page.php:245 +#: src/Admin/Settings/Page.php:300 msgid "View your stats in your WordPress dashboard" msgstr "" -#: src/Admin/Settings/Page.php:248 +#: src/Admin/Settings/Page.php:303 msgid "View your site statistics within your WordPress Dashboard." msgstr "" -#: src/Admin/Settings/Page.php:255 +#: src/Admin/Settings/Page.php:309 msgid "View stats in WordPress" msgstr "" -#: src/Admin/Settings/Page.php:264 +#: src/Admin/Settings/Page.php:318 msgid "Exclude specific pages from being tracked" msgstr "" -#: src/Admin/Settings/Page.php:269 +#: src/Admin/Settings/Page.php:323 msgid "Exclude certain pages from being tracked. You can use an asterisk (*) to match patterns in your page URLs." msgstr "" -#: src/Admin/Settings/Page.php:276 +#: src/Admin/Settings/Page.php:330 msgid "See syntax »" msgstr "" -#: src/Admin/Settings/Page.php:281 +#: src/Admin/Settings/Page.php:334 msgid "Excluded pages" msgstr "" -#: src/Admin/Settings/Page.php:285 +#: src/Admin/Settings/Page.php:338 msgid "E.g." msgstr "" -#: src/Admin/Settings/Page.php:291, src/Admin/Settings/Page.php:368, src/Admin/Settings/Page.php:405 -msgid "Save" -msgstr "" - -#: src/Admin/Settings/Page.php:298 +#: src/Admin/Settings/Page.php:351 msgid "Track analytics for user roles" msgstr "" -#: src/Admin/Settings/Page.php:301 +#: src/Admin/Settings/Page.php:354 msgid "By default, visits from logged in users aren't tracked. If you want to track visits for certain user roles then please specify them below." msgstr "" -#: src/Admin/Settings/Page.php:309 +#: src/Admin/Settings/Page.php:361 msgid "Show stats dashboard to additional user roles" msgstr "" -#: src/Admin/Settings/Page.php:312 +#: src/Admin/Settings/Page.php:364 msgid "By default, the stats dashboard is only available to logged in administrators. If you want the dashboard to be available for other logged in users, then please specify them below." msgstr "" -#: src/Admin/Settings/Page.php:320 +#: src/Admin/Settings/Page.php:371 msgid "Disable menu in toolbar" msgstr "" -#: src/Admin/Settings/Page.php:323 +#: src/Admin/Settings/Page.php:374 msgid "Check this option if you don't want the Plausible Analytics menu item to be added to the toolbar at the top of the screen." msgstr "" -#: src/Admin/Settings/Page.php:331 +#: src/Admin/Settings/Page.php:381 msgid "Disable toolbar menu" msgstr "" -#: src/Admin/Settings/Page.php:341 +#: src/Admin/Settings/Page.php:391 msgid "Plausible Community Edition" msgstr "" -#: src/Admin/Settings/Page.php:347 +#: src/Admin/Settings/Page.php:397 msgid "If you're using Plausible Community Edition on your own infrastructure, enter the domain name where you installed it to enable the integration with your self-hosted instance. Multisites can use the PLAUSIBLE_SELF_HOSTED_DOMAIN constant to define the URL for all subsites at once." msgstr "" -#: src/Admin/Settings/Page.php:354 +#: src/Admin/Settings/Page.php:404 msgid "Learn more about Plausible Community Edition." msgstr "" -#: src/Admin/Settings/Page.php:376 +#: src/Admin/Settings/Page.php:424 msgid "View stats in your WordPress dashboard" msgstr "" -#: src/Admin/Settings/Page.php:381 +#: src/Admin/Settings/Page.php:428 msgid "Create a secure and private shared link in your Plausible account." msgstr "" -#: src/Admin/Settings/Page.php:386 +#: src/Admin/Settings/Page.php:431 msgid "Paste the shared link in the text box to view your stats in your WordPress dashboard." msgstr "" -#: src/Admin/Settings/Page.php:393 +#: src/Admin/Settings/Page.php:439 msgid "Shared link" msgstr "" -#: src/Admin/Settings/Page.php:398 +#: src/Admin/Settings/Page.php:444 msgid "E.g. %s/share/%s?auth=XXXXXXXXXXXX" msgstr "" -#: src/Admin/Settings/Page.php:556, src/Admin/Settings/Page.php:557 +#: src/Admin/Settings/Page.php:598, src/Admin/Settings/Page.php:599 msgid "Analytics" msgstr "" -#: src/Admin/Settings/Page.php:569, src/Admin/Settings/Page.php:570 +#: src/Admin/Settings/Page.php:611, src/Admin/Settings/Page.php:612 msgid "Plausible Analytics" msgstr "" -#: src/Admin/Settings/Page.php:629 +#: src/Admin/Settings/Page.php:669 msgid "You don't have sufficient privileges to access the analytics dashboard. Please contact administrator of the website to grant you the access." msgstr "" -#: src/Admin/Settings/Page.php:710 +#: src/Admin/Settings/Page.php:747 msgid "Please click here to enable View Stats in WordPress." msgstr "" -#: src/Admin/Settings/Page.php:702 +#: src/Admin/Settings/Page.php:739 msgid "Please enter your Shared Link under Self-Hosted Settings." msgstr "" -#: src/Admin/Settings/Page.php:683 +#: src/Admin/Settings/Page.php:720 msgid "Plausible Analytics\' statistics couldn\'t be loaded. Please disable your ad blocker." msgstr "" + +#: src/Admin/Provisioning/Integrations/EDD.php:57 +msgid "EDD Purchase Funnel" +msgstr "" + +#: src/Admin/Provisioning/Integrations/WooCommerce.php:58 +msgid "Woo Purchase Funnel" +msgstr "" diff --git a/src/Actions.php b/src/Actions.php index 257f1ffe..3299a311 100644 --- a/src/Actions.php +++ b/src/Actions.php @@ -46,14 +46,11 @@ public function maybe_register_assets() { * Bail if tracked_user_roles is empty (which means no roles should be tracked) or, * if current role should not be tracked. */ - if ( ( ! empty( $user_role ) && ! isset( $settings[ 'tracked_user_roles' ] ) ) || - ( ! empty( $user_role ) && ! in_array( $user_role, $settings[ 'tracked_user_roles' ], true ) ) ) { + if ( ( ! empty( $user_role ) && ! isset( $settings[ 'tracked_user_roles' ] ) ) || ( ! empty( $user_role ) && ! in_array( $user_role, $settings[ 'tracked_user_roles' ], true ) ) ) { return; // @codeCoverageIgnore } - $version = - Helpers::proxy_enabled() && file_exists( Helpers::get_js_path() ) ? filemtime( Helpers::get_js_path() ) : - PLAUSIBLE_ANALYTICS_VERSION; + $version = Helpers::proxy_enabled() && file_exists( Helpers::get_js_path() ) ? filemtime( Helpers::get_js_path() ) : PLAUSIBLE_ANALYTICS_VERSION; wp_enqueue_script( 'plausible-analytics', @@ -69,6 +66,20 @@ public function maybe_register_assets() { 'window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }' ); + // Track Cloaked Affiliate Links (if enabled) + if ( Helpers::is_enhanced_measurement_enabled( 'affiliate-links' ) ) { + wp_enqueue_script( + 'plausible-affiliate-links', + PLAUSIBLE_ANALYTICS_PLUGIN_URL . 'assets/dist/js/plausible-affiliate-links.js', + [ 'plausible-analytics' ], + filemtime( PLAUSIBLE_ANALYTICS_PLUGIN_DIR . 'assets/dist/js/plausible-affiliate-links.js' ), + ); + + $affiliate_links = Helpers::get_settings()[ 'affiliate_links' ] ?? []; + + wp_add_inline_script( 'plausible-affiliate-links', 'const plausibleAffiliateLinks = ' . wp_json_encode( $affiliate_links ) . ';', 'before' ); + } + // Track 404 pages (if enabled) if ( Helpers::is_enhanced_measurement_enabled( '404' ) && is_404() ) { $data = wp_json_encode( @@ -131,13 +142,13 @@ public function admin_bar_node( $admin_bar ) { return; // @codeCoverageIgnore } - $settings = Helpers::get_settings(); + $settings = Helpers::get_settings(); $current_user = wp_get_current_user(); $has_access = false; $user_roles_have_access = array_merge( [ 'administrator' ], - $settings['expand_dashboard_access'] ?? [] + $settings[ 'expand_dashboard_access' ] ?? [] ); foreach ( $current_user->roles as $role ) { @@ -157,9 +168,7 @@ public function admin_bar_node( $admin_bar ) { 'title' => 'Plausible Analytics', ]; - - if ( ! empty( $settings[ 'enable_analytics_dashboard' ] ) || - ( ! empty( $settings[ 'self_hosted_domain' ] ) && ! empty( $settings[ 'self_hosted_shared_link' ] ) ) ) { + if ( ! empty( $settings[ 'enable_analytics_dashboard' ] ) || ( ! empty( $settings[ 'self_hosted_domain' ] ) && ! empty( $settings[ 'self_hosted_shared_link' ] ) ) ) { $args[] = [ 'id' => 'view-analytics', 'title' => esc_html__( 'View Analytics', 'plausible-analytics' ), diff --git a/src/Admin/Provisioning.php b/src/Admin/Provisioning.php index ff4a9fde..0569ec6a 100644 --- a/src/Admin/Provisioning.php +++ b/src/Admin/Provisioning.php @@ -86,10 +86,11 @@ public function __construct( $client = null ) { $this->custom_event_goals = [ '404' => __( '404', 'plausible-analytics' ), - 'outbound-links' => __( 'Outbound Link: Click', 'plausible-analytics' ), + 'affiliate-links' => __( 'Cloaked Link: Click', 'plausible-analytics' ), 'file-downloads' => __( 'File Download', 'plausible-analytics' ), - 'search' => __( 'WP Search Queries', 'plausible-analytics' ), 'form-completions' => __( 'WP Form Completions', 'plausible-analytics' ), + 'outbound-links' => __( 'Outbound Link: Click', 'plausible-analytics' ), + 'search' => __( 'WP Search Queries', 'plausible-analytics' ), ]; $this->init(); diff --git a/src/Admin/Settings/API.php b/src/Admin/Settings/API.php index 6c0dd82d..28580a47 100644 --- a/src/Admin/Settings/API.php +++ b/src/Admin/Settings/API.php @@ -610,6 +610,44 @@ function ( $field ) { return ob_get_clean(); } + /** + * Renders a clonable text field. + * + * @param array $group + * + * @return false|string + */ + public function render_clonable_text_field( array $group ) { + ob_start(); + $values = $group[ 'value' ] ?: [ 0 => '' ]; + $slug = $group[ 'slug' ] ?? ''; + ?> +
+
+
+
+
    + $value ) : ?> +
  1. + render_text_field( [ 'value' => $value, 'slug' => "{$slug}[$key]", 'classes' => 'flex-1' ] ); ?> + ')" class=" ml-2 cursor-pointer text-red-800 hover:text-red-500 dark:text-red-500 dark:hover:text-red-400"> + + +
  2. + +
+ render_button_field( [ 'slug' => 'save-' . $slug, 'label' => __( 'Save', 'plausible-analytics' ) ] ); ?> + +
+ -
- +
+ + +
-
- -
+
diff --git a/src/Admin/Settings/Page.php b/src/Admin/Settings/Page.php index 8d557cd7..4164b851 100644 --- a/src/Admin/Settings/Page.php +++ b/src/Admin/Settings/Page.php @@ -143,7 +143,7 @@ public function __construct() { 'plausible-analytics' ), 'fields' => [ - '404' => [ + '404' => [ 'label' => esc_html__( '404 error pages', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-404-error-pages', 'slug' => 'enhanced_measurements', @@ -151,7 +151,7 @@ public function __construct() { 'value' => '404', 'caps' => [ self::CAP_GOALS ], ], - 'file-downloads' => [ + 'file-downloads' => [ 'label' => esc_html__( 'File downloads', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-file-downloads', 'slug' => 'enhanced_measurements', @@ -159,7 +159,7 @@ public function __construct() { 'value' => 'file-downloads', 'caps' => [ self::CAP_GOALS ], ], - 'outbound-links' => [ + 'outbound-links' => [ 'label' => esc_html__( 'Outbound links', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-external-link-clicks', 'slug' => 'enhanced_measurements', @@ -167,7 +167,7 @@ public function __construct() { 'value' => 'outbound-links', 'caps' => [ self::CAP_GOALS ], ], - 'pageview-props' => [ + 'pageview-props' => [ 'label' => esc_html__( 'Authors and categories', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-send-custom-properties', 'slug' => 'enhanced_measurements', @@ -175,7 +175,29 @@ public function __construct() { 'value' => 'pageview-props', 'caps' => [ self::CAP_PROPS ], ], - 'revenue' => [ + 'affiliate-links' => [ + 'label' => esc_html__( 'Cloaked affiliate links', 'plausible-analytics' ), + 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-cloaked-affiliate-link-clicks', + 'slug' => 'enhanced_measurements', + 'type' => 'checkbox', + 'value' => 'affiliate-links', + 'addtl_opts' => true, + 'caps' => [ self::CAP_GOALS ], + ], + 'affiliate-links-patterns' => [ + 'slug' => 'affiliate_links', + 'description' => sprintf( + __( + 'Enter the (partial) URLs you want to track (e.g. enter /recommends/ if you want to track %s)', + 'plausible-analytics' + ), + get_home_url() . '/recommends/affiliate-product/' + ), + 'type' => 'clonable_text', + 'value' => Helpers::get_settings()[ 'affiliate_links' ] ?? [], + 'hidden' => ! Helpers::is_enhanced_measurement_enabled( 'affiliate-links' ), + ], + 'revenue' => [ 'label' => esc_html__( 'Ecommerce revenue', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-ecommerce-revenue', 'slug' => 'enhanced_measurements', @@ -183,7 +205,7 @@ public function __construct() { 'value' => 'revenue', 'caps' => [ self::CAP_GOALS, self::CAP_FUNNELS, self::CAP_PROPS, self::CAP_REVENUE ], ], - 'form-completions' => [ + 'form-completions' => [ 'label' => esc_html__( 'Form completions', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-form-completions', 'slug' => 'enhanced_measurements', @@ -191,7 +213,7 @@ public function __construct() { 'value' => 'form-completions', 'caps' => [ self::CAP_GOALS ], ], - 'user-logged-in' => [ + 'user-logged-in' => [ 'label' => esc_html__( 'Logged-in user status', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-track-logged-in-user-status', 'slug' => 'enhanced_measurements', @@ -199,7 +221,7 @@ public function __construct() { 'value' => 'user-logged-in', 'caps' => [ self::CAP_PROPS ], ], - 'search' => [ + 'search' => [ 'label' => esc_html__( 'Search queries', 'plausible-analytics' ), 'docs' => 'https://plausible.io/wordpress-analytics-plugin#how-to-enable-site-search-tracking', 'slug' => 'enhanced_measurements', @@ -207,7 +229,7 @@ public function __construct() { 'value' => 'search', 'caps' => [ self::CAP_GOALS ], ], - 'advanced-options' => [ + 'advanced-options' => [ 'label' => esc_html__( 'Advanced options', 'plausible-analytics' ), 'slug' => 'advanced_options', 'type' => 'toggle_group', diff --git a/src/Ajax.php b/src/Ajax.php index 2e059408..e9f2c5fe 100644 --- a/src/Ajax.php +++ b/src/Ajax.php @@ -267,7 +267,7 @@ private function maybe_render_additional_message( $option_name, $option_value ) * @throws ApiException */ public function save_options() { - // Sanitize all the post data before using. + // Sanitize all the post-data before using. $post_data = $this->clean( $_POST ); $settings = Helpers::get_settings(); @@ -285,11 +285,40 @@ public function save_options() { wp_send_json_error( null, 400 ); } + /** + * If we're dealing with an array of inputs (e.g. item[0], item[1], etc.), we need to convert $options , before storing it in the database. + * + * @since 2.4.0 + */ + $input_array_elements = array_filter( + $options, + function ( $option ) { + return preg_match( '/\[[0-9]+]/', $option->name ); + } + ); + + if ( count( $input_array_elements ) > 0 ) { + $options = []; + $array_name = preg_replace( '/\[[0-9]+]/', '', $input_array_elements[ 0 ]->name ); + $options[ 0 ] = (object) []; + $options[ 0 ]->name = $array_name; + + foreach ( $input_array_elements as $input_array_element ) { + if ( $input_array_element->value ) { + $options[ 0 ]->value[] = $input_array_element->value; + } + } + } + foreach ( $options as $option ) { // Clean spaces - $settings[ $option->name ] = trim( $option->value ); + if ( is_string( $option->value ) ) { + $settings[ $option->name ] = trim( $option->value ); + } else { + $settings[ $option->name ] = $option->value; + } - // Validate Plugin Token, if this is the Plugin Token field. + // Validate Plugin Token if this is the Plugin Token field. if ( $option->name === 'api_token' ) { $this->validate_api_token( $option->value ); diff --git a/src/Helpers.php b/src/Helpers.php index 39c176a3..9f7c80a5 100644 --- a/src/Helpers.php +++ b/src/Helpers.php @@ -60,9 +60,7 @@ public static function get_filename( $local = false ) { /** * Custom Events needs to be enabled, if Revenue Tracking is enabled and any of the available integrations are available. */ - if ( ! self::is_enhanced_measurement_enabled( 'tagged-events' ) && - self::is_enhanced_measurement_enabled( 'revenue' ) && - ( Integrations::is_wc_active() || Integrations::is_edd_active() ) ) { + if ( ! self::is_enhanced_measurement_enabled( 'tagged-events' ) && self::is_enhanced_measurement_enabled( 'revenue' ) && ( Integrations::is_wc_active() || Integrations::is_edd_active() ) ) { $file_name .= '.tagged-events'; } @@ -95,6 +93,7 @@ public static function get_settings() { 'domain_name' => '', 'api_token' => '', 'enhanced_measurements' => [], + 'affiliate-links' => [], 'proxy_enabled' => '', 'enable_analytics_dashboard' => '', 'shared_link' => '', diff --git a/webpack.config.js b/webpack.config.js index 585f156c..9a418057 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,6 +13,7 @@ const config = { mode, entry: { 'plausible-admin': ['./assets/src/css/admin/main.css', './assets/src/js/admin/main.js'], + 'plausible-affiliate-links': ['./assets/src/js/affiliate-links.js'], 'plausible-woocommerce-integration': ['./assets/src/js/integrations/woocommerce.js'], 'plausible-form-submit-integration': ['./assets/src/js/integrations/form-submit.js'] },