Plugin Directory

Changeset 3455489


Ignore:
Timestamp:
02/06/2026 03:12:49 PM (4 weeks ago)
Author:
dekode
Message:

releasing version 2.4.0

Location:
dekode-fundraising
Files:
20 edited
19 copied

Legend:

Unmodified
Added
Removed
  • dekode-fundraising/tags/2.4.0/CHANGELOG.txt

    r3422093 r3455489  
     1= 2.4.0 (2026-02-06) =
     2* Enhancement- Added support for the new conversion and tracking scripts.
     3* Enhancement- Asset build dependency updates.
     4* Bugfix- Reverted `@wordpress/scripts` to `27.9.0`, to keep compatibility with WP 6.4 and up.
     5
    16= 2.3.2 (2025-12-17) =
    27* Remove receipt link icon.
  • dekode-fundraising/tags/2.4.0/README.txt

    r3422093 r3455489  
    44Requires PHP: 8.1
    55Tested up to: 6.8
    6 Stable tag: 2.3.2
     6Stable tag: 2.4.0
    77License: GPLv3 or later
    88License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    4646== Changelog ==
    4747
     48= 2.4.0 (2026-02-06) =
     49* Enhancement- Added support for the new conversion and tracking scripts.
     50* Enhancement- Asset build dependency updates.
     51* Bugfix- Reverted `@wordpress/scripts` to `27.9.0`, to keep compatibility with WP 6.4 and up.
     52
    4853= 2.3.2 (2025-12-04) =
    4954* Remove receipt link icon.
  • dekode-fundraising/tags/2.4.0/build/blocks/donation-form/editor.asset.php

    r3422093 r3455489  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '59d96ee1fd27a6d10057');
     1<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '19dd39a6fe0bc754f01c');
  • dekode-fundraising/tags/2.4.0/build/blocks/donation-form/editor.js

    r3422093 r3455489  
    1 (()=>{"use strict";const e=window.wp.blocks,n=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}'),r=window.wp.blockEditor,o=window.wp.element,i=window.wp.components,t=window.wp.i18n,a=window.ReactJSXRuntime;(0,e.registerBlockType)(n,{edit:function({attributes:{formId:e,urlParams:n=[]},setAttributes:s}){var d,l;const[u,c]=(0,o.useReducer)((e,n)=>({...e,...n}),{isInitialized:!1,isLoaded:!1,apiToken:null!==(d=window.fundySettings.apiToken)&&void 0!==d?d:"",baseURL:null!==(l=window.fundySettings.baseURL)&&void 0!==l?l:"",forms:!1,error:null}),{isInitialized:p,isLoaded:m,apiToken:f,baseURL:h,forms:g,error:k}=u;if((0,o.useEffect)(()=>{!1===p&&f&&h&&c({isInitialized:!0})},[p,f,h]),(0,o.useEffect)(()=>{h&&f&&fetch(`${h}/api/v1/organization/forms`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:"Bearer "+f}}).then(e=>{if(!e.ok)throw new Error("Network response was not ok.");return e.json()}).then(n=>{const r=n.map(e=>({value:e.id,label:e.name}));c({isLoaded:!0,forms:r,error:null}),!e&&r.length&&s({formId:parseInt(r[0].value,10)})}).catch(e=>{c({error:"There has been a problem with your fetch operation: "+e})})},[h,f,e,s]),!f)return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsx)(i.Placeholder,{instructions:(0,t.__)("Please set an API Token on the plugin settings page.","dekode-fundraising")})});const w=g&&g.length>0,y=(e,r,o)=>{const i=n.map((n,i)=>i===e?{...n,[r]:o}:n);s({urlParams:i})};return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsxs)(i.Placeholder,{label:(0,t.__)("Dekode Fundraising Form","dekode-fundraising"),isColumnLayout:!0,children:[(0,a.jsx)(i.SelectControl,{label:(0,t.__)("Select a Form","dekode-fundraising"),value:e,className:"fundy-form",options:g||[{label:"",value:""}],onChange:e=>s({formId:parseInt(e,10)}),disabled:!m}),!w&&(0,a.jsx)("p",{children:(0,t.__)("No forms found. Please create a Form on your Dekode Fundraising account first.","dekode-fundraising")}),!m&&(0,a.jsx)("p",{children:(0,t.__)("Loading…","dekode-fundraising")}),k&&(0,a.jsx)("p",{children:"Error: "+k}),(0,a.jsxs)("div",{className:"fundy-form-params",children:[(0,a.jsx)("h4",{children:(0,t.__)("Default URL Parameters (Optional)","dekode-fundraising")}),(0,a.jsxs)("div",{style:{marginTop:"1em"},children:[n.map((e,r)=>(0,a.jsxs)(i.Flex,{children:[(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Key","dekode-fundraising"),value:e.key,onChange:e=>y(r,"key",e)})}),(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Value","dekode-fundraising"),value:e.value,onChange:e=>y(r,"value",e)})}),(0,a.jsx)(i.FlexItem,{children:(0,a.jsx)(i.Button,{isDestructive:!0,onClick:()=>(e=>{const r=n.filter((n,r)=>r!==e);s({urlParams:r})})(r),style:{marginTop:"14px"},children:(0,t.__)("Remove","dekode-fundraising")})})]},`param-${r}`)),(0,a.jsx)(i.Button,{variant:"link",onClick:()=>{s({urlParams:[...n,{key:"",value:""}]})},children:(0,t.__)("Add Parameter","dekode-fundraising")})]})]})]})})},save:()=>null})})();
     1(()=>{"use strict";const e=window.wp.blocks,t=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}'),n=window.React,r=window.wp.blockEditor,a=window.wp.element,o=window.wp.components,i=window.wp.i18n;(0,e.registerBlockType)(t,{edit:function({attributes:{formId:e,urlParams:t=[]},setAttributes:l}){var s,d;const[u,c]=(0,a.useReducer)((e,t)=>({...e,...t}),{isInitialized:!1,isLoaded:!1,apiToken:null!==(s=window.fundySettings.apiToken)&&void 0!==s?s:"",baseURL:null!==(d=window.fundySettings.baseURL)&&void 0!==d?d:"",forms:!1,error:null}),{isInitialized:m,isLoaded:p,apiToken:f,baseURL:k,forms:g,error:y}=u;if((0,a.useEffect)(()=>{!1===m&&f&&k&&c({isInitialized:!0})},[m,f,k]),(0,a.useEffect)(()=>{k&&f&&fetch(`${k}/api/v1/organization/forms`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:"Bearer "+f}}).then(e=>{if(!e.ok)throw new Error("Network response was not ok.");return e.json()}).then(t=>{const n=t.map(e=>({value:e.id,label:e.name}));c({isLoaded:!0,forms:n,error:null}),!e&&n.length&&l({formId:parseInt(n[0].value,10)})}).catch(e=>{c({error:"There has been a problem with your fetch operation: "+e})})},[k,f,e,l]),!f)return(0,n.createElement)("div",{...(0,r.useBlockProps)()},(0,n.createElement)(o.Placeholder,{instructions:(0,i.__)("Please set an API Token on the plugin settings page.","dekode-fundraising")}));const w=g&&g.length>0,h=(e,n,r)=>{const a=t.map((t,a)=>a===e?{...t,[n]:r}:t);l({urlParams:a})};return(0,n.createElement)("div",{...(0,r.useBlockProps)()},(0,n.createElement)(o.Placeholder,{label:(0,i.__)("Dekode Fundraising Form","dekode-fundraising"),isColumnLayout:!0},(0,n.createElement)(o.SelectControl,{label:(0,i.__)("Select a Form","dekode-fundraising"),value:e,className:"fundy-form",options:g||[{label:"",value:""}],onChange:e=>l({formId:parseInt(e,10)}),disabled:!p}),!w&&(0,n.createElement)("p",null,(0,i.__)("No forms found. Please create a Form on your Dekode Fundraising account first.","dekode-fundraising")),!p&&(0,n.createElement)("p",null,(0,i.__)("Loading…","dekode-fundraising")),y&&(0,n.createElement)("p",null,"Error: "+y),(0,n.createElement)("div",{className:"fundy-form-params"},(0,n.createElement)("h4",null,(0,i.__)("Default URL Parameters (Optional)","dekode-fundraising")),(0,n.createElement)("div",{style:{marginTop:"1em"}},t.map((e,r)=>(0,n.createElement)(o.Flex,{key:`param-${r}`},(0,n.createElement)(o.FlexBlock,null,(0,n.createElement)(o.TextControl,{label:(0,i.__)("Key","dekode-fundraising"),value:e.key,onChange:e=>h(r,"key",e)})),(0,n.createElement)(o.FlexBlock,null,(0,n.createElement)(o.TextControl,{label:(0,i.__)("Value","dekode-fundraising"),value:e.value,onChange:e=>h(r,"value",e)})),(0,n.createElement)(o.FlexItem,null,(0,n.createElement)(o.Button,{isDestructive:!0,onClick:()=>(e=>{const n=t.filter((t,n)=>n!==e);l({urlParams:n})})(r),style:{marginTop:"14px"}},(0,i.__)("Remove","dekode-fundraising"))))),(0,n.createElement)(o.Button,{variant:"link",onClick:()=>{l({urlParams:[...t,{key:"",value:""}]})}},(0,i.__)("Add Parameter","dekode-fundraising"))))))},save:()=>null})})();
  • dekode-fundraising/tags/2.4.0/build/blocks/donation-receipt/editor.asset.php

    r3422093 r3455489  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '7b5f3ffebaab90c2ba48');
     1<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => 'a9cbfded66870dc28128');
  • dekode-fundraising/tags/2.4.0/build/blocks/donation-receipt/editor.js

    r3422093 r3455489  
    1 (()=>{"use strict";const e=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}'),t=window.wp.blockEditor,n=window.wp.i18n,d=window.ReactJSXRuntime;(0,e.registerBlockType)(i,{edit:function(){return(0,d.jsx)("div",{...(0,t.useBlockProps)(),children:(0,d.jsx)("table",{children:(0,d.jsxs)("tbody",{children:[(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Name","dekode-fundraising")}),(0,d.jsx)("td",{children:"John Smith"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Date","dekode-fundraising")}),(0,d.jsx)("td",{children:"name@email.no"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Total amount","dekode-fundraising")}),(0,d.jsx)("td",{children:"400 kr"})]})]})})})},save:()=>null})})();
     1(()=>{"use strict";const e=window.wp.blocks,t=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}'),n=window.React,l=window.wp.blockEditor,r=window.wp.i18n;(0,e.registerBlockType)(t,{edit:function(){return(0,n.createElement)("div",{...(0,l.useBlockProps)()},(0,n.createElement)("table",null,(0,n.createElement)("tbody",null,(0,n.createElement)("tr",null,(0,n.createElement)("td",null,(0,r.__)("Name","dekode-fundraising")),(0,n.createElement)("td",null,"John Smith")),(0,n.createElement)("tr",null,(0,n.createElement)("td",null,(0,r.__)("Date","dekode-fundraising")),(0,n.createElement)("td",null,"name@email.no")),(0,n.createElement)("tr",null,(0,n.createElement)("td",null,(0,r.__)("Total amount","dekode-fundraising")),(0,n.createElement)("td",null,"400 kr")))))},save:()=>null})})();
  • dekode-fundraising/tags/2.4.0/build/blocks/donation-receipt/frontend.asset.php

    r3422093 r3455489  
    1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '3440296201b97170b755');
     1<?php return array('dependencies' => array('react', 'react-dom', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'dd95458bb5886782902a');
  • dekode-fundraising/tags/2.4.0/build/blocks/donation-receipt/frontend.js

    r3422093 r3455489  
    1 (()=>{"use strict";var e={338:(e,n,r)=>{var t=r(795);n.H=t.createRoot,t.hydrateRoot},795:e=>{e.exports=window.ReactDOM}},n={};function r(t){var o=n[t];if(void 0!==o)return o.exports;var d=n[t]={exports:{}};return e[t](d,d.exports,r),d.exports}r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var t=r(338);const o=window.wp.domReady;var d=r.n(o);const i=window.wp.element,a=window.wp.i18n,s=window.ReactJSXRuntime;function c(e){if(!e)return"unknown";const n=e instanceof Date?e:new Date(e);if(Number.isNaN(n.getTime()))return"unknown";const r="undefined"!=typeof navigator?navigator.languages||navigator.language:void 0;return n.toLocaleDateString(r,{year:"numeric",month:"numeric",day:"numeric"})}const l=()=>{var e;const[n,r]=(0,i.useReducer)((e,n)=>({...e,...n}),{isLoaded:!1,isError:!1,baseURL:null!==(e=window.fundySettings.baseURL)&&void 0!==e?e:null,donation:null}),{isLoaded:t,isError:o,baseURL:d,donation:l}=n;return(0,i.useEffect)(()=>{const e=function(){const e=new URLSearchParams(window.location.search);return{donationId:e.get("donation_id")||null,token:e.get("token")||null,expiry:e.get("expiry")||null}}();e.donationId&&e.token&&e.expiry&&d||r({isLoaded:!0,isError:!0});const n={donation_id:e.donationId,token:e.token,expiry:e.expiry},t=new URLSearchParams(n).toString();fetch(d+"/api/v1/donation/receipt?"+t,{method:"GET",headers:{"Content-Type":"application/json"}}).then(e=>{if(e.ok)return e.json();throw new Error("Network response was not ok.")}).then(e=>{r({isLoaded:!0,isError:!1,donation:e})}).catch(()=>{r({isLoaded:!0,isError:!0})})},[d]),t?o||!l?(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("p",{children:(0,a.__)("Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.","dekode-fundraising")})}):(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("table",{children:(0,s.jsx)("tbody",{children:l&&l.company_name?(0,s.jsxs)(i.Fragment,{children:[l.company_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Company name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.company_name})]}),l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Contact person","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]}),l.invoice_url&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Invoice","dekode-fundraising")}),(0,s.jsx)("td",{children:(0,s.jsx)("a",{href:l.invoice_url,children:(0,a.__)("Download invoice","dekode-fundraising")})})]})]}):(0,s.jsxs)(i.Fragment,{children:[l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]})]})})})}):null};d()(function(){document.querySelectorAll(".fundy-receipt").forEach(e=>{(0,t.H)(e).render((0,s.jsx)(l,{}))})})})();
     1(()=>{"use strict";var e={338(e,n,t){var a=t(795);n.H=a.createRoot,a.hydrateRoot},795(e){e.exports=window.ReactDOM}},n={};function t(a){var r=n[a];if(void 0!==r)return r.exports;var o=n[a]={exports:{}};return e[a](o,o.exports,t),o.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var a in n)t.o(n,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:n[a]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);const a=window.React;var r=t(338);const o=window.wp.domReady;var l=t.n(o);const d=window.wp.element,i=window.wp.i18n;function u(e){if(!e)return"unknown";const n=e instanceof Date?e:new Date(e);if(Number.isNaN(n.getTime()))return"unknown";const t="undefined"!=typeof navigator?navigator.languages||navigator.language:void 0;return n.toLocaleDateString(t,{year:"numeric",month:"numeric",day:"numeric"})}const c=()=>{var e;const[n,t]=(0,d.useReducer)((e,n)=>({...e,...n}),{isLoaded:!1,isError:!1,baseURL:null!==(e=window.fundySettings.baseURL)&&void 0!==e?e:null,donation:null}),{isLoaded:r,isError:o,baseURL:l,donation:c}=n;return(0,d.useEffect)(()=>{const e=function(){const e=new URLSearchParams(window.location.search);return{donationId:e.get("donation_id")||null,token:e.get("token")||null,expiry:e.get("expiry")||null}}();e.donationId&&e.token&&e.expiry&&l||t({isLoaded:!0,isError:!0});const n={donation_id:e.donationId,token:e.token,expiry:e.expiry},a=new URLSearchParams(n).toString();fetch(l+"/api/v1/donation/receipt?"+a,{method:"GET",headers:{"Content-Type":"application/json"}}).then(e=>{if(e.ok)return e.json();throw new Error("Network response was not ok.")}).then(e=>{t({isLoaded:!0,isError:!1,donation:e})}).catch(()=>{t({isLoaded:!0,isError:!0})})},[l]),r?o||!c?(0,a.createElement)(d.Fragment,null,(0,a.createElement)("p",null,(0,i.__)("Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.","dekode-fundraising"))):(0,a.createElement)(d.Fragment,null,(0,a.createElement)("table",null,(0,a.createElement)("tbody",null,c&&c.company_name?(0,a.createElement)(d.Fragment,null,c.company_name&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Company name","dekode-fundraising")),(0,a.createElement)("td",null,c.company_name)),c.first_name&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Contact person","dekode-fundraising")),(0,a.createElement)("td",null,c.first_name+" "+c?.last_name)),c.created_at&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Date","dekode-fundraising")),(0,a.createElement)("td",null,u(c.created_at))),c.amount&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Total amount","dekode-fundraising")),(0,a.createElement)("td",null,c.amount)),c.invoice_url&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Invoice","dekode-fundraising")),(0,a.createElement)("td",null,(0,a.createElement)("a",{href:c.invoice_url},(0,i.__)("Download invoice","dekode-fundraising"))))):(0,a.createElement)(d.Fragment,null,c.first_name&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Name","dekode-fundraising")),(0,a.createElement)("td",null,c.first_name+" "+c?.last_name)),c.created_at&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Date","dekode-fundraising")),(0,a.createElement)("td",null,u(c.created_at))),c.amount&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Total amount","dekode-fundraising")),(0,a.createElement)("td",null,c.amount)))))):null};l()(function(){document.querySelectorAll(".fundy-receipt").forEach(e=>{(0,r.H)(e).render((0,a.createElement)(c,null))})})})();
  • dekode-fundraising/tags/2.4.0/dekode-fundraising.php

    r3422093 r3455489  
    44 * Plugin URI:        https://github.com/DekodeInteraktiv/fundy-extension-wp/
    55 * Description:       Integrates with Dekode Fundraising, making it easy to add donation forms to your website.
    6  * Version:           2.3.2
     6 * Version:           2.4.0
    77 * Author:            Dekode Interaktiv
    88 * Author URI:        https://dekode.no
     
    2525}
    2626
    27 \define( 'FUNDY_VERSION', '2.3.2' );
     27\define( 'FUNDY_VERSION', '2.4.0' );
    2828\define( 'FUNDY_PLUGIN_URL', \plugin_dir_url( __FILE__ ) );
    2929\define( 'FUNDY_PLUGIN_DIR', \plugin_dir_path( __FILE__ ) );
     
    4242    } else {
    4343        \define( 'FUNDY_CORE_URL', 'https://fundy.cloud/core' );
     44    }
     45}
     46
     47/**
     48 * Define the Surge URL.
     49 *
     50 * Use existing constant if available, if not check for environment
     51 * variable and if not default to production URL.
     52 */
     53if ( ! \defined( 'FUNDY_SURGE_URL' ) ) {
     54    if ( \function_exists( 'env' ) && ! empty( \env( 'FUNDY_SURGE_URL' ) ) ) {
     55        \define( 'FUNDY_SURGE_URL', \env( 'FUNDY_SURGE_URL' ) );
     56    } else {
     57        \define( 'FUNDY_SURGE_URL', 'https://fundy.cloud/surge' );
    4458    }
    4559}
  • dekode-fundraising/tags/2.4.0/inc/assets.php

    r3382635 r3455489  
    1010namespace Dekode\Fundraising\Assets;
    1111
    12 use function Dekode\Fundraising\Settings\get_script_env;
     12use function Dekode\Fundraising\Settings\get_conversion_script_env;
     13use function Dekode\Fundraising\Settings\get_debug_enabled;
     14use function Dekode\Fundraising\Settings\get_disable_data_layer_event;
     15use function Dekode\Fundraising\Settings\get_forms_script_env;
     16use function Dekode\Fundraising\Settings\get_tracking_script_enabled;
     17use function Dekode\Fundraising\Settings\get_tracking_script_env;
    1318
    1419if ( ! \defined( 'ABSPATH' ) ) {
     
    2126\add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\register_assets' );
    2227
    23 function register_assets() {
    24     if (
    25         \wp_script_is( 'fundy-form-script', 'registered' )
    26         && \wp_style_is( 'fundy-form-style', 'registered' )
    27     ) {
     28/**
     29 * Register all assets.
     30 *
     31 * @return void
     32 */
     33function register_assets(): void {
     34    register_fundy_config();
     35    register_form_assets();
     36    register_conversion_script();
     37    register_tracking_script();
     38}
     39
     40/**
     41 * Register the FundyConfig script.
     42 *
     43 * This registers a virtual script handle and attaches the configuration
     44 * as an inline script. This approach is CSP-compatible as WordPress can
     45 * add the proper nonce when a CSP plugin is active.
     46 *
     47 * @return void
     48 */
     49function register_fundy_config(): void {
     50    // Register a virtual script handle (no actual file, loads in head).
     51    \wp_register_script( 'fundy-config', false, [], \FUNDY_VERSION, false );
     52
     53    // Build and attach the config as inline script.
     54    $config = build_fundy_config();
     55
     56    \wp_add_inline_script(
     57        'fundy-config',
     58        'window.FundyConfig = ' . \wp_json_encode( $config, \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_UNESCAPED_SLASHES ) . ';'
     59    );
     60
     61    // Always enqueue the config script.
     62    \wp_enqueue_script( 'fundy-config' );
     63}
     64
     65/**
     66 * Build the FundyConfig array.
     67 *
     68 * All values can be filtered using the 'fundy/config' and 'fundy/config/{key}' filters.
     69 *
     70 * @return array<string, mixed> The configuration array.
     71 */
     72function build_fundy_config(): array {
     73    $enable_debug_mode = \apply_filters( 'fundy/config/debug', get_debug_enabled() );
     74    $enable_debug_mode = \apply_filters( 'fundy/config/enable_debug_mode', $enable_debug_mode );
     75
     76    $config = [
     77        'coreBaseUrl'           => \apply_filters( 'fundy/config/core_base_url', \FUNDY_CORE_URL ),
     78        'surgeBaseUrl'          => \apply_filters( 'fundy/config/surge_base_url', \FUNDY_SURGE_URL ),
     79        'disableDataLayerEvent' => \apply_filters( 'fundy/config/disable_data_layer_event', get_disable_data_layer_event() ),
     80        'enableDebugMode'       => $enable_debug_mode,
     81    ];
     82
     83    /**
     84     * Filter the entire FundyConfig array.
     85     *
     86     * @param array $config The configuration array.
     87     */
     88    return \apply_filters( 'fundy/config', $config );
     89}
     90
     91/**
     92 * Register form scripts and styles.
     93 *
     94 * @return void
     95 */
     96function register_form_assets(): void {
     97    $env    = get_forms_script_env();
     98    $suffix = ( 'prod' === $env ) ? 'latest' : 'development';
     99
     100    if ( ! \wp_script_is( 'fundy-form-script', 'registered' ) ) {
     101        \wp_register_script( 'fundy-form-script', "https://assets.fundy.cloud/fundy-forms.{$suffix}.js", [ 'fundy-config' ], null, true );
     102    }
     103
     104    if ( \apply_filters( 'fundy/enqueue/form_styles', true ) && ! \wp_style_is( 'fundy-form-style', 'registered' ) ) {
     105        \wp_register_style( 'fundy-form-style', "https://assets.fundy.cloud/fundy-forms.{$suffix}.css", [], null, 'all' );
     106    }
     107}
     108
     109/**
     110 * Register the conversion script.
     111 *
     112 * @return void
     113 */
     114function register_conversion_script(): void {
     115    if ( ! \apply_filters( 'fundy/enable/conversion_script', true ) ) {
    28116        return;
    29117    }
    30118
    31     $suffix = ( 'prod' === get_script_env() ) ? 'latest' : 'development';
     119    $env    = get_conversion_script_env();
     120    $suffix = ( 'prod' === $env ) ? 'latest' : 'development';
     121    $src    = \apply_filters( 'fundy/conversion_script_src', "https://assets.fundy.cloud/fundy-conversion.{$suffix}.js", $env );
    32122
    33     \wp_register_script( 'fundy-form-script', "https://assets.fundy.cloud/fundy-forms.{$suffix}.js", [], null, true );
     123    if ( ! \wp_script_is( 'fundy-conversion-script', 'registered' ) ) {
     124        \wp_register_script( 'fundy-conversion-script', $src, [ 'fundy-config' ], null, true );
     125    }
    34126
    35     if ( \apply_filters( 'fundy/enqueue/form_styles', true ) ) {
    36         \wp_register_style( 'fundy-form-style', "https://assets.fundy.cloud/fundy-forms.{$suffix}.css", [], null, 'all' );
     127    \wp_enqueue_script( 'fundy-conversion-script' );
     128}
     129
     130/**
     131 * Register the tracking script.
     132 *
     133 * @return void
     134 */
     135function register_tracking_script(): void {
     136    if ( ! get_tracking_script_enabled() ) {
     137        return;
    37138    }
     139
     140    $env    = get_tracking_script_env();
     141    $suffix = ( 'prod' === $env ) ? 'latest' : 'development';
     142    $src    = \apply_filters( 'fundy/tracking_script_src', "https://assets.fundy.cloud/fundy-tracking.{$suffix}.js", $env );
     143
     144    if ( ! \wp_script_is( 'fundy-tracking-script', 'registered' ) ) {
     145        \wp_register_script( 'fundy-tracking-script', $src, [ 'fundy-config' ], null, true );
     146    }
     147
     148    \wp_enqueue_script( 'fundy-tracking-script' );
    38149}
  • dekode-fundraising/tags/2.4.0/inc/settings-page-network.php

    r3382635 r3455489  
    99
    1010namespace Dekode\Fundraising\SettingsPageNetwork;
     11
     12use function Dekode\Fundraising\Settings\normalize_script_env;
    1113
    1214if ( ! \defined( 'ABSPATH' ) ) {
     
    4547            'sanitize_callback' => __NAMESPACE__ . '\\sanitize_network_options',
    4648            'default'           => [
    47                 'api_key'    => '',
    48                 'script_env' => 'prod',
     49                'api_key'                  => '',
     50                'forms_script'             => 'prod',
     51                'conversion_script'        => 'prod',
     52                'tracking_enabled'         => '',
     53                'tracking_script'          => 'prod',
     54                'disable_data_layer_event' => '',
     55                'debug'                    => '',
    4956            ],
    5057        ]
     
    5360    \add_settings_section(
    5461        'fundy_network_settings_section',
    55         \__( 'General Configuration', 'dekode-fundraising' ),
     62        \__( 'General', 'dekode-fundraising' ),
    5663        __NAMESPACE__ . '\\settings_section_callback',
     64        'fundy_network_settings_page',
     65    );
     66
     67    \add_settings_section(
     68        'fundy_network_settings_section_advanced',
     69        \__( 'Advanced', 'dekode-fundraising' ),
     70        __NAMESPACE__ . '\\advanced_settings_section_callback',
    5771        'fundy_network_settings_page',
    5872    );
     
    6781
    6882    \add_settings_field(
    69         'fundy_script_env',
    70         \__( 'Script Environment', 'dekode-fundraising' ),
    71         __NAMESPACE__ . '\\script_env_callback',
    72         'fundy_network_settings_page',
    73         'fundy_network_settings_section',
    74     );
     83        'fundy_forms_script',
     84        \__( 'Forms Script', 'dekode-fundraising' ),
     85        __NAMESPACE__ . '\\forms_script_callback',
     86        'fundy_network_settings_page',
     87        'fundy_network_settings_section',
     88    );
     89
     90    \add_settings_field(
     91        'fundy_conversion_script',
     92        \__( 'Conversion Script', 'dekode-fundraising' ),
     93        __NAMESPACE__ . '\\conversion_script_callback',
     94        'fundy_network_settings_page',
     95        'fundy_network_settings_section',
     96    );
     97
     98    \add_settings_field(
     99        'fundy_disable_data_layer_event',
     100        \__( 'Data Layer Event', 'dekode-fundraising' ),
     101        __NAMESPACE__ . '\\disable_data_layer_event_callback',
     102        'fundy_network_settings_page',
     103        'fundy_network_settings_section',
     104    );
     105
     106    \add_settings_field(
     107        'fundy_tracking_script',
     108        \__( 'Tracking Script', 'dekode-fundraising' ),
     109        __NAMESPACE__ . '\\tracking_script_callback',
     110        'fundy_network_settings_page',
     111        'fundy_network_settings_section',
     112    );
     113
     114    \add_settings_field(
     115        'fundy_debug',
     116        \__( 'Debug Mode', 'dekode-fundraising' ),
     117        __NAMESPACE__ . '\\debug_callback',
     118        'fundy_network_settings_page',
     119        'fundy_network_settings_section_advanced',
     120    );
     121
    75122}
    76123
     
    107154        : '';
    108155
    109     $sanitized['script_env'] = ( isset( $input['script_env'] ) && 'dev' === $input['script_env'] )
    110         ? 'dev'
    111         : 'prod';
     156    $sanitized['forms_script'] = normalize_script_env( (string) ( $input['forms_script'] ?? '' ), 'prod' );
     157    $sanitized['conversion_script'] = normalize_script_env( (string) ( $input['conversion_script'] ?? '' ), 'prod' );
     158    $sanitized['tracking_enabled'] = ! empty( $input['tracking_enabled'] ) ? 'yes' : '';
     159    $sanitized['tracking_script'] = normalize_script_env( (string) ( $input['tracking_script'] ?? '' ), 'prod' );
     160    $sanitized['disable_data_layer_event'] = ! empty( $input['disable_data_layer_event'] ) ? 'yes' : '';
     161    $sanitized['debug'] = ! empty( $input['debug'] ) ? 'yes' : '';
    112162
    113163    return $sanitized;
     
    119169function settings_section_callback(): void {
    120170    echo '<p>' . \esc_html__( 'If you are unsure about the settings here please talk to your Dekode Fundraising contact.', 'dekode-fundraising' ) . '</p>';
     171}
     172
     173/**
     174 * Advanced settings section callback.
     175 */
     176function advanced_settings_section_callback(): void {
     177    echo '<p>' . \esc_html__( 'Advanced settings for troubleshooting and diagnostics.', 'dekode-fundraising' ) . '</p>';
    121178}
    122179
     
    138195
    139196/**
    140  * Field callback for the Script Environment.
    141  */
    142 function script_env_callback(): void {
    143     $options    = \get_network_option( null, 'fundy_network_options', [] );
    144     $script_env = $options['script_env'] ?? 'prod';
     197 * Field callback for the Fundy Forms script.
     198 */
     199function forms_script_callback(): void {
     200    $options = \get_network_option( null, 'fundy_network_options', [] );
     201    $env     = normalize_script_env( (string) ( $options['forms_script'] ?? '' ), 'prod' );
    145202    ?>
    146203    <fieldset>
     
    148205            <input
    149206                type="radio"
    150                 name="fundy_network_options[script_env]"
     207                name="fundy_network_options[forms_script]"
    151208                value="dev"
    152                 <?php \checked( $script_env, 'dev' ); ?>
     209                <?php \checked( $env, 'dev' ); ?>
    153210            />
    154211            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     
    157214            <input
    158215                type="radio"
    159                 name="fundy_network_options[script_env]"
     216                name="fundy_network_options[forms_script]"
    160217                value="prod"
    161                 <?php \checked( $script_env, 'prod' ); ?>
     218                <?php \checked( $env, 'prod' ); ?>
    162219            />
    163220            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
    164221        </label>
    165222    </fieldset>
     223    <?php
     224}
     225
     226/**
     227 * Field callback for the Fundy Conversion script.
     228 */
     229function conversion_script_callback(): void {
     230    $options = \get_network_option( null, 'fundy_network_options', [] );
     231    $env     = normalize_script_env( (string) ( $options['conversion_script'] ?? '' ), 'prod' );
     232    ?>
     233    <fieldset>
     234        <label>
     235            <input
     236                type="radio"
     237                name="fundy_network_options[conversion_script]"
     238                value="dev"
     239                <?php \checked( $env, 'dev' ); ?>
     240            />
     241            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     242        </label><br/>
     243        <label>
     244            <input
     245                type="radio"
     246                name="fundy_network_options[conversion_script]"
     247                value="prod"
     248                <?php \checked( $env, 'prod' ); ?>
     249            />
     250            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     251        </label>
     252    </fieldset>
     253    <?php
     254}
     255
     256/**
     257 * Field callback for the Tracking script.
     258 */
     259function tracking_script_callback(): void {
     260    $options = \get_network_option( null, 'fundy_network_options', [] );
     261    $enabled = ! empty( $options['tracking_enabled'] );
     262    $env     = normalize_script_env( (string) ( $options['tracking_script'] ?? '' ), 'prod' );
     263    ?>
     264    <p>
     265        <label>
     266            <input
     267                type="checkbox"
     268                name="fundy_network_options[tracking_enabled]"
     269                value="yes"
     270                <?php \checked( $enabled, true ); ?>
     271            />
     272            <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     273        </label>
     274    </p>
     275    <fieldset>
     276        <label>
     277            <input
     278                type="radio"
     279                name="fundy_network_options[tracking_script]"
     280                value="dev"
     281                <?php \checked( $env, 'dev' ); ?>
     282            />
     283            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     284        </label><br/>
     285        <label>
     286            <input
     287                type="radio"
     288                name="fundy_network_options[tracking_script]"
     289                value="prod"
     290                <?php \checked( $env, 'prod' ); ?>
     291            />
     292            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     293        </label>
     294    </fieldset>
     295    <?php
     296}
     297
     298/**
     299 * Field callback for the disableDataLayerEvent setting.
     300 */
     301function disable_data_layer_event_callback(): void {
     302    $options = \get_network_option( null, 'fundy_network_options', [] );
     303    $enabled = ! empty( $options['disable_data_layer_event'] );
     304    ?>
     305    <label>
     306        <input
     307            type="checkbox"
     308            name="fundy_network_options[disable_data_layer_event]"
     309            value="yes"
     310            <?php \checked( $enabled, true ); ?>
     311        />
     312        <?php \esc_html_e( 'Disable', 'dekode-fundraising' ); ?>
     313    </label>
     314    <p class="description"><?php \esc_html_e( 'Prevents pushing conversion events to the dataLayer.', 'dekode-fundraising' ); ?></p>
     315    <?php
     316}
     317
     318/**
     319 * Field callback for the Debug setting.
     320 */
     321function debug_callback(): void {
     322    $options = \get_network_option( null, 'fundy_network_options', [] );
     323    $enabled = ! empty( $options['debug'] );
     324    ?>
     325    <label>
     326        <input
     327            type="checkbox"
     328            name="fundy_network_options[debug]"
     329            value="yes"
     330            <?php \checked( $enabled, true ); ?>
     331        />
     332        <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     333    </label>
    166334    <?php
    167335}
  • dekode-fundraising/tags/2.4.0/inc/settings-page.php

    r3382635 r3455489  
    99
    1010namespace Dekode\Fundraising\SettingsPage;
     11
     12use function Dekode\Fundraising\Settings\get_conversion_script_env;
     13use function Dekode\Fundraising\Settings\get_debug_enabled;
     14use function Dekode\Fundraising\Settings\get_disable_data_layer_event;
     15use function Dekode\Fundraising\Settings\get_forms_script_env;
     16use function Dekode\Fundraising\Settings\get_tracking_script_enabled;
     17use function Dekode\Fundraising\Settings\get_tracking_script_env;
     18use function Dekode\Fundraising\Settings\normalize_script_env;
    1119
    1220if ( ! \defined( 'ABSPATH' ) ) {
     
    4654            'sanitize_callback' => __NAMESPACE__ . '\\sanitize_options',
    4755            'default'           => [
    48                 'api_key'    => '',
    49                 'script_env' => 'prod',
     56                'api_key'                  => '',
     57                'forms_script'             => 'prod',
     58                'conversion_script'        => 'prod',
     59                'tracking_enabled'         => '',
     60                'tracking_script'          => 'prod',
     61                'disable_data_layer_event' => '',
     62                'debug'                    => '',
    5063            ],
    5164        ]
     
    5467    \add_settings_section(
    5568        'fundy_settings_section',
    56         \__( 'General Configuration', 'dekode-fundraising' ),
     69        \__( 'General', 'dekode-fundraising' ),
    5770        __NAMESPACE__ . '\\section_callback',
     71        'fundy_settings_page',
     72    );
     73
     74    \add_settings_section(
     75        'fundy_settings_section_advanced',
     76        \__( 'Advanced', 'dekode-fundraising' ),
     77        __NAMESPACE__ . '\\advanced_section_callback',
    5878        'fundy_settings_page',
    5979    );
     
    7898
    7999    \add_settings_field(
    80         'fundy_script_env',
    81         \__( 'Script Environment', 'dekode-fundraising' ),
    82         __NAMESPACE__ . '\\script_env_callback',
     100        'fundy_forms_script',
     101        \__( 'Forms Script', 'dekode-fundraising' ),
     102        __NAMESPACE__ . '\\forms_script_callback',
    83103        'fundy_settings_page',
    84104        'fundy_settings_section'
    85105    );
     106
     107    \add_settings_field(
     108        'fundy_conversion_script',
     109        \__( 'Conversion Script', 'dekode-fundraising' ),
     110        __NAMESPACE__ . '\\conversion_script_callback',
     111        'fundy_settings_page',
     112        'fundy_settings_section'
     113    );
     114
     115    \add_settings_field(
     116        'fundy_disable_data_layer_event',
     117        \__( 'Data Layer Event', 'dekode-fundraising' ),
     118        __NAMESPACE__ . '\\disable_data_layer_event_callback',
     119        'fundy_settings_page',
     120        'fundy_settings_section'
     121    );
     122
     123    \add_settings_field(
     124        'fundy_tracking_script',
     125        \__( 'Tracking Script', 'dekode-fundraising' ),
     126        __NAMESPACE__ . '\\tracking_script_callback',
     127        'fundy_settings_page',
     128        'fundy_settings_section'
     129    );
     130
     131    \add_settings_field(
     132        'fundy_debug',
     133        \__( 'Debug Mode', 'dekode-fundraising' ),
     134        __NAMESPACE__ . '\\debug_callback',
     135        'fundy_settings_page',
     136        'fundy_settings_section_advanced'
     137    );
     138
    86139}
    87140
     
    99152    if (\is_multisite() && 'yes' !== $sanitized['override_network']) {
    100153        $sanitized['api_key'] = '';
    101         $sanitized['script_env'] = '';
     154        $sanitized['forms_script'] = '';
     155        $sanitized['conversion_script'] = '';
     156        $sanitized['tracking_enabled'] = '';
     157        $sanitized['tracking_script'] = '';
     158        $sanitized['disable_data_layer_event'] = '';
     159        $sanitized['debug'] = '';
    102160
    103161        return $sanitized;
     
    108166        : '';
    109167
    110     $sanitized['script_env'] = ( isset( $input['script_env'] ) && 'dev' === $input['script_env'] )
    111         ? 'dev'
    112         : 'prod';
     168    $sanitized['forms_script'] = normalize_script_env( (string) ( $input['forms_script'] ?? '' ), 'prod' );
     169    $sanitized['conversion_script'] = normalize_script_env( (string) ( $input['conversion_script'] ?? '' ), 'prod' );
     170    $sanitized['tracking_enabled'] = ! empty( $input['tracking_enabled'] ) ? 'yes' : '';
     171    $sanitized['tracking_script'] = normalize_script_env( (string) ( $input['tracking_script'] ?? '' ), 'prod' );
     172    $sanitized['disable_data_layer_event'] = ! empty( $input['disable_data_layer_event'] ) ? 'yes' : '';
     173    $sanitized['debug'] = ! empty( $input['debug'] ) ? 'yes' : '';
    113174
    114175    return $sanitized;
     
    120181function section_callback(): void {
    121182    echo '<p>' . \esc_html__( 'If you are unsure about the settings here please talk to your Dekode Fundraising contact.', 'dekode-fundraising' ) . '</p>';
     183}
     184
     185/**
     186 * Advanced settings section callback.
     187 */
     188function advanced_section_callback(): void {
     189    echo '<p>' . \esc_html__( 'Advanced settings for troubleshooting and diagnostics.', 'dekode-fundraising' ) . '</p>';
    122190}
    123191
     
    160228
    161229/**
    162  * Field callback for the Script Environment.
    163  */
    164 function script_env_callback(): void {
    165     $options    = \get_option( 'fundy_options' );
    166     $script_env = isset( $options['script_env'] ) ? $options['script_env'] : 'prod';
     230 * Field callback for the Fundy Forms script.
     231 */
     232function forms_script_callback(): void {
     233    $options = \get_option( 'fundy_options', [] );
     234    $env     = get_forms_script_env();
    167235    ?>
    168236    <fieldset>
     
    170238            <input
    171239                type="radio"
    172                 name="fundy_options[script_env]"
     240                name="fundy_options[forms_script]"
    173241                value="dev"
    174                 <?php \checked( $script_env, 'dev' ); ?>
     242                <?php \checked( $env, 'dev' ); ?>
    175243                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
    176244            />
     
    181249            <input
    182250                type="radio"
    183                 name="fundy_options[script_env]"
     251                name="fundy_options[forms_script]"
    184252                value="prod"
    185                 <?php \checked( $script_env, 'prod' ); ?>
     253                <?php \checked( $env, 'prod' ); ?>
    186254                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
    187255            />
     
    189257        </label>
    190258    </fieldset>
     259    <?php
     260}
     261
     262/**
     263 * Field callback for the Fundy Conversion script.
     264 */
     265function conversion_script_callback(): void {
     266    $options = \get_option( 'fundy_options', [] );
     267    $env     = get_conversion_script_env();
     268    ?>
     269    <fieldset>
     270        <label>
     271            <input
     272                type="radio"
     273                name="fundy_options[conversion_script]"
     274                value="dev"
     275                <?php \checked( $env, 'dev' ); ?>
     276                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     277            />
     278            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     279        </label>
     280        <br>
     281        <label>
     282            <input
     283                type="radio"
     284                name="fundy_options[conversion_script]"
     285                value="prod"
     286                <?php \checked( $env, 'prod' ); ?>
     287                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     288            />
     289            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     290        </label>
     291    </fieldset>
     292    <?php
     293}
     294
     295/**
     296 * Field callback for the Tracking script.
     297 */
     298function tracking_script_callback(): void {
     299    $options = \get_option( 'fundy_options', [] );
     300    $enabled = get_tracking_script_enabled();
     301    $env     = get_tracking_script_env();
     302    ?>
     303    <p>
     304        <label>
     305            <input
     306                type="checkbox"
     307                name="fundy_options[tracking_enabled]"
     308                value="yes"
     309                <?php \checked( $enabled, true ); ?>
     310                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     311            />
     312            <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     313        </label>
     314    </p>
     315    <fieldset>
     316        <label>
     317            <input
     318                type="radio"
     319                name="fundy_options[tracking_script]"
     320                value="dev"
     321                <?php \checked( $env, 'dev' ); ?>
     322                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     323            />
     324            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     325        </label>
     326        <br>
     327        <label>
     328            <input
     329                type="radio"
     330                name="fundy_options[tracking_script]"
     331                value="prod"
     332                <?php \checked( $env, 'prod' ); ?>
     333                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     334            />
     335            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     336        </label>
     337    </fieldset>
     338    <?php
     339}
     340
     341/**
     342 * Field callback for the disableDataLayerEvent setting.
     343 */
     344function disable_data_layer_event_callback(): void {
     345    $options = \get_option( 'fundy_options', [] );
     346    $enabled = get_disable_data_layer_event();
     347    ?>
     348    <label>
     349        <input
     350            type="checkbox"
     351            name="fundy_options[disable_data_layer_event]"
     352            value="yes"
     353            <?php \checked( $enabled, true ); ?>
     354            <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     355        />
     356        <?php \esc_html_e( 'Disable', 'dekode-fundraising' ); ?>
     357    </label>
     358    <p class="description"><?php \esc_html_e( 'Prevents pushing conversion events to the dataLayer.', 'dekode-fundraising' ); ?></p>
     359    <?php
     360}
     361
     362/**
     363 * Field callback for the Debug setting.
     364 */
     365function debug_callback(): void {
     366    $options = \get_option( 'fundy_options', [] );
     367    $enabled = get_debug_enabled();
     368    ?>
     369    <label>
     370        <input
     371            type="checkbox"
     372            name="fundy_options[debug]"
     373            value="yes"
     374            <?php \checked( $enabled, true ); ?>
     375            <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     376        />
     377        <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     378    </label>
    191379    <?php
    192380}
  • dekode-fundraising/tags/2.4.0/inc/settings.php

    r3382635 r3455489  
    1111
    1212/**
    13  * Retrieve the API key.
     13 * Retrieve a setting value, respecting multisite overrides.
     14 *
     15 * @param string $key     Option key.
     16 * @param mixed  $default Default value when not set.
     17 * @return mixed
    1418 */
    15 function get_api_key(): string {
     19function get_setting_value( string $key, mixed $default = '' ): mixed {
    1620    $site_options = \get_option( 'fundy_options', [] );
     21    if ( ! \is_array( $site_options ) ) {
     22        $site_options = [];
     23    }
    1724
    1825    if ( ! \is_multisite() ) {
    19         return $site_options['api_key'] ?? '';
     26        return $site_options[ $key ] ?? $default;
    2027    }
    2128
    2229    // Should site override network?
    2330    if ( ! empty( $site_options['override_network'] ) ) {
    24         return $site_options['api_key'] ?? '';
     31        return $site_options[ $key ] ?? $default;
    2532    }
    2633
    2734    $network_options = \get_network_option( null, 'fundy_network_options', [] );
     35    if ( ! \is_array( $network_options ) ) {
     36        $network_options = [];
     37    }
    2838
    29     return $network_options['api_key'] ?? '';
     39    return $network_options[ $key ] ?? $default;
     40}
     41
     42/**
     43 * Retrieve a setting value with a flag indicating if the key existed.
     44 *
     45 * @param string $key     Option key.
     46 * @param mixed  $default Default value when not set.
     47 * @return array{0: mixed, 1: bool} [value, exists]
     48 */
     49function get_setting_value_with_presence( string $key, mixed $default = '' ): array {
     50    $site_options = \get_option( 'fundy_options', [] );
     51    if ( ! \is_array( $site_options ) ) {
     52        $site_options = [];
     53    }
     54
     55    if ( ! \is_multisite() ) {
     56        return [
     57            $site_options[ $key ] ?? $default,
     58            \array_key_exists( $key, $site_options ),
     59        ];
     60    }
     61
     62    if ( ! empty( $site_options['override_network'] ) ) {
     63        return [
     64            $site_options[ $key ] ?? $default,
     65            \array_key_exists( $key, $site_options ),
     66        ];
     67    }
     68
     69    $network_options = \get_network_option( null, 'fundy_network_options', [] );
     70    if ( ! \is_array( $network_options ) ) {
     71        $network_options = [];
     72    }
     73
     74    return [
     75        $network_options[ $key ] ?? $default,
     76        \array_key_exists( $key, $network_options ),
     77    ];
     78}
     79
     80/**
     81 * Normalize script environment values.
     82 */
     83function normalize_script_env( string $value, string $default = 'prod' ): string {
     84    $value = \strtolower( $value );
     85
     86    if ( \in_array( $value, [ 'dev', 'prod' ], true ) ) {
     87        return $value;
     88    }
     89
     90    if ( 'development' === $value ) {
     91        return 'dev';
     92    }
     93
     94    if ( 'latest' === $value ) {
     95        return 'prod';
     96    }
     97
     98    return $default;
     99}
     100
     101/**
     102 * Retrieve the API key.
     103 */
     104function get_api_key(): string {
     105    return (string) get_setting_value( 'api_key', '' );
     106}
     107
     108/**
     109 * Retrieve the forms script environment ('dev' or 'prod').
     110 */
     111function get_forms_script_env(): string {
     112    $value = get_setting_value( 'forms_script', '' );
     113
     114    if ( '' !== $value ) {
     115        return normalize_script_env( (string) $value, 'prod' );
     116    }
     117
     118    $legacy = get_setting_value( 'script_env', '' );
     119
     120    if ( '' !== $legacy ) {
     121        return normalize_script_env( (string) $legacy, 'prod' );
     122    }
     123
     124    return 'prod';
     125}
     126
     127/**
     128 * Retrieve the conversion script environment ('dev' or 'prod').
     129 */
     130function get_conversion_script_env(): string {
     131    $value = get_setting_value( 'conversion_script', '' );
     132
     133    if ( '' !== $value ) {
     134        return normalize_script_env( (string) $value, 'prod' );
     135    }
     136
     137    $legacy = get_setting_value( 'script_env', '' );
     138
     139    if ( '' !== $legacy ) {
     140        return normalize_script_env( (string) $legacy, 'prod' );
     141    }
     142
     143    return 'prod';
     144}
     145
     146/**
     147 * Check if the tracking script is enabled.
     148 */
     149function get_tracking_script_enabled(): bool {
     150    [ $enabled, $exists ] = get_setting_value_with_presence( 'tracking_enabled', '' );
     151
     152    if ( ! $exists ) {
     153        return false;
     154    }
     155
     156    return ! empty( $enabled );
     157}
     158
     159/**
     160 * Retrieve the tracking script environment ('dev' or 'prod').
     161 */
     162function get_tracking_script_env(): string {
     163    $value = get_setting_value( 'tracking_script', '' );
     164
     165    if ( '' !== $value ) {
     166        return normalize_script_env( (string) $value, 'prod' );
     167    }
     168
     169    return 'prod';
     170}
     171
     172/**
     173 * Retrieve the disableDataLayerEvent config value.
     174 */
     175function get_disable_data_layer_event(): bool {
     176    return ! empty( get_setting_value( 'disable_data_layer_event', '' ) );
     177}
     178
     179/**
     180 * Retrieve the debug config value.
     181 */
     182function get_debug_enabled(): bool {
     183    return ! empty( get_setting_value( 'debug', '' ) );
    30184}
    31185
     
    34188 */
    35189function get_script_env(): string {
    36     $site_options = \get_option( 'fundy_options', [] );
    37 
    38     if ( ! \is_multisite() ) {
    39         return $site_options['script_env'] ?? 'prod';
    40     }
    41 
    42     // Should site override network?
    43     if ( ! empty( $site_options['override_network'] ) ) {
    44         return $site_options['script_env'] ?? 'prod';
    45     }
    46 
    47     $network_options = \get_network_option( null, 'fundy_network_options', [] );
    48 
    49     return $network_options['script_env'] ?? 'prod';
     190    return get_forms_script_env();
    50191}
  • dekode-fundraising/tags/2.4.0/inc/shortcodes.php

    r3382635 r3455489  
    5757
    5858    \wp_enqueue_script( 'fundy-form-script' );
    59     \wp_enqueue_style( 'fundy-form-style' );
     59
     60    if ( \apply_filters( 'fundy/enqueue/form_styles', true ) ) {
     61        \wp_enqueue_style( 'fundy-form-style' );
     62    }
    6063
    6164    return \sprintf( '
  • dekode-fundraising/tags/2.4.0/package.json

    r3408236 r3455489  
    44    "private": true,
    55    "engines": {
    6         "node": "22",
     6        "node": "24",
    77        "npm": ">=10",
    88        "yarn": "Please use npm"
     
    1010    "devDependencies": {
    1111        "@playwright/test": "~1.57.0",
    12         "@wordpress/dom-ready": "~4.36.0",
    13         "@wordpress/e2e-test-utils-playwright": "~1.31.0",
    14         "@wordpress/element": "~6.36.0",
    15         "@wordpress/env": "~10.31.0",
    16         "@wordpress/eslint-plugin": "~22.15.0",
    17         "@wordpress/scripts": "~31.1.0",
    18         "@wordpress/stylelint-config": "~23.23.0",
    19         "eslint-plugin-prettier": "~5.5.4",
     12        "@wordpress/dom-ready": "~4.37.0",
     13        "@wordpress/e2e-test-utils-playwright": "~1.37.0",
     14        "@wordpress/element": "~6.37.0",
     15        "@wordpress/env": "~10.37.0",
     16        "@wordpress/eslint-plugin": "~23.0.0",
     17        "@wordpress/scripts": "~27.9.0",
     18        "@wordpress/stylelint-config": "~23.29.0",
     19        "eslint-plugin-prettier": "~5.5.5",
    2020        "husky": "~9.1.7",
    21         "lint-staged": "~16.1.5",
     21        "lint-staged": "~16.2.7",
    2222        "prettier": "~3.6.2",
    23         "stylelint-order": "~7.0.0",
    24         "typescript": "~5.9.2"
     23        "stylelint-order": "~7.0.1",
     24        "typescript": "~5.9.3"
    2525    },
    2626    "scripts": {
  • dekode-fundraising/trunk/CHANGELOG.txt

    r3422093 r3455489  
     1= 2.4.0 (2026-02-06) =
     2* Enhancement- Added support for the new conversion and tracking scripts.
     3* Enhancement- Asset build dependency updates.
     4* Bugfix- Reverted `@wordpress/scripts` to `27.9.0`, to keep compatibility with WP 6.4 and up.
     5
    16= 2.3.2 (2025-12-17) =
    27* Remove receipt link icon.
  • dekode-fundraising/trunk/README.txt

    r3422093 r3455489  
    44Requires PHP: 8.1
    55Tested up to: 6.8
    6 Stable tag: 2.3.2
     6Stable tag: 2.4.0
    77License: GPLv3 or later
    88License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    4646== Changelog ==
    4747
     48= 2.4.0 (2026-02-06) =
     49* Enhancement- Added support for the new conversion and tracking scripts.
     50* Enhancement- Asset build dependency updates.
     51* Bugfix- Reverted `@wordpress/scripts` to `27.9.0`, to keep compatibility with WP 6.4 and up.
     52
    4853= 2.3.2 (2025-12-04) =
    4954* Remove receipt link icon.
  • dekode-fundraising/trunk/build/blocks/donation-form/editor.asset.php

    r3422093 r3455489  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '59d96ee1fd27a6d10057');
     1<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '19dd39a6fe0bc754f01c');
  • dekode-fundraising/trunk/build/blocks/donation-form/editor.js

    r3422093 r3455489  
    1 (()=>{"use strict";const e=window.wp.blocks,n=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}'),r=window.wp.blockEditor,o=window.wp.element,i=window.wp.components,t=window.wp.i18n,a=window.ReactJSXRuntime;(0,e.registerBlockType)(n,{edit:function({attributes:{formId:e,urlParams:n=[]},setAttributes:s}){var d,l;const[u,c]=(0,o.useReducer)((e,n)=>({...e,...n}),{isInitialized:!1,isLoaded:!1,apiToken:null!==(d=window.fundySettings.apiToken)&&void 0!==d?d:"",baseURL:null!==(l=window.fundySettings.baseURL)&&void 0!==l?l:"",forms:!1,error:null}),{isInitialized:p,isLoaded:m,apiToken:f,baseURL:h,forms:g,error:k}=u;if((0,o.useEffect)(()=>{!1===p&&f&&h&&c({isInitialized:!0})},[p,f,h]),(0,o.useEffect)(()=>{h&&f&&fetch(`${h}/api/v1/organization/forms`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:"Bearer "+f}}).then(e=>{if(!e.ok)throw new Error("Network response was not ok.");return e.json()}).then(n=>{const r=n.map(e=>({value:e.id,label:e.name}));c({isLoaded:!0,forms:r,error:null}),!e&&r.length&&s({formId:parseInt(r[0].value,10)})}).catch(e=>{c({error:"There has been a problem with your fetch operation: "+e})})},[h,f,e,s]),!f)return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsx)(i.Placeholder,{instructions:(0,t.__)("Please set an API Token on the plugin settings page.","dekode-fundraising")})});const w=g&&g.length>0,y=(e,r,o)=>{const i=n.map((n,i)=>i===e?{...n,[r]:o}:n);s({urlParams:i})};return(0,a.jsx)("div",{...(0,r.useBlockProps)(),children:(0,a.jsxs)(i.Placeholder,{label:(0,t.__)("Dekode Fundraising Form","dekode-fundraising"),isColumnLayout:!0,children:[(0,a.jsx)(i.SelectControl,{label:(0,t.__)("Select a Form","dekode-fundraising"),value:e,className:"fundy-form",options:g||[{label:"",value:""}],onChange:e=>s({formId:parseInt(e,10)}),disabled:!m}),!w&&(0,a.jsx)("p",{children:(0,t.__)("No forms found. Please create a Form on your Dekode Fundraising account first.","dekode-fundraising")}),!m&&(0,a.jsx)("p",{children:(0,t.__)("Loading…","dekode-fundraising")}),k&&(0,a.jsx)("p",{children:"Error: "+k}),(0,a.jsxs)("div",{className:"fundy-form-params",children:[(0,a.jsx)("h4",{children:(0,t.__)("Default URL Parameters (Optional)","dekode-fundraising")}),(0,a.jsxs)("div",{style:{marginTop:"1em"},children:[n.map((e,r)=>(0,a.jsxs)(i.Flex,{children:[(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Key","dekode-fundraising"),value:e.key,onChange:e=>y(r,"key",e)})}),(0,a.jsx)(i.FlexBlock,{children:(0,a.jsx)(i.TextControl,{label:(0,t.__)("Value","dekode-fundraising"),value:e.value,onChange:e=>y(r,"value",e)})}),(0,a.jsx)(i.FlexItem,{children:(0,a.jsx)(i.Button,{isDestructive:!0,onClick:()=>(e=>{const r=n.filter((n,r)=>r!==e);s({urlParams:r})})(r),style:{marginTop:"14px"},children:(0,t.__)("Remove","dekode-fundraising")})})]},`param-${r}`)),(0,a.jsx)(i.Button,{variant:"link",onClick:()=>{s({urlParams:[...n,{key:"",value:""}]})},children:(0,t.__)("Add Parameter","dekode-fundraising")})]})]})]})})},save:()=>null})})();
     1(()=>{"use strict";const e=window.wp.blocks,t=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-form","title":"Donation Form","description":"Displays a donation form.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true}},"attributes":{"formId":{"type":"number","default":0},"urlParams":{"type":"array","default":[],"items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"editorScript":"file:./editor.js","viewScript":"fundy-form-script","viewStyle":"fundy-form-style"}'),n=window.React,r=window.wp.blockEditor,a=window.wp.element,o=window.wp.components,i=window.wp.i18n;(0,e.registerBlockType)(t,{edit:function({attributes:{formId:e,urlParams:t=[]},setAttributes:l}){var s,d;const[u,c]=(0,a.useReducer)((e,t)=>({...e,...t}),{isInitialized:!1,isLoaded:!1,apiToken:null!==(s=window.fundySettings.apiToken)&&void 0!==s?s:"",baseURL:null!==(d=window.fundySettings.baseURL)&&void 0!==d?d:"",forms:!1,error:null}),{isInitialized:m,isLoaded:p,apiToken:f,baseURL:k,forms:g,error:y}=u;if((0,a.useEffect)(()=>{!1===m&&f&&k&&c({isInitialized:!0})},[m,f,k]),(0,a.useEffect)(()=>{k&&f&&fetch(`${k}/api/v1/organization/forms`,{method:"GET",headers:{"Content-Type":"application/json",Authorization:"Bearer "+f}}).then(e=>{if(!e.ok)throw new Error("Network response was not ok.");return e.json()}).then(t=>{const n=t.map(e=>({value:e.id,label:e.name}));c({isLoaded:!0,forms:n,error:null}),!e&&n.length&&l({formId:parseInt(n[0].value,10)})}).catch(e=>{c({error:"There has been a problem with your fetch operation: "+e})})},[k,f,e,l]),!f)return(0,n.createElement)("div",{...(0,r.useBlockProps)()},(0,n.createElement)(o.Placeholder,{instructions:(0,i.__)("Please set an API Token on the plugin settings page.","dekode-fundraising")}));const w=g&&g.length>0,h=(e,n,r)=>{const a=t.map((t,a)=>a===e?{...t,[n]:r}:t);l({urlParams:a})};return(0,n.createElement)("div",{...(0,r.useBlockProps)()},(0,n.createElement)(o.Placeholder,{label:(0,i.__)("Dekode Fundraising Form","dekode-fundraising"),isColumnLayout:!0},(0,n.createElement)(o.SelectControl,{label:(0,i.__)("Select a Form","dekode-fundraising"),value:e,className:"fundy-form",options:g||[{label:"",value:""}],onChange:e=>l({formId:parseInt(e,10)}),disabled:!p}),!w&&(0,n.createElement)("p",null,(0,i.__)("No forms found. Please create a Form on your Dekode Fundraising account first.","dekode-fundraising")),!p&&(0,n.createElement)("p",null,(0,i.__)("Loading…","dekode-fundraising")),y&&(0,n.createElement)("p",null,"Error: "+y),(0,n.createElement)("div",{className:"fundy-form-params"},(0,n.createElement)("h4",null,(0,i.__)("Default URL Parameters (Optional)","dekode-fundraising")),(0,n.createElement)("div",{style:{marginTop:"1em"}},t.map((e,r)=>(0,n.createElement)(o.Flex,{key:`param-${r}`},(0,n.createElement)(o.FlexBlock,null,(0,n.createElement)(o.TextControl,{label:(0,i.__)("Key","dekode-fundraising"),value:e.key,onChange:e=>h(r,"key",e)})),(0,n.createElement)(o.FlexBlock,null,(0,n.createElement)(o.TextControl,{label:(0,i.__)("Value","dekode-fundraising"),value:e.value,onChange:e=>h(r,"value",e)})),(0,n.createElement)(o.FlexItem,null,(0,n.createElement)(o.Button,{isDestructive:!0,onClick:()=>(e=>{const n=t.filter((t,n)=>n!==e);l({urlParams:n})})(r),style:{marginTop:"14px"}},(0,i.__)("Remove","dekode-fundraising"))))),(0,n.createElement)(o.Button,{variant:"link",onClick:()=>{l({urlParams:[...t,{key:"",value:""}]})}},(0,i.__)("Add Parameter","dekode-fundraising"))))))},save:()=>null})})();
  • dekode-fundraising/trunk/build/blocks/donation-receipt/editor.asset.php

    r3422093 r3455489  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => '7b5f3ffebaab90c2ba48');
     1<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-i18n'), 'version' => 'a9cbfded66870dc28128');
  • dekode-fundraising/trunk/build/blocks/donation-receipt/editor.js

    r3422093 r3455489  
    1 (()=>{"use strict";const e=window.wp.blocks,i=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}'),t=window.wp.blockEditor,n=window.wp.i18n,d=window.ReactJSXRuntime;(0,e.registerBlockType)(i,{edit:function(){return(0,d.jsx)("div",{...(0,t.useBlockProps)(),children:(0,d.jsx)("table",{children:(0,d.jsxs)("tbody",{children:[(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Name","dekode-fundraising")}),(0,d.jsx)("td",{children:"John Smith"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Date","dekode-fundraising")}),(0,d.jsx)("td",{children:"name@email.no"})]}),(0,d.jsxs)("tr",{children:[(0,d.jsx)("td",{children:(0,n.__)("Total amount","dekode-fundraising")}),(0,d.jsx)("td",{children:"400 kr"})]})]})})})},save:()=>null})})();
     1(()=>{"use strict";const e=window.wp.blocks,t=JSON.parse('{"$schema":"https://schemas.wp.org/trunk/block.json","apiVersion":3,"name":"fundy/donation-receipt","title":"Donation Receipt","description":"Displays a donation receipt on a thank you page.","category":"widgets","textdomain":"fundy","icon":"clipboard","supports":{"html":false,"color":{"background":true,"text":true},"spacing":{"margin":true,"padding":true},"multiple":false},"attributes":{},"editorScript":"file:editor.js","script":"file:frontend.js"}'),n=window.React,l=window.wp.blockEditor,r=window.wp.i18n;(0,e.registerBlockType)(t,{edit:function(){return(0,n.createElement)("div",{...(0,l.useBlockProps)()},(0,n.createElement)("table",null,(0,n.createElement)("tbody",null,(0,n.createElement)("tr",null,(0,n.createElement)("td",null,(0,r.__)("Name","dekode-fundraising")),(0,n.createElement)("td",null,"John Smith")),(0,n.createElement)("tr",null,(0,n.createElement)("td",null,(0,r.__)("Date","dekode-fundraising")),(0,n.createElement)("td",null,"name@email.no")),(0,n.createElement)("tr",null,(0,n.createElement)("td",null,(0,r.__)("Total amount","dekode-fundraising")),(0,n.createElement)("td",null,"400 kr")))))},save:()=>null})})();
  • dekode-fundraising/trunk/build/blocks/donation-receipt/frontend.asset.php

    r3422093 r3455489  
    1 <?php return array('dependencies' => array('react-dom', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '3440296201b97170b755');
     1<?php return array('dependencies' => array('react', 'react-dom', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'dd95458bb5886782902a');
  • dekode-fundraising/trunk/build/blocks/donation-receipt/frontend.js

    r3422093 r3455489  
    1 (()=>{"use strict";var e={338:(e,n,r)=>{var t=r(795);n.H=t.createRoot,t.hydrateRoot},795:e=>{e.exports=window.ReactDOM}},n={};function r(t){var o=n[t];if(void 0!==o)return o.exports;var d=n[t]={exports:{}};return e[t](d,d.exports,r),d.exports}r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);var t=r(338);const o=window.wp.domReady;var d=r.n(o);const i=window.wp.element,a=window.wp.i18n,s=window.ReactJSXRuntime;function c(e){if(!e)return"unknown";const n=e instanceof Date?e:new Date(e);if(Number.isNaN(n.getTime()))return"unknown";const r="undefined"!=typeof navigator?navigator.languages||navigator.language:void 0;return n.toLocaleDateString(r,{year:"numeric",month:"numeric",day:"numeric"})}const l=()=>{var e;const[n,r]=(0,i.useReducer)((e,n)=>({...e,...n}),{isLoaded:!1,isError:!1,baseURL:null!==(e=window.fundySettings.baseURL)&&void 0!==e?e:null,donation:null}),{isLoaded:t,isError:o,baseURL:d,donation:l}=n;return(0,i.useEffect)(()=>{const e=function(){const e=new URLSearchParams(window.location.search);return{donationId:e.get("donation_id")||null,token:e.get("token")||null,expiry:e.get("expiry")||null}}();e.donationId&&e.token&&e.expiry&&d||r({isLoaded:!0,isError:!0});const n={donation_id:e.donationId,token:e.token,expiry:e.expiry},t=new URLSearchParams(n).toString();fetch(d+"/api/v1/donation/receipt?"+t,{method:"GET",headers:{"Content-Type":"application/json"}}).then(e=>{if(e.ok)return e.json();throw new Error("Network response was not ok.")}).then(e=>{r({isLoaded:!0,isError:!1,donation:e})}).catch(()=>{r({isLoaded:!0,isError:!0})})},[d]),t?o||!l?(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("p",{children:(0,a.__)("Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.","dekode-fundraising")})}):(0,s.jsx)(i.Fragment,{children:(0,s.jsx)("table",{children:(0,s.jsx)("tbody",{children:l&&l.company_name?(0,s.jsxs)(i.Fragment,{children:[l.company_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Company name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.company_name})]}),l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Contact person","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]}),l.invoice_url&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Invoice","dekode-fundraising")}),(0,s.jsx)("td",{children:(0,s.jsx)("a",{href:l.invoice_url,children:(0,a.__)("Download invoice","dekode-fundraising")})})]})]}):(0,s.jsxs)(i.Fragment,{children:[l.first_name&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Name","dekode-fundraising")}),(0,s.jsx)("td",{children:l.first_name+" "+l?.last_name})]}),l.created_at&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Date","dekode-fundraising")}),(0,s.jsx)("td",{children:c(l.created_at)})]}),l.amount&&(0,s.jsxs)("tr",{children:[(0,s.jsx)("td",{children:(0,a.__)("Total amount","dekode-fundraising")}),(0,s.jsx)("td",{children:l.amount})]})]})})})}):null};d()(function(){document.querySelectorAll(".fundy-receipt").forEach(e=>{(0,t.H)(e).render((0,s.jsx)(l,{}))})})})();
     1(()=>{"use strict";var e={338(e,n,t){var a=t(795);n.H=a.createRoot,a.hydrateRoot},795(e){e.exports=window.ReactDOM}},n={};function t(a){var r=n[a];if(void 0!==r)return r.exports;var o=n[a]={exports:{}};return e[a](o,o.exports,t),o.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var a in n)t.o(n,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:n[a]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n);const a=window.React;var r=t(338);const o=window.wp.domReady;var l=t.n(o);const d=window.wp.element,i=window.wp.i18n;function u(e){if(!e)return"unknown";const n=e instanceof Date?e:new Date(e);if(Number.isNaN(n.getTime()))return"unknown";const t="undefined"!=typeof navigator?navigator.languages||navigator.language:void 0;return n.toLocaleDateString(t,{year:"numeric",month:"numeric",day:"numeric"})}const c=()=>{var e;const[n,t]=(0,d.useReducer)((e,n)=>({...e,...n}),{isLoaded:!1,isError:!1,baseURL:null!==(e=window.fundySettings.baseURL)&&void 0!==e?e:null,donation:null}),{isLoaded:r,isError:o,baseURL:l,donation:c}=n;return(0,d.useEffect)(()=>{const e=function(){const e=new URLSearchParams(window.location.search);return{donationId:e.get("donation_id")||null,token:e.get("token")||null,expiry:e.get("expiry")||null}}();e.donationId&&e.token&&e.expiry&&l||t({isLoaded:!0,isError:!0});const n={donation_id:e.donationId,token:e.token,expiry:e.expiry},a=new URLSearchParams(n).toString();fetch(l+"/api/v1/donation/receipt?"+a,{method:"GET",headers:{"Content-Type":"application/json"}}).then(e=>{if(e.ok)return e.json();throw new Error("Network response was not ok.")}).then(e=>{t({isLoaded:!0,isError:!1,donation:e})}).catch(()=>{t({isLoaded:!0,isError:!0})})},[l]),r?o||!c?(0,a.createElement)(d.Fragment,null,(0,a.createElement)("p",null,(0,i.__)("Unfortunately, we were unable to load the details for the donation at this moment; the link may have expired.","dekode-fundraising"))):(0,a.createElement)(d.Fragment,null,(0,a.createElement)("table",null,(0,a.createElement)("tbody",null,c&&c.company_name?(0,a.createElement)(d.Fragment,null,c.company_name&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Company name","dekode-fundraising")),(0,a.createElement)("td",null,c.company_name)),c.first_name&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Contact person","dekode-fundraising")),(0,a.createElement)("td",null,c.first_name+" "+c?.last_name)),c.created_at&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Date","dekode-fundraising")),(0,a.createElement)("td",null,u(c.created_at))),c.amount&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Total amount","dekode-fundraising")),(0,a.createElement)("td",null,c.amount)),c.invoice_url&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Invoice","dekode-fundraising")),(0,a.createElement)("td",null,(0,a.createElement)("a",{href:c.invoice_url},(0,i.__)("Download invoice","dekode-fundraising"))))):(0,a.createElement)(d.Fragment,null,c.first_name&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Name","dekode-fundraising")),(0,a.createElement)("td",null,c.first_name+" "+c?.last_name)),c.created_at&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Date","dekode-fundraising")),(0,a.createElement)("td",null,u(c.created_at))),c.amount&&(0,a.createElement)("tr",null,(0,a.createElement)("td",null,(0,i.__)("Total amount","dekode-fundraising")),(0,a.createElement)("td",null,c.amount)))))):null};l()(function(){document.querySelectorAll(".fundy-receipt").forEach(e=>{(0,r.H)(e).render((0,a.createElement)(c,null))})})})();
  • dekode-fundraising/trunk/dekode-fundraising.php

    r3422093 r3455489  
    44 * Plugin URI:        https://github.com/DekodeInteraktiv/fundy-extension-wp/
    55 * Description:       Integrates with Dekode Fundraising, making it easy to add donation forms to your website.
    6  * Version:           2.3.2
     6 * Version:           2.4.0
    77 * Author:            Dekode Interaktiv
    88 * Author URI:        https://dekode.no
     
    2525}
    2626
    27 \define( 'FUNDY_VERSION', '2.3.2' );
     27\define( 'FUNDY_VERSION', '2.4.0' );
    2828\define( 'FUNDY_PLUGIN_URL', \plugin_dir_url( __FILE__ ) );
    2929\define( 'FUNDY_PLUGIN_DIR', \plugin_dir_path( __FILE__ ) );
     
    4242    } else {
    4343        \define( 'FUNDY_CORE_URL', 'https://fundy.cloud/core' );
     44    }
     45}
     46
     47/**
     48 * Define the Surge URL.
     49 *
     50 * Use existing constant if available, if not check for environment
     51 * variable and if not default to production URL.
     52 */
     53if ( ! \defined( 'FUNDY_SURGE_URL' ) ) {
     54    if ( \function_exists( 'env' ) && ! empty( \env( 'FUNDY_SURGE_URL' ) ) ) {
     55        \define( 'FUNDY_SURGE_URL', \env( 'FUNDY_SURGE_URL' ) );
     56    } else {
     57        \define( 'FUNDY_SURGE_URL', 'https://fundy.cloud/surge' );
    4458    }
    4559}
  • dekode-fundraising/trunk/inc/assets.php

    r3382635 r3455489  
    1010namespace Dekode\Fundraising\Assets;
    1111
    12 use function Dekode\Fundraising\Settings\get_script_env;
     12use function Dekode\Fundraising\Settings\get_conversion_script_env;
     13use function Dekode\Fundraising\Settings\get_debug_enabled;
     14use function Dekode\Fundraising\Settings\get_disable_data_layer_event;
     15use function Dekode\Fundraising\Settings\get_forms_script_env;
     16use function Dekode\Fundraising\Settings\get_tracking_script_enabled;
     17use function Dekode\Fundraising\Settings\get_tracking_script_env;
    1318
    1419if ( ! \defined( 'ABSPATH' ) ) {
     
    2126\add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\\register_assets' );
    2227
    23 function register_assets() {
    24     if (
    25         \wp_script_is( 'fundy-form-script', 'registered' )
    26         && \wp_style_is( 'fundy-form-style', 'registered' )
    27     ) {
     28/**
     29 * Register all assets.
     30 *
     31 * @return void
     32 */
     33function register_assets(): void {
     34    register_fundy_config();
     35    register_form_assets();
     36    register_conversion_script();
     37    register_tracking_script();
     38}
     39
     40/**
     41 * Register the FundyConfig script.
     42 *
     43 * This registers a virtual script handle and attaches the configuration
     44 * as an inline script. This approach is CSP-compatible as WordPress can
     45 * add the proper nonce when a CSP plugin is active.
     46 *
     47 * @return void
     48 */
     49function register_fundy_config(): void {
     50    // Register a virtual script handle (no actual file, loads in head).
     51    \wp_register_script( 'fundy-config', false, [], \FUNDY_VERSION, false );
     52
     53    // Build and attach the config as inline script.
     54    $config = build_fundy_config();
     55
     56    \wp_add_inline_script(
     57        'fundy-config',
     58        'window.FundyConfig = ' . \wp_json_encode( $config, \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_UNESCAPED_SLASHES ) . ';'
     59    );
     60
     61    // Always enqueue the config script.
     62    \wp_enqueue_script( 'fundy-config' );
     63}
     64
     65/**
     66 * Build the FundyConfig array.
     67 *
     68 * All values can be filtered using the 'fundy/config' and 'fundy/config/{key}' filters.
     69 *
     70 * @return array<string, mixed> The configuration array.
     71 */
     72function build_fundy_config(): array {
     73    $enable_debug_mode = \apply_filters( 'fundy/config/debug', get_debug_enabled() );
     74    $enable_debug_mode = \apply_filters( 'fundy/config/enable_debug_mode', $enable_debug_mode );
     75
     76    $config = [
     77        'coreBaseUrl'           => \apply_filters( 'fundy/config/core_base_url', \FUNDY_CORE_URL ),
     78        'surgeBaseUrl'          => \apply_filters( 'fundy/config/surge_base_url', \FUNDY_SURGE_URL ),
     79        'disableDataLayerEvent' => \apply_filters( 'fundy/config/disable_data_layer_event', get_disable_data_layer_event() ),
     80        'enableDebugMode'       => $enable_debug_mode,
     81    ];
     82
     83    /**
     84     * Filter the entire FundyConfig array.
     85     *
     86     * @param array $config The configuration array.
     87     */
     88    return \apply_filters( 'fundy/config', $config );
     89}
     90
     91/**
     92 * Register form scripts and styles.
     93 *
     94 * @return void
     95 */
     96function register_form_assets(): void {
     97    $env    = get_forms_script_env();
     98    $suffix = ( 'prod' === $env ) ? 'latest' : 'development';
     99
     100    if ( ! \wp_script_is( 'fundy-form-script', 'registered' ) ) {
     101        \wp_register_script( 'fundy-form-script', "https://assets.fundy.cloud/fundy-forms.{$suffix}.js", [ 'fundy-config' ], null, true );
     102    }
     103
     104    if ( \apply_filters( 'fundy/enqueue/form_styles', true ) && ! \wp_style_is( 'fundy-form-style', 'registered' ) ) {
     105        \wp_register_style( 'fundy-form-style', "https://assets.fundy.cloud/fundy-forms.{$suffix}.css", [], null, 'all' );
     106    }
     107}
     108
     109/**
     110 * Register the conversion script.
     111 *
     112 * @return void
     113 */
     114function register_conversion_script(): void {
     115    if ( ! \apply_filters( 'fundy/enable/conversion_script', true ) ) {
    28116        return;
    29117    }
    30118
    31     $suffix = ( 'prod' === get_script_env() ) ? 'latest' : 'development';
     119    $env    = get_conversion_script_env();
     120    $suffix = ( 'prod' === $env ) ? 'latest' : 'development';
     121    $src    = \apply_filters( 'fundy/conversion_script_src', "https://assets.fundy.cloud/fundy-conversion.{$suffix}.js", $env );
    32122
    33     \wp_register_script( 'fundy-form-script', "https://assets.fundy.cloud/fundy-forms.{$suffix}.js", [], null, true );
     123    if ( ! \wp_script_is( 'fundy-conversion-script', 'registered' ) ) {
     124        \wp_register_script( 'fundy-conversion-script', $src, [ 'fundy-config' ], null, true );
     125    }
    34126
    35     if ( \apply_filters( 'fundy/enqueue/form_styles', true ) ) {
    36         \wp_register_style( 'fundy-form-style', "https://assets.fundy.cloud/fundy-forms.{$suffix}.css", [], null, 'all' );
     127    \wp_enqueue_script( 'fundy-conversion-script' );
     128}
     129
     130/**
     131 * Register the tracking script.
     132 *
     133 * @return void
     134 */
     135function register_tracking_script(): void {
     136    if ( ! get_tracking_script_enabled() ) {
     137        return;
    37138    }
     139
     140    $env    = get_tracking_script_env();
     141    $suffix = ( 'prod' === $env ) ? 'latest' : 'development';
     142    $src    = \apply_filters( 'fundy/tracking_script_src', "https://assets.fundy.cloud/fundy-tracking.{$suffix}.js", $env );
     143
     144    if ( ! \wp_script_is( 'fundy-tracking-script', 'registered' ) ) {
     145        \wp_register_script( 'fundy-tracking-script', $src, [ 'fundy-config' ], null, true );
     146    }
     147
     148    \wp_enqueue_script( 'fundy-tracking-script' );
    38149}
  • dekode-fundraising/trunk/inc/settings-page-network.php

    r3382635 r3455489  
    99
    1010namespace Dekode\Fundraising\SettingsPageNetwork;
     11
     12use function Dekode\Fundraising\Settings\normalize_script_env;
    1113
    1214if ( ! \defined( 'ABSPATH' ) ) {
     
    4547            'sanitize_callback' => __NAMESPACE__ . '\\sanitize_network_options',
    4648            'default'           => [
    47                 'api_key'    => '',
    48                 'script_env' => 'prod',
     49                'api_key'                  => '',
     50                'forms_script'             => 'prod',
     51                'conversion_script'        => 'prod',
     52                'tracking_enabled'         => '',
     53                'tracking_script'          => 'prod',
     54                'disable_data_layer_event' => '',
     55                'debug'                    => '',
    4956            ],
    5057        ]
     
    5360    \add_settings_section(
    5461        'fundy_network_settings_section',
    55         \__( 'General Configuration', 'dekode-fundraising' ),
     62        \__( 'General', 'dekode-fundraising' ),
    5663        __NAMESPACE__ . '\\settings_section_callback',
     64        'fundy_network_settings_page',
     65    );
     66
     67    \add_settings_section(
     68        'fundy_network_settings_section_advanced',
     69        \__( 'Advanced', 'dekode-fundraising' ),
     70        __NAMESPACE__ . '\\advanced_settings_section_callback',
    5771        'fundy_network_settings_page',
    5872    );
     
    6781
    6882    \add_settings_field(
    69         'fundy_script_env',
    70         \__( 'Script Environment', 'dekode-fundraising' ),
    71         __NAMESPACE__ . '\\script_env_callback',
    72         'fundy_network_settings_page',
    73         'fundy_network_settings_section',
    74     );
     83        'fundy_forms_script',
     84        \__( 'Forms Script', 'dekode-fundraising' ),
     85        __NAMESPACE__ . '\\forms_script_callback',
     86        'fundy_network_settings_page',
     87        'fundy_network_settings_section',
     88    );
     89
     90    \add_settings_field(
     91        'fundy_conversion_script',
     92        \__( 'Conversion Script', 'dekode-fundraising' ),
     93        __NAMESPACE__ . '\\conversion_script_callback',
     94        'fundy_network_settings_page',
     95        'fundy_network_settings_section',
     96    );
     97
     98    \add_settings_field(
     99        'fundy_disable_data_layer_event',
     100        \__( 'Data Layer Event', 'dekode-fundraising' ),
     101        __NAMESPACE__ . '\\disable_data_layer_event_callback',
     102        'fundy_network_settings_page',
     103        'fundy_network_settings_section',
     104    );
     105
     106    \add_settings_field(
     107        'fundy_tracking_script',
     108        \__( 'Tracking Script', 'dekode-fundraising' ),
     109        __NAMESPACE__ . '\\tracking_script_callback',
     110        'fundy_network_settings_page',
     111        'fundy_network_settings_section',
     112    );
     113
     114    \add_settings_field(
     115        'fundy_debug',
     116        \__( 'Debug Mode', 'dekode-fundraising' ),
     117        __NAMESPACE__ . '\\debug_callback',
     118        'fundy_network_settings_page',
     119        'fundy_network_settings_section_advanced',
     120    );
     121
    75122}
    76123
     
    107154        : '';
    108155
    109     $sanitized['script_env'] = ( isset( $input['script_env'] ) && 'dev' === $input['script_env'] )
    110         ? 'dev'
    111         : 'prod';
     156    $sanitized['forms_script'] = normalize_script_env( (string) ( $input['forms_script'] ?? '' ), 'prod' );
     157    $sanitized['conversion_script'] = normalize_script_env( (string) ( $input['conversion_script'] ?? '' ), 'prod' );
     158    $sanitized['tracking_enabled'] = ! empty( $input['tracking_enabled'] ) ? 'yes' : '';
     159    $sanitized['tracking_script'] = normalize_script_env( (string) ( $input['tracking_script'] ?? '' ), 'prod' );
     160    $sanitized['disable_data_layer_event'] = ! empty( $input['disable_data_layer_event'] ) ? 'yes' : '';
     161    $sanitized['debug'] = ! empty( $input['debug'] ) ? 'yes' : '';
    112162
    113163    return $sanitized;
     
    119169function settings_section_callback(): void {
    120170    echo '<p>' . \esc_html__( 'If you are unsure about the settings here please talk to your Dekode Fundraising contact.', 'dekode-fundraising' ) . '</p>';
     171}
     172
     173/**
     174 * Advanced settings section callback.
     175 */
     176function advanced_settings_section_callback(): void {
     177    echo '<p>' . \esc_html__( 'Advanced settings for troubleshooting and diagnostics.', 'dekode-fundraising' ) . '</p>';
    121178}
    122179
     
    138195
    139196/**
    140  * Field callback for the Script Environment.
    141  */
    142 function script_env_callback(): void {
    143     $options    = \get_network_option( null, 'fundy_network_options', [] );
    144     $script_env = $options['script_env'] ?? 'prod';
     197 * Field callback for the Fundy Forms script.
     198 */
     199function forms_script_callback(): void {
     200    $options = \get_network_option( null, 'fundy_network_options', [] );
     201    $env     = normalize_script_env( (string) ( $options['forms_script'] ?? '' ), 'prod' );
    145202    ?>
    146203    <fieldset>
     
    148205            <input
    149206                type="radio"
    150                 name="fundy_network_options[script_env]"
     207                name="fundy_network_options[forms_script]"
    151208                value="dev"
    152                 <?php \checked( $script_env, 'dev' ); ?>
     209                <?php \checked( $env, 'dev' ); ?>
    153210            />
    154211            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     
    157214            <input
    158215                type="radio"
    159                 name="fundy_network_options[script_env]"
     216                name="fundy_network_options[forms_script]"
    160217                value="prod"
    161                 <?php \checked( $script_env, 'prod' ); ?>
     218                <?php \checked( $env, 'prod' ); ?>
    162219            />
    163220            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
    164221        </label>
    165222    </fieldset>
     223    <?php
     224}
     225
     226/**
     227 * Field callback for the Fundy Conversion script.
     228 */
     229function conversion_script_callback(): void {
     230    $options = \get_network_option( null, 'fundy_network_options', [] );
     231    $env     = normalize_script_env( (string) ( $options['conversion_script'] ?? '' ), 'prod' );
     232    ?>
     233    <fieldset>
     234        <label>
     235            <input
     236                type="radio"
     237                name="fundy_network_options[conversion_script]"
     238                value="dev"
     239                <?php \checked( $env, 'dev' ); ?>
     240            />
     241            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     242        </label><br/>
     243        <label>
     244            <input
     245                type="radio"
     246                name="fundy_network_options[conversion_script]"
     247                value="prod"
     248                <?php \checked( $env, 'prod' ); ?>
     249            />
     250            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     251        </label>
     252    </fieldset>
     253    <?php
     254}
     255
     256/**
     257 * Field callback for the Tracking script.
     258 */
     259function tracking_script_callback(): void {
     260    $options = \get_network_option( null, 'fundy_network_options', [] );
     261    $enabled = ! empty( $options['tracking_enabled'] );
     262    $env     = normalize_script_env( (string) ( $options['tracking_script'] ?? '' ), 'prod' );
     263    ?>
     264    <p>
     265        <label>
     266            <input
     267                type="checkbox"
     268                name="fundy_network_options[tracking_enabled]"
     269                value="yes"
     270                <?php \checked( $enabled, true ); ?>
     271            />
     272            <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     273        </label>
     274    </p>
     275    <fieldset>
     276        <label>
     277            <input
     278                type="radio"
     279                name="fundy_network_options[tracking_script]"
     280                value="dev"
     281                <?php \checked( $env, 'dev' ); ?>
     282            />
     283            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     284        </label><br/>
     285        <label>
     286            <input
     287                type="radio"
     288                name="fundy_network_options[tracking_script]"
     289                value="prod"
     290                <?php \checked( $env, 'prod' ); ?>
     291            />
     292            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     293        </label>
     294    </fieldset>
     295    <?php
     296}
     297
     298/**
     299 * Field callback for the disableDataLayerEvent setting.
     300 */
     301function disable_data_layer_event_callback(): void {
     302    $options = \get_network_option( null, 'fundy_network_options', [] );
     303    $enabled = ! empty( $options['disable_data_layer_event'] );
     304    ?>
     305    <label>
     306        <input
     307            type="checkbox"
     308            name="fundy_network_options[disable_data_layer_event]"
     309            value="yes"
     310            <?php \checked( $enabled, true ); ?>
     311        />
     312        <?php \esc_html_e( 'Disable', 'dekode-fundraising' ); ?>
     313    </label>
     314    <p class="description"><?php \esc_html_e( 'Prevents pushing conversion events to the dataLayer.', 'dekode-fundraising' ); ?></p>
     315    <?php
     316}
     317
     318/**
     319 * Field callback for the Debug setting.
     320 */
     321function debug_callback(): void {
     322    $options = \get_network_option( null, 'fundy_network_options', [] );
     323    $enabled = ! empty( $options['debug'] );
     324    ?>
     325    <label>
     326        <input
     327            type="checkbox"
     328            name="fundy_network_options[debug]"
     329            value="yes"
     330            <?php \checked( $enabled, true ); ?>
     331        />
     332        <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     333    </label>
    166334    <?php
    167335}
  • dekode-fundraising/trunk/inc/settings-page.php

    r3382635 r3455489  
    99
    1010namespace Dekode\Fundraising\SettingsPage;
     11
     12use function Dekode\Fundraising\Settings\get_conversion_script_env;
     13use function Dekode\Fundraising\Settings\get_debug_enabled;
     14use function Dekode\Fundraising\Settings\get_disable_data_layer_event;
     15use function Dekode\Fundraising\Settings\get_forms_script_env;
     16use function Dekode\Fundraising\Settings\get_tracking_script_enabled;
     17use function Dekode\Fundraising\Settings\get_tracking_script_env;
     18use function Dekode\Fundraising\Settings\normalize_script_env;
    1119
    1220if ( ! \defined( 'ABSPATH' ) ) {
     
    4654            'sanitize_callback' => __NAMESPACE__ . '\\sanitize_options',
    4755            'default'           => [
    48                 'api_key'    => '',
    49                 'script_env' => 'prod',
     56                'api_key'                  => '',
     57                'forms_script'             => 'prod',
     58                'conversion_script'        => 'prod',
     59                'tracking_enabled'         => '',
     60                'tracking_script'          => 'prod',
     61                'disable_data_layer_event' => '',
     62                'debug'                    => '',
    5063            ],
    5164        ]
     
    5467    \add_settings_section(
    5568        'fundy_settings_section',
    56         \__( 'General Configuration', 'dekode-fundraising' ),
     69        \__( 'General', 'dekode-fundraising' ),
    5770        __NAMESPACE__ . '\\section_callback',
     71        'fundy_settings_page',
     72    );
     73
     74    \add_settings_section(
     75        'fundy_settings_section_advanced',
     76        \__( 'Advanced', 'dekode-fundraising' ),
     77        __NAMESPACE__ . '\\advanced_section_callback',
    5878        'fundy_settings_page',
    5979    );
     
    7898
    7999    \add_settings_field(
    80         'fundy_script_env',
    81         \__( 'Script Environment', 'dekode-fundraising' ),
    82         __NAMESPACE__ . '\\script_env_callback',
     100        'fundy_forms_script',
     101        \__( 'Forms Script', 'dekode-fundraising' ),
     102        __NAMESPACE__ . '\\forms_script_callback',
    83103        'fundy_settings_page',
    84104        'fundy_settings_section'
    85105    );
     106
     107    \add_settings_field(
     108        'fundy_conversion_script',
     109        \__( 'Conversion Script', 'dekode-fundraising' ),
     110        __NAMESPACE__ . '\\conversion_script_callback',
     111        'fundy_settings_page',
     112        'fundy_settings_section'
     113    );
     114
     115    \add_settings_field(
     116        'fundy_disable_data_layer_event',
     117        \__( 'Data Layer Event', 'dekode-fundraising' ),
     118        __NAMESPACE__ . '\\disable_data_layer_event_callback',
     119        'fundy_settings_page',
     120        'fundy_settings_section'
     121    );
     122
     123    \add_settings_field(
     124        'fundy_tracking_script',
     125        \__( 'Tracking Script', 'dekode-fundraising' ),
     126        __NAMESPACE__ . '\\tracking_script_callback',
     127        'fundy_settings_page',
     128        'fundy_settings_section'
     129    );
     130
     131    \add_settings_field(
     132        'fundy_debug',
     133        \__( 'Debug Mode', 'dekode-fundraising' ),
     134        __NAMESPACE__ . '\\debug_callback',
     135        'fundy_settings_page',
     136        'fundy_settings_section_advanced'
     137    );
     138
    86139}
    87140
     
    99152    if (\is_multisite() && 'yes' !== $sanitized['override_network']) {
    100153        $sanitized['api_key'] = '';
    101         $sanitized['script_env'] = '';
     154        $sanitized['forms_script'] = '';
     155        $sanitized['conversion_script'] = '';
     156        $sanitized['tracking_enabled'] = '';
     157        $sanitized['tracking_script'] = '';
     158        $sanitized['disable_data_layer_event'] = '';
     159        $sanitized['debug'] = '';
    102160
    103161        return $sanitized;
     
    108166        : '';
    109167
    110     $sanitized['script_env'] = ( isset( $input['script_env'] ) && 'dev' === $input['script_env'] )
    111         ? 'dev'
    112         : 'prod';
     168    $sanitized['forms_script'] = normalize_script_env( (string) ( $input['forms_script'] ?? '' ), 'prod' );
     169    $sanitized['conversion_script'] = normalize_script_env( (string) ( $input['conversion_script'] ?? '' ), 'prod' );
     170    $sanitized['tracking_enabled'] = ! empty( $input['tracking_enabled'] ) ? 'yes' : '';
     171    $sanitized['tracking_script'] = normalize_script_env( (string) ( $input['tracking_script'] ?? '' ), 'prod' );
     172    $sanitized['disable_data_layer_event'] = ! empty( $input['disable_data_layer_event'] ) ? 'yes' : '';
     173    $sanitized['debug'] = ! empty( $input['debug'] ) ? 'yes' : '';
    113174
    114175    return $sanitized;
     
    120181function section_callback(): void {
    121182    echo '<p>' . \esc_html__( 'If you are unsure about the settings here please talk to your Dekode Fundraising contact.', 'dekode-fundraising' ) . '</p>';
     183}
     184
     185/**
     186 * Advanced settings section callback.
     187 */
     188function advanced_section_callback(): void {
     189    echo '<p>' . \esc_html__( 'Advanced settings for troubleshooting and diagnostics.', 'dekode-fundraising' ) . '</p>';
    122190}
    123191
     
    160228
    161229/**
    162  * Field callback for the Script Environment.
    163  */
    164 function script_env_callback(): void {
    165     $options    = \get_option( 'fundy_options' );
    166     $script_env = isset( $options['script_env'] ) ? $options['script_env'] : 'prod';
     230 * Field callback for the Fundy Forms script.
     231 */
     232function forms_script_callback(): void {
     233    $options = \get_option( 'fundy_options', [] );
     234    $env     = get_forms_script_env();
    167235    ?>
    168236    <fieldset>
     
    170238            <input
    171239                type="radio"
    172                 name="fundy_options[script_env]"
     240                name="fundy_options[forms_script]"
    173241                value="dev"
    174                 <?php \checked( $script_env, 'dev' ); ?>
     242                <?php \checked( $env, 'dev' ); ?>
    175243                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
    176244            />
     
    181249            <input
    182250                type="radio"
    183                 name="fundy_options[script_env]"
     251                name="fundy_options[forms_script]"
    184252                value="prod"
    185                 <?php \checked( $script_env, 'prod' ); ?>
     253                <?php \checked( $env, 'prod' ); ?>
    186254                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
    187255            />
     
    189257        </label>
    190258    </fieldset>
     259    <?php
     260}
     261
     262/**
     263 * Field callback for the Fundy Conversion script.
     264 */
     265function conversion_script_callback(): void {
     266    $options = \get_option( 'fundy_options', [] );
     267    $env     = get_conversion_script_env();
     268    ?>
     269    <fieldset>
     270        <label>
     271            <input
     272                type="radio"
     273                name="fundy_options[conversion_script]"
     274                value="dev"
     275                <?php \checked( $env, 'dev' ); ?>
     276                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     277            />
     278            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     279        </label>
     280        <br>
     281        <label>
     282            <input
     283                type="radio"
     284                name="fundy_options[conversion_script]"
     285                value="prod"
     286                <?php \checked( $env, 'prod' ); ?>
     287                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     288            />
     289            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     290        </label>
     291    </fieldset>
     292    <?php
     293}
     294
     295/**
     296 * Field callback for the Tracking script.
     297 */
     298function tracking_script_callback(): void {
     299    $options = \get_option( 'fundy_options', [] );
     300    $enabled = get_tracking_script_enabled();
     301    $env     = get_tracking_script_env();
     302    ?>
     303    <p>
     304        <label>
     305            <input
     306                type="checkbox"
     307                name="fundy_options[tracking_enabled]"
     308                value="yes"
     309                <?php \checked( $enabled, true ); ?>
     310                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     311            />
     312            <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     313        </label>
     314    </p>
     315    <fieldset>
     316        <label>
     317            <input
     318                type="radio"
     319                name="fundy_options[tracking_script]"
     320                value="dev"
     321                <?php \checked( $env, 'dev' ); ?>
     322                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     323            />
     324            <?php \esc_html_e( 'Development', 'dekode-fundraising' ); ?>
     325        </label>
     326        <br>
     327        <label>
     328            <input
     329                type="radio"
     330                name="fundy_options[tracking_script]"
     331                value="prod"
     332                <?php \checked( $env, 'prod' ); ?>
     333                <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     334            />
     335            <?php \esc_html_e( 'Production', 'dekode-fundraising' ); ?>
     336        </label>
     337    </fieldset>
     338    <?php
     339}
     340
     341/**
     342 * Field callback for the disableDataLayerEvent setting.
     343 */
     344function disable_data_layer_event_callback(): void {
     345    $options = \get_option( 'fundy_options', [] );
     346    $enabled = get_disable_data_layer_event();
     347    ?>
     348    <label>
     349        <input
     350            type="checkbox"
     351            name="fundy_options[disable_data_layer_event]"
     352            value="yes"
     353            <?php \checked( $enabled, true ); ?>
     354            <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     355        />
     356        <?php \esc_html_e( 'Disable', 'dekode-fundraising' ); ?>
     357    </label>
     358    <p class="description"><?php \esc_html_e( 'Prevents pushing conversion events to the dataLayer.', 'dekode-fundraising' ); ?></p>
     359    <?php
     360}
     361
     362/**
     363 * Field callback for the Debug setting.
     364 */
     365function debug_callback(): void {
     366    $options = \get_option( 'fundy_options', [] );
     367    $enabled = get_debug_enabled();
     368    ?>
     369    <label>
     370        <input
     371            type="checkbox"
     372            name="fundy_options[debug]"
     373            value="yes"
     374            <?php \checked( $enabled, true ); ?>
     375            <?php \disabled( ( \is_multisite() && empty( $options['override_network'] ) ) ); ?>
     376        />
     377        <?php \esc_html_e( 'Enable', 'dekode-fundraising' ); ?>
     378    </label>
    191379    <?php
    192380}
  • dekode-fundraising/trunk/inc/settings.php

    r3382635 r3455489  
    1111
    1212/**
    13  * Retrieve the API key.
     13 * Retrieve a setting value, respecting multisite overrides.
     14 *
     15 * @param string $key     Option key.
     16 * @param mixed  $default Default value when not set.
     17 * @return mixed
    1418 */
    15 function get_api_key(): string {
     19function get_setting_value( string $key, mixed $default = '' ): mixed {
    1620    $site_options = \get_option( 'fundy_options', [] );
     21    if ( ! \is_array( $site_options ) ) {
     22        $site_options = [];
     23    }
    1724
    1825    if ( ! \is_multisite() ) {
    19         return $site_options['api_key'] ?? '';
     26        return $site_options[ $key ] ?? $default;
    2027    }
    2128
    2229    // Should site override network?
    2330    if ( ! empty( $site_options['override_network'] ) ) {
    24         return $site_options['api_key'] ?? '';
     31        return $site_options[ $key ] ?? $default;
    2532    }
    2633
    2734    $network_options = \get_network_option( null, 'fundy_network_options', [] );
     35    if ( ! \is_array( $network_options ) ) {
     36        $network_options = [];
     37    }
    2838
    29     return $network_options['api_key'] ?? '';
     39    return $network_options[ $key ] ?? $default;
     40}
     41
     42/**
     43 * Retrieve a setting value with a flag indicating if the key existed.
     44 *
     45 * @param string $key     Option key.
     46 * @param mixed  $default Default value when not set.
     47 * @return array{0: mixed, 1: bool} [value, exists]
     48 */
     49function get_setting_value_with_presence( string $key, mixed $default = '' ): array {
     50    $site_options = \get_option( 'fundy_options', [] );
     51    if ( ! \is_array( $site_options ) ) {
     52        $site_options = [];
     53    }
     54
     55    if ( ! \is_multisite() ) {
     56        return [
     57            $site_options[ $key ] ?? $default,
     58            \array_key_exists( $key, $site_options ),
     59        ];
     60    }
     61
     62    if ( ! empty( $site_options['override_network'] ) ) {
     63        return [
     64            $site_options[ $key ] ?? $default,
     65            \array_key_exists( $key, $site_options ),
     66        ];
     67    }
     68
     69    $network_options = \get_network_option( null, 'fundy_network_options', [] );
     70    if ( ! \is_array( $network_options ) ) {
     71        $network_options = [];
     72    }
     73
     74    return [
     75        $network_options[ $key ] ?? $default,
     76        \array_key_exists( $key, $network_options ),
     77    ];
     78}
     79
     80/**
     81 * Normalize script environment values.
     82 */
     83function normalize_script_env( string $value, string $default = 'prod' ): string {
     84    $value = \strtolower( $value );
     85
     86    if ( \in_array( $value, [ 'dev', 'prod' ], true ) ) {
     87        return $value;
     88    }
     89
     90    if ( 'development' === $value ) {
     91        return 'dev';
     92    }
     93
     94    if ( 'latest' === $value ) {
     95        return 'prod';
     96    }
     97
     98    return $default;
     99}
     100
     101/**
     102 * Retrieve the API key.
     103 */
     104function get_api_key(): string {
     105    return (string) get_setting_value( 'api_key', '' );
     106}
     107
     108/**
     109 * Retrieve the forms script environment ('dev' or 'prod').
     110 */
     111function get_forms_script_env(): string {
     112    $value = get_setting_value( 'forms_script', '' );
     113
     114    if ( '' !== $value ) {
     115        return normalize_script_env( (string) $value, 'prod' );
     116    }
     117
     118    $legacy = get_setting_value( 'script_env', '' );
     119
     120    if ( '' !== $legacy ) {
     121        return normalize_script_env( (string) $legacy, 'prod' );
     122    }
     123
     124    return 'prod';
     125}
     126
     127/**
     128 * Retrieve the conversion script environment ('dev' or 'prod').
     129 */
     130function get_conversion_script_env(): string {
     131    $value = get_setting_value( 'conversion_script', '' );
     132
     133    if ( '' !== $value ) {
     134        return normalize_script_env( (string) $value, 'prod' );
     135    }
     136
     137    $legacy = get_setting_value( 'script_env', '' );
     138
     139    if ( '' !== $legacy ) {
     140        return normalize_script_env( (string) $legacy, 'prod' );
     141    }
     142
     143    return 'prod';
     144}
     145
     146/**
     147 * Check if the tracking script is enabled.
     148 */
     149function get_tracking_script_enabled(): bool {
     150    [ $enabled, $exists ] = get_setting_value_with_presence( 'tracking_enabled', '' );
     151
     152    if ( ! $exists ) {
     153        return false;
     154    }
     155
     156    return ! empty( $enabled );
     157}
     158
     159/**
     160 * Retrieve the tracking script environment ('dev' or 'prod').
     161 */
     162function get_tracking_script_env(): string {
     163    $value = get_setting_value( 'tracking_script', '' );
     164
     165    if ( '' !== $value ) {
     166        return normalize_script_env( (string) $value, 'prod' );
     167    }
     168
     169    return 'prod';
     170}
     171
     172/**
     173 * Retrieve the disableDataLayerEvent config value.
     174 */
     175function get_disable_data_layer_event(): bool {
     176    return ! empty( get_setting_value( 'disable_data_layer_event', '' ) );
     177}
     178
     179/**
     180 * Retrieve the debug config value.
     181 */
     182function get_debug_enabled(): bool {
     183    return ! empty( get_setting_value( 'debug', '' ) );
    30184}
    31185
     
    34188 */
    35189function get_script_env(): string {
    36     $site_options = \get_option( 'fundy_options', [] );
    37 
    38     if ( ! \is_multisite() ) {
    39         return $site_options['script_env'] ?? 'prod';
    40     }
    41 
    42     // Should site override network?
    43     if ( ! empty( $site_options['override_network'] ) ) {
    44         return $site_options['script_env'] ?? 'prod';
    45     }
    46 
    47     $network_options = \get_network_option( null, 'fundy_network_options', [] );
    48 
    49     return $network_options['script_env'] ?? 'prod';
     190    return get_forms_script_env();
    50191}
  • dekode-fundraising/trunk/inc/shortcodes.php

    r3382635 r3455489  
    5757
    5858    \wp_enqueue_script( 'fundy-form-script' );
    59     \wp_enqueue_style( 'fundy-form-style' );
     59
     60    if ( \apply_filters( 'fundy/enqueue/form_styles', true ) ) {
     61        \wp_enqueue_style( 'fundy-form-style' );
     62    }
    6063
    6164    return \sprintf( '
  • dekode-fundraising/trunk/package.json

    r3408236 r3455489  
    44    "private": true,
    55    "engines": {
    6         "node": "22",
     6        "node": "24",
    77        "npm": ">=10",
    88        "yarn": "Please use npm"
     
    1010    "devDependencies": {
    1111        "@playwright/test": "~1.57.0",
    12         "@wordpress/dom-ready": "~4.36.0",
    13         "@wordpress/e2e-test-utils-playwright": "~1.31.0",
    14         "@wordpress/element": "~6.36.0",
    15         "@wordpress/env": "~10.31.0",
    16         "@wordpress/eslint-plugin": "~22.15.0",
    17         "@wordpress/scripts": "~31.1.0",
    18         "@wordpress/stylelint-config": "~23.23.0",
    19         "eslint-plugin-prettier": "~5.5.4",
     12        "@wordpress/dom-ready": "~4.37.0",
     13        "@wordpress/e2e-test-utils-playwright": "~1.37.0",
     14        "@wordpress/element": "~6.37.0",
     15        "@wordpress/env": "~10.37.0",
     16        "@wordpress/eslint-plugin": "~23.0.0",
     17        "@wordpress/scripts": "~27.9.0",
     18        "@wordpress/stylelint-config": "~23.29.0",
     19        "eslint-plugin-prettier": "~5.5.5",
    2020        "husky": "~9.1.7",
    21         "lint-staged": "~16.1.5",
     21        "lint-staged": "~16.2.7",
    2222        "prettier": "~3.6.2",
    23         "stylelint-order": "~7.0.0",
    24         "typescript": "~5.9.2"
     23        "stylelint-order": "~7.0.1",
     24        "typescript": "~5.9.3"
    2525    },
    2626    "scripts": {
Note: See TracChangeset for help on using the changeset viewer.