@automattic/newspack-blocks 4.33.1 → 4.34.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/editor-rtl.css +4 -3
- package/dist/editor.asset.php +1 -1
- package/dist/editor.css +4 -3
- package/dist/editor.js +14 -14
- package/dist/modal.asset.php +1 -1
- package/dist/modal.js +1 -1
- package/includes/class-modal-checkout.php +248 -6
- package/includes/class-newspack-blocks-api.php +8 -0
- package/includes/class-newspack-blocks.php +38 -0
- package/languages/newspack-blocks-de_DE.po +124 -119
- package/languages/newspack-blocks-es_ES.po +124 -119
- package/languages/newspack-blocks-fr_BE.po +124 -119
- package/languages/newspack-blocks-nb_NO.po +124 -119
- package/languages/newspack-blocks-pt_PT.po +124 -119
- package/languages/newspack-blocks.pot +129 -125
- package/newspack-blocks.php +2 -2
- package/package.json +2 -2
- package/src/blocks/author-list/class-wp-rest-newspack-author-list-controller.php +6 -1
- package/src/blocks/author-profile/class-wp-rest-newspack-authors-controller.php +196 -48
- package/src/blocks/author-profile/edit.js +23 -65
- package/src/blocks/author-profile/single-author.js +7 -12
- package/src/blocks/author-profile/social-links.js +25 -0
- package/src/blocks/author-profile/social-links.test.js +42 -0
- package/src/blocks/checkout-button/view.php +4 -2
- package/src/blocks/homepage-articles/templates/article.php +1 -18
- package/src/modal-checkout/checkout-button-trigger.js +162 -24
- package/src/modal-checkout/checkout-button-trigger.test.js +149 -9
- package/src/modal-checkout/modal.js +31 -1
- package/src/shared/js/author-fetch.js +217 -0
- package/src/shared/js/author-fetch.test.js +230 -0
- package/vendor/composer/installed.php +2 -2
package/dist/modal.asset.php
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<?php return array('dependencies' => array(), 'version' => '
|
|
1
|
+
<?php return array('dependencies' => array(), 'version' => 'ad0265d8573d5220c5fe');
|
package/dist/modal.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";function e(e,t=!1){const n=e.querySelectorAll('button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');if(0===n.length)return!1;const o=n?.[0];let c;o.focus(),t?(document.addEventListener("keydown",function(e){if(("Tab"===e.key||9===e.keyCode)&&e.shiftKey&&document.activeElement===o){const n=t.contentWindow.document,o=n.getElementById("checkout-after-success");c=null!==o?o:n.getElementById("checkout_cancel"),c.focus(),e.preventDefault()}}),document.getElementById("newspack-a11y-last-element").addEventListener("focus",()=>{o.focus()})):(c=n[n.length-1],document.addEventListener("keydown",function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===o&&(c.focus(),e.preventDefault()):document.activeElement===c&&(o.focus(),e.preventDefault()))}))}const t=(e,t={})=>({...t,action:e}),n=["action","action_type","amount","currency","product_id","product_type","quantity","variation_id","variation_ids","is_variable","is_grouped","child_ids","price_summary","newspack_popup_id","prompt_title","gate_post_id","contextual_prompt_post_id","contextual_prompt_placement","contextual_prompt_condition","recurrence","referrer"],o=(e,t="np_modal_checkout_interaction")=>{if("function"==typeof window.gtag&&e){const o={};for(const t of n)e[t]&&("boolean"==typeof e[t]?e[t]=e[t]?"yes":"no":"true"===e[t]?e[t]="yes":"false"===e[t]&&(e[t]="no"),o[t]=e[t].toString());window.gtag("event",t,o)}},c=e=>{if("function"!=typeof window.gtag)return;let n="opened";const{amount:c="",is_variable:a="",is_grouped:r="",price:i="",variation_id:s=""}=e,l={...e};(c||i)&&(l.amount=c||i),a&&!s&&(n="opened_variations"),r&&(n="opened_grouped");const u=t(n,l);o(u)};function a(e,t=null){const n=document.createElement("input");return n.type="hidden",n.name=e,t&&(n.value=t),n}function r(e){e.requestSubmit(e.querySelector('button[type="submit"]'))}function i(e){const t="string"==typeof e?document.getElementById(e):e;if(!t)return console.warn("No container found for checkout data"),{};let n={};if("FORM"===t.tagName){const e=new FormData(t);n=Object.fromEntries(e)}const o=t.dataset.checkout;if(!o)return console.warn("No checkout data found"),n;try{n={...n,...JSON.parse(o)}}catch(e){console.warn("Error parsing checkout data")}const c=new URL(t.ownerDocument.defaultView.location.href);return c.searchParams.get("action_type")&&(n.action_type=c.searchParams.get("action_type")),n}const s=e=>{if("function"!=typeof window.gtag)return;e=e||i("newspack_modal_checkout");const n=t("dismissed",e);o(n)};function l(e){const t=e&&e.dataset?e.dataset.checkout:null;if(!t)return null;try{return JSON.parse(t)}catch(e){return null}}function u(e,t,n=null){const o=e.querySelectorAll(".wp-block-newspack-blocks-checkout-button"),c=null!=n&&""!==String(n);let a=null;return o.forEach(e=>{if(a)return;const o=e.querySelector("form"),r=l(o);r&&String(r.product_id)===String(t)&&(c&&String(r.variation_id)!==String(n)||(a=o))}),a}const d=["after_success_behavior","after_success_url","after_success_button_label","after_success_token","gate_post_id","newspack_popup_id","prompt_title","contextual_prompt_post_id","contextual_prompt_placement","contextual_prompt_condition","coupon","quantity"];const p=["tiered","frequency","untiered"],m=["once","month","year"];const h={gate:"gate_post_id",prompt:"newspack_popup_id"};const f=newspackBlocksModal.newspack_class_prefix,y="newspack_modal_checkout_iframe",_="newspack_modal_checkout_container",w=`${f}__modal`,k="newspack-blocks__modal-variation",g=`${f}__processing-payment-text`,v=newspackBlocksModal.processing_payment_messages;let b=!1,S=newspackBlocksModal.labels.checkout_modal_title,E=null;const q=e=>{e.overlayId&&window.newspackReaderActivation?.overlays&&window.newspackReaderActivation?.overlays.remove(e.overlayId),e.setAttribute("data-state","closed"),document.body.style.overflow="auto"};window.onpageshow=e=>{e.persisted&&(document.querySelectorAll(".modal-processing").forEach(e=>e.classList.remove("modal-processing")),document.querySelectorAll(".non-modal-checkout-loading").forEach(e=>e.classList.remove("non-modal-checkout-loading")),document.querySelectorAll(`.${w}-container`).forEach(e=>q(e)))};const A=new CustomEvent("checkout-closed");var L;window.newspackRAS=window.newspackRAS||[],L=()=>{const t=document.querySelector("#newspack_modal_checkout");if(!t)return;const n=t.querySelector(`.${w}__content`),o=a("modal_checkout","1"),L=n.querySelector(`.${f}__spinner`);let $=document.querySelector(".newspack-reader__account-link")?.[0];const R="600px",M=document.createElement("iframe");M.name=y,M.style.height=R,M.style.visibility="hidden";const x=e=>{D.observe(e),"none"!==L.style.display&&(L.style.display="none"),"visible"!==M.style.visibility&&(M.style.visibility="visible"),M._ready=!0};!function(e,t,n){e._ready=!1,e._readyTimer&&clearTimeout(e._readyTimer);let o=!1,c="";function a(){o||(o=!0,clearTimeout(e._readyTimer),t.call(this))}function r(){"complete"===this.readyState&&a.call(this)}function i(){e._ready=!1,n&&n(),e._readyTimer&&clearTimeout(e._readyTimer);const t=e.contentDocument||e.contentWindow?.document;t&&(t.removeEventListener("DOMContentLoaded",a),t.removeEventListener("readystatechange",r))}function s(){if(e._ready)return void i();const t=e.contentDocument||e.contentWindow?.document;t&&0!==t.URL.indexOf("about:")?"complete"===t?.readyState?a.call(t):(t.addEventListener("DOMContentLoaded",a),t.addEventListener("readystatechange",r)):e._readyTimer=setTimeout(s,10)}e._observer||(e._observer=new MutationObserver(e=>{e.forEach(e=>{"attributes"===e.type&&"src"===e.attributeName&&(o=!1,i(),s())})}),e._observer.observe(e,{attributes:!0})),e._locationObserver||(e._locationObserver=setInterval(function(){const t=e.contentDocument||e.contentWindow?.document;t&&t.URL!==c&&(c=t.URL,o=!1,i(),s())},50)),s()}(M,function(){const n=M.contentWindow?.location;if(window.newspackReaderActivation&&n?.href?.includes("order-received")){const e=window.newspackReaderActivation,t=new Proxy(new URLSearchParams(n.search),{get:(e,t)=>e.get(t)});t.email&&(e.setReaderEmail(t.email),e.setAuthenticated(!0))}const o=M?.contentDocument?.querySelector(`#${_}`);if(!o)return;const c=i(o.querySelector("#modal-checkout-product-details")),a=document.createElement("p");a.classList.add(g);let r=[];const s=()=>{r.forEach(e=>clearTimeout(e)),r=[]},l=()=>{L.style.display="none",s(),L.querySelectorAll(`.${g}`).forEach(e=>e.remove())};!function(e,t){e.checkoutCancel?t():e.addEventListener("checkout-cancel",t)}(o,()=>{I()}),function(e,t){e.checkoutPlaceOrderStart?t():e.addEventListener("checkout-place-order-start",t)}(o,e=>{L.querySelectorAll(`.${g}`).forEach(e=>e.remove()),L.style.display="flex",s(),a.textContent=v[0]?.text??"",v.slice(1).forEach(({text:t,delay:n})=>{const o=setTimeout(()=>{e.target.dispatchEvent(new CustomEvent("checkout-place-order-processing")),a.textContent=t},n);r.push(o)}),L.appendChild(a)}),function(e,t){e.checkoutPlaceOrderError?t():e.addEventListener("checkout-place-order-error",t)}(o,l),function(e,t){e.checkoutReady?t():e.addEventListener("checkout-ready",t)}(o,()=>{if(t.initialErrors){const e=document.createElement("div");e.classList.add("woocommerce-error"),e.textContent=t.initialErrors,o.prepend(e),delete t.initialErrors}j(),U(S),M.contentWindow?.newspackBlocksModalCheckout?.checkout_nonce&&(t.checkout_nonce=M.contentWindow.newspackBlocksModalCheckout.checkout_nonce),x(o)}),function(e,t){e.checkoutComplete?t():e.addEventListener("checkout-complete",t)}(o,()=>{window.newspackRAS.push(["checkout_completed",c]),window?.newspackReaderActivation?.refreshNewslettersSignupModal&&window?.newspackReaderActivation?.getReader()?.email&&window.newspackReaderActivation.refreshNewslettersSignupModal(window.newspackReaderActivation.getReader().email),j("small"),U(newspackBlocksModal.labels.thankyou_modal_title),x(o),e(t.querySelector(`.${w}`)),l()}),function(e,t){e.checkoutPlaceOrderCriticalError?t():e.addEventListener("checkout-place-order-critical-error",t)}(o,()=>{var e;(e=E)&&(I(),L.style.display="none",t.initialErrors=newspackBlocksModal.labels.critical_error,e.requestSubmit(e.querySelector('button[type="submit"]')),l())})},()=>{L.style.display="flex"});const C=e=>new Promise((t,n)=>{const o=new URLSearchParams(e);o.append("action","modal_checkout_request"),fetch(newspackBlocksModal.ajax_url+"?"+o.toString()).then(e=>{e.ok||n(e),e.json().then(e=>{t(e.url)}).catch(n)}).catch(n)}),B=()=>"undefined"!=typeof newspack_ras_config&&!newspack_ras_config?.is_logged_in&&!window?.newspackReaderActivation?.getReader?.()?.authenticated&&newspackBlocksModal?.is_registration_required&&window?.newspackReaderActivation?.openAuthModal,P=t=>{const n=!newspackBlocksModal.has_unsupported_payment_gateway;n||t.preventDefault();const o=t.target;o.classList.add("modal-processing"),function(e){if(!e||"function"!=typeof e.querySelector)return!1;if(e.closest(".newspack-content-gate__gate"))return!1;const t=function(){let e,t;try{e=window.sessionStorage.getItem("newspack_cta_attribution")}catch(e){return null}if(!e)return null;try{t=JSON.parse(e)}catch(e){return null}return t&&1===t.v&&h[t.type]&&t.id?"number"!=typeof t.ts||Date.now()-t.ts>18e5?null:t:null}();if(!t)return!1;const n=h[t.type];if(e.querySelector(`input[name="${n}"]`))return!1;const o=document.createElement("input");o.type="hidden",o.name=n,o.value=t.id,e.prepend(o)}(o);const u=i(o);if(u.newspack_donate){const e=u.donation_frequency,t=[...o.querySelectorAll(`.donation-tier__${e}, .donation-frequency__${e}`)],n=u.donation_tier_index;let c,a;n?(c=t[n],a=u[`donation_value_${e}`]):(c=t[0],u[`donation_value_${e}_untiered`]?a=u[`donation_value_${e}_untiered`]:(a=u[`donation_value_${e}`],"other"===a&&(a=u[`donation_value_${e}_other`])));const r=i(c);for(const e in r)u[e]=r[e];u.amount=a,u.price_summary=u.summary_template.replace("{{PRICE}}",function(e,t="USD"){return parseFloat(e).toLocaleString(document.documentElement.lang,{style:"currency",currency:t,currencyDisplay:"narrowSymbol"})}(u.amount,u.currency))}u&&Object.keys(u).forEach(e=>{0===o.querySelectorAll('input[name="'+e+'"]').length&&o.prepend(a(e,u[e]))}),u.variation_id||($=t.submitter);const p=document.querySelectorAll(`.${k}`);if(p.forEach(e=>{(B()||n)&&q(e)}),u.is_grouped||u.is_variable&&!u.variation_id){const n=[...p].find(e=>e.dataset.productId===u.product_id);if(n)return n.querySelectorAll(`form[target="${y}"]`).forEach(e=>{!function(e,t,n=d){if(!e||!t)return;const o=e.ownerDocument;n.forEach(n=>{if(e.querySelectorAll(`input[type="hidden"][name="${n}"]`).forEach(e=>e.remove()),function(e,t){return!!e.querySelector(`input[name="${t}"]:not([type="hidden"])`)}(e,n))return;const c=t[n],a=null==c?"":String(c);if(!a)return;const r=o.createElement("input");r.type="hidden",r.name=n,r.value=a,e.prepend(r)})}(e,u);const t=l(e);t&&Object.keys(t).forEach(n=>{0===e.querySelectorAll('input[name="'+n+'"]').length&&e.prepend(a(n,t[n]))})}),t.preventDefault(),o.classList.remove("modal-processing"),O(n),e(n,!1),b||c(u),void document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u))}if(n||B()){if(o.classList.remove("modal-processing"),b||c(u),b=!0,B()){t.preventDefault();const e=C(u);e.then(e=>{window.newspackReaderActivation?.setPendingCheckout?.(e)}),window.newspackReaderActivation.openAuthModal({title:newspackBlocksModal.labels.auth_modal_title,onSuccess:(t,o)=>{e.then(e=>{o?.registered&&n&&(e+=`&${newspackBlocksModal.checkout_registration_flag}=1`),n?r(T(e)):C(u).then(window.location.href=e)}).catch(e=>{console.warn("Unable to generate cart:",e),I()})},onError:()=>{I()},onDismiss:()=>{s(u),b=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout")},skipSuccess:!0,skipNewslettersSignup:!0,labels:{signin:{title:newspackBlocksModal.labels.signin_modal_title},register:{title:newspackBlocksModal.labels.register_modal_title}},trigger:t.submitter,closeOnSuccess:n})}else N(),document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u));E=o}else C(u).then(e=>{window.location.href=e}),(!u.is_variable||u.variation_id)&&o.querySelectorAll("button[type=submit]:focus").forEach(e=>{e.classList.add("non-modal-checkout-loading");const t=e.innerHTML;e.innerHTML="<span>"+t+"</span>"})},T=e=>{const t=document.createElement("form");t.method="POST",t.action=e,t.target=y,t.style.display="none";const n=document.createElement("button");return n.setAttribute("type","submit"),t.appendChild(n),document.body.appendChild(t),t.addEventListener("submit",P),t},D=new ResizeObserver(e=>{if(!e||!e.length)return;if(!M.contentDocument)return;const o=e[0].contentRect;if(o){const e=.01*Math.max(document.documentElement.clientHeight,window.innerHeight||0)*90-(t.querySelector(`.${w}__header`)?.offsetHeight||0),c=o.top+o.bottom,a=Math.min(c,e);if(0===a)return void(M.style.visibility="hidden");n.style.height=a+"px",M.style.height=a+"px"}}),I=()=>{const e=M?.contentDocument?.querySelector(`#${_}`),o=e?.querySelector('input[name="after_success_url"]'),c=e?.querySelector('input[name="after_success_behavior"]'),a=document?.querySelector(".newspack-newsletters-signup-modal"),r=i(e?.querySelector("#modal-checkout-product-details"));e?.checkoutComplete||(async()=>{const e=new FormData;newspackBlocksModal.has_unsupported_payment_gateway||e.append("modal_checkout","1"),e.append("action","abandon_modal_checkout"),e.append("_wpnonce",t.checkout_nonce),t.checkout_nonce=null;try{await fetch(newspackBlocksModal.ajax_url,{method:"POST",body:e})}catch(e){console.warn("Unable to empty cart:",e)}})();const l=!(M.contentDocument&&o&&c&&e?.checkoutComplete);if((l||a)&&(L.style.display="flex",M&&n.contains(M)&&(M._ready=!1,M.src="about:blank",M.style.height=R,M.style.visibility="hidden",n.style.height=R,n.removeChild(M)),D&&D.disconnect(),document.querySelectorAll(`.${w}-container`).forEach(e=>q(e)),$&&$.focus(),document.dispatchEvent(A)),e?.checkoutComplete){const e=()=>{if(o&&c){const e=o.getAttribute("value"),t=c.getAttribute("value");if("custom"===t)window.location.href=e;else if("referrer"===t){const e=document.referrer;let t=!1;if(e)try{new URL(e).origin===window.location.origin&&(window.location.href=e,t=!0)}catch(e){}t||window.history.back()}}window?.newspackReaderActivation?.setPendingCheckout?.(),b=!1};"subscription_switch"!==r.action_type&&window?.newspackReaderActivation?.openNewslettersSignupModal?window.newspackReaderActivation.openNewslettersSignupModal({onSuccess:e,onError:e,closeOnSuccess:l}):e(),l&&(S=newspackBlocksModal.labels.checkout_modal_title,j(),U(S))}else window?.newspackReaderActivation?.setPendingCheckout?.(),s(),b=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout");document.removeEventListener("keydown",W)},N=o=>{o&&(M.src=o),L.style.display="flex",O(t),n.appendChild(M),t.addEventListener("click",e=>{e.target===t&&I()}),e(t,M),document.addEventListener("keydown",W)},O=e=>{window.newspackReaderActivation?.overlays&&(e.overlayId=window.newspackReaderActivation?.overlays.add()),e.setAttribute("data-state","open"),document.body.style.overflow="hidden"},U=e=>{const n=t.querySelector(`.${w}__header h2`);n&&(n.innerText=e)},j=(e="default")=>{const n=t.querySelector(`.${w}`);n&&("small"===e?n.classList.add(`${w}--small`):n.classList.remove(`${w}--small`))};t.querySelectorAll(`.${w}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),I()})}),document.querySelectorAll(".newspack-blocks__modal-variation").forEach(e=>{e.addEventListener("click",t=>{t.target===e&&I()}),e.querySelectorAll(`.${w}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),I()})})});const W=e=>{"Escape"===e.key&&I()};document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc, .wp-block-newspack-blocks-checkout-button, .newspack-blocks__modal-variation").forEach(e=>{e.querySelectorAll("form").forEach(e=>{newspackBlocksModal.has_unsupported_payment_gateway||e.prepend(o.cloneNode()),e.target=y,e.addEventListener("submit",P)})});const F=["checkout","type","layout","frequency","amount","other","product_id","variation_id"],H=()=>{const e=new URL(window.location.href);F.forEach(t=>e.searchParams.delete(t)),window.history.replaceState(null,null,e.href)},J=(e,t,n,o=null)=>{const c=function(e,{layout:t,frequency:n,amount:o}){if(!function(e,t,n){return!(!p.includes(e)||!m.includes(t))&&("other"===n?"frequency"===e:/^\d+(\.\d+)?$/.test(n))}(t,n,o))return{status:"invalid-params"};let c=null;for(const a of e.querySelectorAll(".wpbnbd.wpbnbd--platform-wc form")){const e=a.closest(".wpbnbd--tiers-based");if("tiered"===t){if(!e)continue;const t=a.querySelector(`.wpbnbd__tiers__amount [data-frequency-slug="${n}"][data-amount="${o}"]`);if(!t)continue;const r=parseInt(t.getAttribute("data-tier-index"));if(isNaN(r))continue;const i=a.querySelector(`button[data-frequency-slug="${n}"]`);if(!i&&!a.querySelector(`input[name="donation_frequency"][value="${n}"]`))continue;if(!e.hasAttribute("data-tiers-based-ready")){c||(c=a);continue}return{status:"tiered",form:a,frequencyButton:i,tierIndex:r}}if(e)continue;const r=a.querySelector(`input[name="donation_frequency"][value="${n}"]`);if(!r)continue;const i="untiered"===t?a.querySelector(`input[name="donation_value_${n}_untiered"]`):a.querySelector(`input[name="donation_value_${n}"][value="${o}"]`);if(i)return{status:t,form:a,frequencyInput:r,amountInput:i}}return c?{status:"not-ready",form:c}:{status:"no-match"}}(document,{layout:e,frequency:t,amount:n}),a=`layout "${e}", frequency "${t}" and amount "${n}"`;if("invalid-params"===c.status)return console.warn(`Newspack modal checkout: invalid donate trigger parameters (${a}). The checkout was not triggered.`),!1;if("no-match"===c.status)return console.warn(`Newspack modal checkout: no donate form matches ${a}. The checkout was not triggered.`),!1;if("not-ready"===c.status){const c=setTimeout(()=>{console.warn(`Newspack modal checkout: the donate form matching ${a} never finished initializing. The checkout was not triggered; the URL params were kept so a reload can retry.`)},5e3);return document.addEventListener("newspack-tiers-based-ready",()=>{clearTimeout(c),J(e,t,n,o)&&H()},{once:!0}),!1}const{form:i}=c;if("tiered"===c.status){c.frequencyButton&&c.frequencyButton.click();const e=i.querySelector(`button[type="submit"][data-tier-index="${c.tierIndex}"]`);return e?(e.click(),!0):(console.warn(`Newspack modal checkout: no tier submit button matches ${a}. The checkout was not triggered.`),!1)}if(c.frequencyInput.checked=!0,"untiered"===c.status)c.amountInput.value=n;else if("other"===n){c.amountInput.click();const e=i.querySelector(`input[name="donation_value_${t}_other"]`);e&&o&&(e.value=o)}else c.amountInput.checked=!0;return i.checkValidity()?(r(i),!0):(console.warn(`Newspack modal checkout: the donate form rejected the values for ${a}. The checkout was not triggered.`),!1)};(()=>{const e=new URLSearchParams(window.location.search);if(!e.has("checkout"))return;let t=!0;const n=e.get("type");if("donate"===n){const n=e.get("layout"),o=e.get("frequency"),c=e.get("amount"),a=e.get("other");n&&o&&c?t=J(n,o,c,a):(t=!1,console.warn("Newspack modal checkout: donate trigger is missing layout, frequency or amount. The checkout was not triggered."))}else if("checkout_button"===n){const n=e.get("product_id"),o=e.get("variation_id");n?t=((e,t=null)=>{const n=function(e,t,n,o={}){const{allowProductOnlyFallback:c=!1}=o;if(null==n||""===String(n))return u(e,t,null);const a=u(e,t,n);if(a)return a;const r=function(e,t,n,o={}){const{variationModalClassPrefix:c,iframeName:a}=o,r=[...e.querySelectorAll(`.${c}`)].find(e=>String(e.dataset.productId)===String(t));if(!r)return null;const i=r.querySelectorAll("form"),s=a?[...i].find(e=>e.getAttribute("target")===a):i[0];if(!s)return null;const l=[...s.querySelectorAll('input[type="radio"][name="product_id"]')].find(e=>String(e.value)===String(n));return l?(l.checked=!0,s):null}(e,t,n,o);return r?(function(e,t,n=d){if(!e||!t)return;const o=t.ownerDocument,c=new FormData(e);n.forEach(e=>{if(t.querySelector(`input[name="${e}"]`))return;const n=c.getAll(e).filter(e=>"string"==typeof e&&e);if(!n.length)return;const a=o.createElement("input");a.type="hidden",a.name=e,a.value=n[n.length-1],t.prepend(a)})}(function(e,t){const n=e.querySelectorAll(".wp-block-newspack-blocks-checkout-button");let o=null,c=null;return n.forEach(e=>{if(c)return;const n=e.querySelector("form"),a=l(n);a&&String(a.product_id)===String(t)&&(a.variation_id?o=o||n:c=n)}),c||o}(e,t),r),r):c?u(e,t,null):null}(document,e,t,{variationModalClassPrefix:k,iframeName:y});if(n)return r(n),!0;const o=`Newspack modal checkout: no checkout form found for product_id "${e}"`+(t?` and variation_id "${t}"`:"")+". The checkout was not triggered.";return console.warn(o),!1})(n,o):(t=!1,console.warn("Newspack modal checkout: checkout_button trigger is missing product_id. The checkout was not triggered."))}else{const e=window.newspackReaderActivation?.getPendingCheckout?.();e&&r(T(e))}t&&H()})(),window.newspackOpenModalCheckout=({url:e=null,title:t=null,actionType:n=null,afterSuccess:o={},quantity:c=null,onCheckoutComplete:a=null,onClose:r=null})=>{if(S=t||newspackBlocksModal.labels.checkout_modal_title,U(S),(e=new URL(e||newspackBlocksModal.checkout_url)).searchParams.has("my_account_checkout")&&e.searchParams.delete("my_account_checkout"),e.searchParams.has("modal_checkout")||e.searchParams.set("modal_checkout","1"),n&&e.searchParams.set("action_type",n),c&&parseInt(c,10)>1&&e.searchParams.set("quantity",String(parseInt(c,10))),o?.url&&e.searchParams.set("after_success_url",o.url),(o?.behavior||o?.url)&&e.searchParams.set("after_success_behavior",o.behavior||"custom"),o?.buttonLabel&&e.searchParams.set("after_success_button_label",o.buttonLabel),a){const e=({detail:{action:e,data:t}})=>{"checkout_completed"===e&&a(t)};window.newspackRAS.push(t=>{t.on("activity",e);const n=()=>{t.off("activity",e),document.removeEventListener("checkout-closed",n)};document.addEventListener("checkout-closed",n)})}if(r){const e=()=>{r(),document.removeEventListener("checkout-closed",e)};document.addEventListener("checkout-closed",e)}N(e.toString())},window.newspackCloseModalCheckout=I},"undefined"!=typeof document&&("complete"!==document.readyState&&"interactive"!==document.readyState?document.addEventListener("DOMContentLoaded",L):L())})();
|
|
1
|
+
(()=>{"use strict";function e(e,t=!1){const n=e.querySelectorAll('button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])');if(0===n.length)return!1;const o=n?.[0];let c;o.focus(),t?(document.addEventListener("keydown",function(e){if(("Tab"===e.key||9===e.keyCode)&&e.shiftKey&&document.activeElement===o){const n=t.contentWindow.document,o=n.getElementById("checkout-after-success");c=null!==o?o:n.getElementById("checkout_cancel"),c.focus(),e.preventDefault()}}),document.getElementById("newspack-a11y-last-element").addEventListener("focus",()=>{o.focus()})):(c=n[n.length-1],document.addEventListener("keydown",function(e){("Tab"===e.key||9===e.keyCode)&&(e.shiftKey?document.activeElement===o&&(c.focus(),e.preventDefault()):document.activeElement===c&&(o.focus(),e.preventDefault()))}))}const t=(e,t={})=>({...t,action:e}),n=["action","action_type","amount","currency","product_id","product_type","quantity","variation_id","variation_ids","is_variable","is_grouped","child_ids","price_summary","newspack_popup_id","prompt_title","gate_post_id","contextual_prompt_post_id","contextual_prompt_placement","contextual_prompt_condition","recurrence","referrer"],o=(e,t="np_modal_checkout_interaction")=>{if("function"==typeof window.gtag&&e){const o={};for(const t of n)e[t]&&("boolean"==typeof e[t]?e[t]=e[t]?"yes":"no":"true"===e[t]?e[t]="yes":"false"===e[t]&&(e[t]="no"),o[t]=e[t].toString());window.gtag("event",t,o)}},c=e=>{if("function"!=typeof window.gtag)return;let n="opened";const{amount:c="",is_variable:r="",is_grouped:a="",price:i="",variation_id:s=""}=e,l={...e};(c||i)&&(l.amount=c||i),r&&!s&&(n="opened_variations"),a&&(n="opened_grouped");const u=t(n,l);o(u)};function r(e,t=null){const n=document.createElement("input");return n.type="hidden",n.name=e,t&&(n.value=t),n}function a(e){e.requestSubmit(e.querySelector('button[type="submit"]'))}function i(e){const t="string"==typeof e?document.getElementById(e):e;if(!t)return console.warn("No container found for checkout data"),{};let n={};if("FORM"===t.tagName){const e=new FormData(t);n=Object.fromEntries(e)}const o=t.dataset.checkout;if(!o)return console.warn("No checkout data found"),n;try{n={...n,...JSON.parse(o)}}catch(e){console.warn("Error parsing checkout data")}const c=new URL(t.ownerDocument.defaultView.location.href);return c.searchParams.get("action_type")&&(n.action_type=c.searchParams.get("action_type")),n}const s=e=>{if("function"!=typeof window.gtag)return;e=e||i("newspack_modal_checkout");const n=t("dismissed",e);o(n)};function l(e){const t=e&&e.dataset?e.dataset.checkout:null;if(!t)return null;try{return JSON.parse(t)}catch(e){return null}}const u=e=>Boolean(e.closest(".newspack-blocks__url-triggered-checkout"));function d(e,t,n=null,o={}){const{synthesized:c=null}=o,r=e.querySelectorAll(".wp-block-newspack-blocks-checkout-button"),a=null!=n&&""!==String(n);let i=null;return r.forEach(e=>{if(i)return;if(null!==c&&u(e)!==c)return;const o=e.querySelector("form"),r=l(o);r&&String(r.product_id)===String(t)&&(a&&String(r.variation_id)!==String(n)||!a&&r.variation_id||(i=o))}),i}function p(e,t,n={}){const{synthesized:o=null}=n,c=e.querySelectorAll(".wp-block-newspack-blocks-checkout-button");let r=null,a=null;return c.forEach(e=>{if(a)return;if(null!==o&&u(e)!==o)return;const n=e.querySelector("form"),c=l(n);c&&String(c.product_id)===String(t)&&(c.variation_id?r=r||n:a=n)}),a||r}function m(e,t,n,o={}){const{variationModalClassPrefix:c,iframeName:r}=o,a=[...e.querySelectorAll(`.${c}`)].find(e=>String(e.dataset.productId)===String(t));if(!a)return null;const i=a.querySelectorAll("form"),s=r?[...i].find(e=>e.getAttribute("target")===r):i[0];if(!s)return null;const l=[...s.querySelectorAll('input[type="radio"][name="product_id"]')].find(e=>String(e.value)===String(n));return l?(l.checked=!0,s):null}const h=["after_success_behavior","after_success_url","after_success_button_label","after_success_token","gate_post_id","newspack_popup_id","prompt_title","contextual_prompt_post_id","contextual_prompt_placement","contextual_prompt_condition","coupon","quantity"];function f(e,t,n=h){if(!e||!t)return;const o=t.ownerDocument,c=new FormData(e);n.forEach(e=>{if(t.querySelector(`input[name="${e}"]`))return;const n=c.getAll(e).filter(e=>"string"==typeof e&&e);if(!n.length)return;const r=o.createElement("input");r.type="hidden",r.name=e,r.value=n[n.length-1],t.prepend(r)})}const y=["coupon","after_success_behavior","after_success_url","after_success_button_label"],_=["tiered","frequency","untiered"],w=["once","month","year"];const k={gate:"gate_post_id",prompt:"newspack_popup_id"};const g=newspackBlocksModal.newspack_class_prefix,v="newspack_modal_checkout_iframe",b="newspack_modal_checkout_container",S=`${g}__modal`,E="newspack-blocks__modal-variation",q=`${g}__processing-payment-text`,A=newspackBlocksModal.processing_payment_messages;let L=!1,$=newspackBlocksModal.labels.checkout_modal_title,R=null;const M=e=>{e.overlayId&&window.newspackReaderActivation?.overlays&&window.newspackReaderActivation?.overlays.remove(e.overlayId),e.setAttribute("data-state","closed"),document.body.style.overflow="auto"};window.onpageshow=e=>{e.persisted&&(document.querySelectorAll(".modal-processing").forEach(e=>e.classList.remove("modal-processing")),document.querySelectorAll(".non-modal-checkout-loading").forEach(e=>e.classList.remove("non-modal-checkout-loading")),document.querySelectorAll(`.${S}-container`).forEach(e=>M(e)))};const x=new CustomEvent("checkout-closed");var C;window.newspackRAS=window.newspackRAS||[],C=()=>{const t=document.querySelector("#newspack_modal_checkout");if(!t)return;const n=t.querySelector(`.${S}__content`),o=r("modal_checkout","1"),u=n.querySelector(`.${g}__spinner`);let C=document.querySelector(".newspack-reader__account-link")?.[0];const B="600px",P=document.createElement("iframe");P.name=v,P.style.height=B,P.style.visibility="hidden";const T=e=>{j.observe(e),"none"!==u.style.display&&(u.style.display="none"),"visible"!==P.style.visibility&&(P.style.visibility="visible"),P._ready=!0};!function(e,t,n){e._ready=!1,e._readyTimer&&clearTimeout(e._readyTimer);let o=!1,c="";function r(){o||(o=!0,clearTimeout(e._readyTimer),t.call(this))}function a(){"complete"===this.readyState&&r.call(this)}function i(){e._ready=!1,n&&n(),e._readyTimer&&clearTimeout(e._readyTimer);const t=e.contentDocument||e.contentWindow?.document;t&&(t.removeEventListener("DOMContentLoaded",r),t.removeEventListener("readystatechange",a))}function s(){if(e._ready)return void i();const t=e.contentDocument||e.contentWindow?.document;t&&0!==t.URL.indexOf("about:")?"complete"===t?.readyState?r.call(t):(t.addEventListener("DOMContentLoaded",r),t.addEventListener("readystatechange",a)):e._readyTimer=setTimeout(s,10)}e._observer||(e._observer=new MutationObserver(e=>{e.forEach(e=>{"attributes"===e.type&&"src"===e.attributeName&&(o=!1,i(),s())})}),e._observer.observe(e,{attributes:!0})),e._locationObserver||(e._locationObserver=setInterval(function(){const t=e.contentDocument||e.contentWindow?.document;t&&t.URL!==c&&(c=t.URL,o=!1,i(),s())},50)),s()}(P,function(){const n=P.contentWindow?.location;if(window.newspackReaderActivation&&n?.href?.includes("order-received")){const e=window.newspackReaderActivation,t=new Proxy(new URLSearchParams(n.search),{get:(e,t)=>e.get(t)});t.email&&(e.setReaderEmail(t.email),e.setAuthenticated(!0))}const o=P?.contentDocument?.querySelector(`#${b}`);if(!o)return;const c=i(o.querySelector("#modal-checkout-product-details")),r=document.createElement("p");r.classList.add(q);let a=[];const s=()=>{a.forEach(e=>clearTimeout(e)),a=[]},l=()=>{u.style.display="none",s(),u.querySelectorAll(`.${q}`).forEach(e=>e.remove())};!function(e,t){e.checkoutCancel?t():e.addEventListener("checkout-cancel",t)}(o,()=>{z()}),function(e,t){e.checkoutPlaceOrderStart?t():e.addEventListener("checkout-place-order-start",t)}(o,e=>{u.querySelectorAll(`.${q}`).forEach(e=>e.remove()),u.style.display="flex",s(),r.textContent=A[0]?.text??"",A.slice(1).forEach(({text:t,delay:n})=>{const o=setTimeout(()=>{e.target.dispatchEvent(new CustomEvent("checkout-place-order-processing")),r.textContent=t},n);a.push(o)}),u.appendChild(r)}),function(e,t){e.checkoutPlaceOrderError?t():e.addEventListener("checkout-place-order-error",t)}(o,l),function(e,t){e.checkoutReady?t():e.addEventListener("checkout-ready",t)}(o,()=>{if(t.initialErrors){const e=document.createElement("div");e.classList.add("woocommerce-error"),e.textContent=t.initialErrors,o.prepend(e),delete t.initialErrors}J(),H($),P.contentWindow?.newspackBlocksModalCheckout?.checkout_nonce&&(t.checkout_nonce=P.contentWindow.newspackBlocksModalCheckout.checkout_nonce),T(o)}),function(e,t){e.checkoutComplete?t():e.addEventListener("checkout-complete",t)}(o,()=>{window.newspackRAS.push(["checkout_completed",c]),window?.newspackReaderActivation?.refreshNewslettersSignupModal&&window?.newspackReaderActivation?.getReader()?.email&&window.newspackReaderActivation.refreshNewslettersSignupModal(window.newspackReaderActivation.getReader().email),J("small"),H(newspackBlocksModal.labels.thankyou_modal_title),T(o),e(t.querySelector(`.${S}`)),l()}),function(e,t){e.checkoutPlaceOrderCriticalError?t():e.addEventListener("checkout-place-order-critical-error",t)}(o,()=>{var e;(e=R)&&(z(),u.style.display="none",t.initialErrors=newspackBlocksModal.labels.critical_error,e.requestSubmit(e.querySelector('button[type="submit"]')),l())})},()=>{u.style.display="flex"});const D=e=>new Promise((t,n)=>{const o=new URLSearchParams(e);o.append("action","modal_checkout_request"),fetch(newspackBlocksModal.ajax_url+"?"+o.toString()).then(e=>{e.ok||n(e),e.json().then(e=>{t(e.url)}).catch(n)}).catch(n)}),I=()=>"undefined"!=typeof newspack_ras_config&&!newspack_ras_config?.is_logged_in&&!window?.newspackReaderActivation?.getReader?.()?.authenticated&&newspackBlocksModal?.is_registration_required&&window?.newspackReaderActivation?.openAuthModal,N=function(e){const t={};return new URLSearchParams(e).forEach((e,n)=>{n.startsWith("utm")&&e&&(t[n]=e)}),t}(window.location.search),O=t=>{const n=!newspackBlocksModal.has_unsupported_payment_gateway;n||t.preventDefault();const o=t.target;o.classList.add("modal-processing"),function(e){if(!e||"function"!=typeof e.querySelector)return!1;if(e.closest(".newspack-content-gate__gate"))return!1;const t=function(){let e,t;try{e=window.sessionStorage.getItem("newspack_cta_attribution")}catch(e){return null}if(!e)return null;try{t=JSON.parse(e)}catch(e){return null}return t&&1===t.v&&k[t.type]&&t.id?"number"!=typeof t.ts||Date.now()-t.ts>18e5?null:t:null}();if(!t)return!1;const n=k[t.type];if(e.querySelector(`input[name="${n}"]`))return!1;const o=document.createElement("input");o.type="hidden",o.name=n,o.value=t.id,e.prepend(o)}(o),function(e,t){if(!e||!t)return;const n=e.ownerDocument;Object.keys(t).forEach(o=>{if(!t[o]||e.elements.namedItem(o))return;const c=n.createElement("input");c.type="hidden",c.name=o,c.value=t[o],e.prepend(c)})}(o,N);const u=i(o);if(u.newspack_donate){const e=u.donation_frequency,t=[...o.querySelectorAll(`.donation-tier__${e}, .donation-frequency__${e}`)],n=u.donation_tier_index;let c,r;n?(c=t[n],r=u[`donation_value_${e}`]):(c=t[0],u[`donation_value_${e}_untiered`]?r=u[`donation_value_${e}_untiered`]:(r=u[`donation_value_${e}`],"other"===r&&(r=u[`donation_value_${e}_other`])));const a=i(c);for(const e in a)u[e]=a[e];u.amount=r,u.price_summary=u.summary_template.replace("{{PRICE}}",function(e,t="USD"){return parseFloat(e).toLocaleString(document.documentElement.lang,{style:"currency",currency:t,currencyDisplay:"narrowSymbol"})}(u.amount,u.currency))}u&&Object.keys(u).forEach(e=>{0===o.querySelectorAll('input[name="'+e+'"]').length&&o.prepend(r(e,u[e]))}),u.variation_id||(C=t.submitter);const d=document.querySelectorAll(`.${E}`);if(d.forEach(e=>{(I()||n)&&M(e)}),u.is_grouped||u.is_variable&&!u.variation_id){const n=[...d].find(e=>e.dataset.productId===u.product_id);if(n)return n.querySelectorAll(`form[target="${v}"]`).forEach(e=>{!function(e,t,n=h){if(!e||!t)return;const o=e.ownerDocument;n.forEach(n=>{if(e.querySelectorAll(`input[type="hidden"][name="${n}"]`).forEach(e=>e.remove()),function(e,t){return!!e.querySelector(`input[name="${t}"]:not([type="hidden"])`)}(e,n))return;const c=t[n],r=null==c?"":String(c);if(!r)return;const a=o.createElement("input");a.type="hidden",a.name=n,a.value=r,e.prepend(a)})}(e,u);const t=l(e);t&&Object.keys(t).forEach(n=>{0===e.querySelectorAll('input[name="'+n+'"]').length&&e.prepend(r(n,t[n]))})}),t.preventDefault(),o.classList.remove("modal-processing"),F(n),e(n,!1),L||c(u),void document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u))}if(n||I()){if(o.classList.remove("modal-processing"),L||c(u),L=!0,I()){t.preventDefault();const e=D(u);e.then(e=>{window.newspackReaderActivation?.setPendingCheckout?.(e)}),window.newspackReaderActivation.openAuthModal({title:newspackBlocksModal.labels.auth_modal_title,onSuccess:(t,o)=>{e.then(e=>{o?.registered&&n&&(e+=`&${newspackBlocksModal.checkout_registration_flag}=1`),n?a(U(e)):D(u).then(window.location.href=e)}).catch(e=>{console.warn("Unable to generate cart:",e),z()})},onError:()=>{z()},onDismiss:()=>{s(u),L=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout")},skipSuccess:!0,skipNewslettersSignup:!0,labels:{signin:{title:newspackBlocksModal.labels.signin_modal_title},register:{title:newspackBlocksModal.labels.register_modal_title}},trigger:t.submitter,closeOnSuccess:n})}else W(),document.getElementById("newspack_modal_checkout").setAttribute("data-checkout",JSON.stringify(u));R=o}else D(u).then(e=>{window.location.href=e}),(!u.is_variable||u.variation_id)&&o.querySelectorAll("button[type=submit]:focus").forEach(e=>{e.classList.add("non-modal-checkout-loading");const t=e.innerHTML;e.innerHTML="<span>"+t+"</span>"})},U=e=>{const t=document.createElement("form");t.method="POST",t.action=e,t.target=v,t.style.display="none";const n=document.createElement("button");return n.setAttribute("type","submit"),t.appendChild(n),document.body.appendChild(t),t.addEventListener("submit",O),t},j=new ResizeObserver(e=>{if(!e||!e.length)return;if(!P.contentDocument)return;const o=e[0].contentRect;if(o){const e=.01*Math.max(document.documentElement.clientHeight,window.innerHeight||0)*90-(t.querySelector(`.${S}__header`)?.offsetHeight||0),c=o.top+o.bottom,r=Math.min(c,e);if(0===r)return void(P.style.visibility="hidden");n.style.height=r+"px",P.style.height=r+"px"}}),z=()=>{const e=P?.contentDocument?.querySelector(`#${b}`),o=e?.querySelector('input[name="after_success_url"]'),c=e?.querySelector('input[name="after_success_behavior"]'),r=document?.querySelector(".newspack-newsletters-signup-modal"),a=i(e?.querySelector("#modal-checkout-product-details"));e?.checkoutComplete||(async()=>{const e=new FormData;newspackBlocksModal.has_unsupported_payment_gateway||e.append("modal_checkout","1"),e.append("action","abandon_modal_checkout"),e.append("_wpnonce",t.checkout_nonce),t.checkout_nonce=null;try{await fetch(newspackBlocksModal.ajax_url,{method:"POST",body:e})}catch(e){console.warn("Unable to empty cart:",e)}})();const l=!(P.contentDocument&&o&&c&&e?.checkoutComplete);if((l||r)&&(u.style.display="flex",P&&n.contains(P)&&(P._ready=!1,P.src="about:blank",P.style.height=B,P.style.visibility="hidden",n.style.height=B,n.removeChild(P)),j&&j.disconnect(),document.querySelectorAll(`.${S}-container`).forEach(e=>M(e)),C&&C.focus(),document.dispatchEvent(x)),e?.checkoutComplete){const e=()=>{if(o&&c){const e=o.getAttribute("value"),t=c.getAttribute("value");if("custom"===t)window.location.href=e;else if("referrer"===t){const e=document.referrer;let t=!1;if(e)try{new URL(e).origin===window.location.origin&&(window.location.href=e,t=!0)}catch(e){}t||window.history.back()}}window?.newspackReaderActivation?.setPendingCheckout?.(),L=!1};"subscription_switch"!==a.action_type&&window?.newspackReaderActivation?.openNewslettersSignupModal?window.newspackReaderActivation.openNewslettersSignupModal({onSuccess:e,onError:e,closeOnSuccess:l}):e(),l&&($=newspackBlocksModal.labels.checkout_modal_title,J(),H($))}else window?.newspackReaderActivation?.setPendingCheckout?.(),s(),L=!1,document.getElementById("newspack_modal_checkout").removeAttribute("data-checkout");document.removeEventListener("keydown",K)},W=o=>{o&&(P.src=o),u.style.display="flex",F(t),n.appendChild(P),t.addEventListener("click",e=>{e.target===t&&z()}),e(t,P),document.addEventListener("keydown",K)},F=e=>{window.newspackReaderActivation?.overlays&&(e.overlayId=window.newspackReaderActivation?.overlays.add()),e.setAttribute("data-state","open"),document.body.style.overflow="hidden"},H=e=>{const n=t.querySelector(`.${S}__header h2`);n&&(n.innerText=e)},J=(e="default")=>{const n=t.querySelector(`.${S}`);n&&("small"===e?n.classList.add(`${S}--small`):n.classList.remove(`${S}--small`))};t.querySelectorAll(`.${S}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),z()})}),document.querySelectorAll(".newspack-blocks__modal-variation").forEach(e=>{e.addEventListener("click",t=>{t.target===e&&z()}),e.querySelectorAll(`.${S}__close`).forEach(e=>{e.addEventListener("click",e=>{e.preventDefault(),z()})})});const K=e=>{"Escape"===e.key&&z()};document.querySelectorAll(".wpbnbd.wpbnbd--platform-wc, .wp-block-newspack-blocks-checkout-button, .newspack-blocks__modal-variation").forEach(e=>{e.querySelectorAll("form").forEach(e=>{newspackBlocksModal.has_unsupported_payment_gateway||e.prepend(o.cloneNode()),e.target=v,e.addEventListener("submit",O)})});const V=["checkout","type","layout","frequency","amount","other","product_id","variation_id"],G=()=>{const e=new URL(window.location.href);V.forEach(t=>e.searchParams.delete(t)),window.history.replaceState(null,null,e.href)},Q=(e,t,n,o=null)=>{const c=function(e,{layout:t,frequency:n,amount:o}){if(!function(e,t,n){return!(!_.includes(e)||!w.includes(t))&&("other"===n?"frequency"===e:/^\d+(\.\d+)?$/.test(n))}(t,n,o))return{status:"invalid-params"};let c=null;for(const r of e.querySelectorAll(".wpbnbd.wpbnbd--platform-wc form")){const e=r.closest(".wpbnbd--tiers-based");if("tiered"===t){if(!e)continue;const t=r.querySelector(`.wpbnbd__tiers__amount [data-frequency-slug="${n}"][data-amount="${o}"]`);if(!t)continue;const a=parseInt(t.getAttribute("data-tier-index"));if(isNaN(a))continue;const i=r.querySelector(`button[data-frequency-slug="${n}"]`);if(!i&&!r.querySelector(`input[name="donation_frequency"][value="${n}"]`))continue;if(!e.hasAttribute("data-tiers-based-ready")){c||(c=r);continue}return{status:"tiered",form:r,frequencyButton:i,tierIndex:a}}if(e)continue;const a=r.querySelector(`input[name="donation_frequency"][value="${n}"]`);if(!a)continue;const i="untiered"===t?r.querySelector(`input[name="donation_value_${n}_untiered"]`):r.querySelector(`input[name="donation_value_${n}"][value="${o}"]`);if(i)return{status:t,form:r,frequencyInput:a,amountInput:i}}return c?{status:"not-ready",form:c}:{status:"no-match"}}(document,{layout:e,frequency:t,amount:n}),r=`layout "${e}", frequency "${t}" and amount "${n}"`;if("invalid-params"===c.status)return console.warn(`Newspack modal checkout: invalid donate trigger parameters (${r}). The checkout was not triggered.`),!1;if("no-match"===c.status)return console.warn(`Newspack modal checkout: no donate form matches ${r}. The checkout was not triggered.`),!1;if("not-ready"===c.status){const c=setTimeout(()=>{console.warn(`Newspack modal checkout: the donate form matching ${r} never finished initializing. The checkout was not triggered; the URL params were kept so a reload can retry.`)},5e3);return document.addEventListener("newspack-tiers-based-ready",()=>{clearTimeout(c),Q(e,t,n,o)&&G()},{once:!0}),!1}const{form:i}=c;if("tiered"===c.status){c.frequencyButton&&c.frequencyButton.click();const e=i.querySelector(`button[type="submit"][data-tier-index="${c.tierIndex}"]`);return e?(e.click(),!0):(console.warn(`Newspack modal checkout: no tier submit button matches ${r}. The checkout was not triggered.`),!1)}if(c.frequencyInput.checked=!0,"untiered"===c.status)c.amountInput.value=n;else if("other"===n){c.amountInput.click();const e=i.querySelector(`input[name="donation_value_${t}_other"]`);e&&o&&(e.value=o)}else c.amountInput.checked=!0;return i.checkValidity()?(a(i),!0):(console.warn(`Newspack modal checkout: the donate form rejected the values for ${r}. The checkout was not triggered.`),!1)};(()=>{const e=new URLSearchParams(window.location.search);if(!e.has("checkout"))return;let t=!0;const n=e.get("type");if("donate"===n){const n=e.get("layout"),o=e.get("frequency"),c=e.get("amount"),r=e.get("other");n&&o&&c?t=Q(n,o,c,r):(t=!1,console.warn("Newspack modal checkout: donate trigger is missing layout, frequency or amount. The checkout was not triggered."))}else if("checkout_button"===n){const n=e.get("product_id"),o=e.get("variation_id");n?t=((e,t=null)=>{const n=function(e,t,n,o={}){if(null==n||""===String(n))return d(e,t,null,{synthesized:!1})||d(e,t,null,{synthesized:!0});const c=d(e,t,n,{synthesized:!1});if(c)return c;const r=p(e,t,{synthesized:!1});if(r){const c=m(e,t,n,o);if(c)return f(r,c),c}const a=d(e,t,n,{synthesized:!0});if(a)return a;const i=m(e,t,n,o);return i?(f(p(e,t),i),i):null}(document,e,t,{variationModalClassPrefix:E,iframeName:v});if(n){const e=function(e,t){const n=new URLSearchParams(t);return y.filter(t=>n.get(t)&&!(e&&e.elements.namedItem(t)))}(n,window.location.search);return e.length&&console.warn(`Newspack modal checkout: the resolved checkout form does not carry ${e.join(", ")} from the URL. The page block's own settings apply instead.`),a(n),!0}const o=`Newspack modal checkout: no checkout form found for product_id "${e}"`+(t?` and variation_id "${t}"`:"")+". The checkout was not triggered.";return console.warn(o),!1})(n,o):(t=!1,console.warn("Newspack modal checkout: checkout_button trigger is missing product_id. The checkout was not triggered."))}else{const e=window.newspackReaderActivation?.getPendingCheckout?.();e&&a(U(e))}t&&G()})(),window.newspackOpenModalCheckout=({url:e=null,title:t=null,actionType:n=null,afterSuccess:o={},quantity:c=null,onCheckoutComplete:r=null,onClose:a=null})=>{if($=t||newspackBlocksModal.labels.checkout_modal_title,H($),(e=new URL(e||newspackBlocksModal.checkout_url)).searchParams.has("my_account_checkout")&&e.searchParams.delete("my_account_checkout"),e.searchParams.has("modal_checkout")||e.searchParams.set("modal_checkout","1"),n&&e.searchParams.set("action_type",n),c&&parseInt(c,10)>1&&e.searchParams.set("quantity",String(parseInt(c,10))),o?.url&&e.searchParams.set("after_success_url",o.url),(o?.behavior||o?.url)&&e.searchParams.set("after_success_behavior",o.behavior||"custom"),o?.buttonLabel&&e.searchParams.set("after_success_button_label",o.buttonLabel),r){const e=({detail:{action:e,data:t}})=>{"checkout_completed"===e&&r(t)};window.newspackRAS.push(t=>{t.on("activity",e);const n=()=>{t.off("activity",e),document.removeEventListener("checkout-closed",n)};document.addEventListener("checkout-closed",n)})}if(a){const e=()=>{a(),document.removeEventListener("checkout-closed",e)};document.addEventListener("checkout-closed",e)}W(e.toString())},window.newspackCloseModalCheckout=z},"undefined"!=typeof document&&("complete"!==document.readyState&&"interactive"!==document.readyState?document.addEventListener("DOMContentLoaded",C):C())})();
|
|
@@ -119,6 +119,14 @@ final class Modal_Checkout {
|
|
|
119
119
|
*/
|
|
120
120
|
private static $has_modal = false;
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Block markup synthesized from URL trigger params, echoed (hidden) in the
|
|
124
|
+
* footer. Empty when the request carries no valid trigger.
|
|
125
|
+
*
|
|
126
|
+
* @var string
|
|
127
|
+
*/
|
|
128
|
+
private static $url_triggered_block_html = '';
|
|
129
|
+
|
|
122
130
|
/**
|
|
123
131
|
* Products that are being rendered a checkout modal for.
|
|
124
132
|
*
|
|
@@ -231,6 +239,7 @@ final class Modal_Checkout {
|
|
|
231
239
|
add_filter( 'wp_redirect', [ __CLASS__, 'pass_url_param_on_redirect' ] );
|
|
232
240
|
add_filter( 'woocommerce_cart_product_cannot_be_purchased_message', [ __CLASS__, 'woocommerce_cart_product_cannot_be_purchased_message' ], 10, 2 );
|
|
233
241
|
add_filter( 'woocommerce_add_error', [ __CLASS__, 'hide_expiry_message_shop_link' ] );
|
|
242
|
+
add_action( 'wp', [ __CLASS__, 'maybe_setup_url_triggered_checkout' ], 11 );
|
|
234
243
|
add_action( 'wp_footer', [ __CLASS__, 'render_modal_markup' ], 100 );
|
|
235
244
|
add_action( 'wp_footer', [ __CLASS__, 'render_variation_selection' ], 100 );
|
|
236
245
|
add_action( 'wp_enqueue_scripts', [ __CLASS__, 'enqueue_scripts' ] );
|
|
@@ -524,6 +533,7 @@ final class Modal_Checkout {
|
|
|
524
533
|
}
|
|
525
534
|
|
|
526
535
|
$params = array_merge( $params, compact( 'after_success_behavior', 'after_success_url', 'after_success_button_label', 'after_success_token' ) );
|
|
536
|
+
$params = self::merge_request_utm_params( $params );
|
|
527
537
|
|
|
528
538
|
if ( function_exists( 'wpcom_vip_url_to_postid' ) ) {
|
|
529
539
|
$referer_post_id = wpcom_vip_url_to_postid( $referer );
|
|
@@ -604,11 +614,14 @@ final class Modal_Checkout {
|
|
|
604
614
|
}
|
|
605
615
|
|
|
606
616
|
// Pass through UTM and after_success params so they can be forwarded to the WooCommerce checkout flow.
|
|
617
|
+
// Values are encoded here because add_query_arg() does not encode them:
|
|
618
|
+
// an ampersand or space in a campaign name would otherwise split into a
|
|
619
|
+
// stray param or be dropped by the redirect sanitizer.
|
|
607
620
|
foreach ( $params as $param => $value ) {
|
|
608
621
|
if ( 'utm' === substr( $param, 0, 3 ) || 'after_success' === substr( $param, 0, 13 ) ) {
|
|
609
622
|
if ( ! empty( $value ) ) {
|
|
610
623
|
$param = sanitize_text_field( $param );
|
|
611
|
-
$query_args[ $param ] = sanitize_text_field( $value );
|
|
624
|
+
$query_args[ $param ] = rawurlencode( sanitize_text_field( $value ) );
|
|
612
625
|
}
|
|
613
626
|
}
|
|
614
627
|
}
|
|
@@ -661,6 +674,215 @@ final class Modal_Checkout {
|
|
|
661
674
|
}
|
|
662
675
|
}
|
|
663
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Merge utm_* parameters from the current request into a params array.
|
|
679
|
+
*
|
|
680
|
+
* The modal form's own submission is what carries a promo link's values here:
|
|
681
|
+
* appendUtmFields() in modal.js copies the landing page's utm params onto the
|
|
682
|
+
* form as hidden fields before it GET-submits into the checkout iframe, so
|
|
683
|
+
* they arrive in this request's $_GET rather than depending on the referer.
|
|
684
|
+
* Request params win over referer params.
|
|
685
|
+
*
|
|
686
|
+
* @param array $params Params parsed from the referer query string.
|
|
687
|
+
* @return array Params with the request's utm_* params merged in.
|
|
688
|
+
*/
|
|
689
|
+
public static function merge_request_utm_params( $params ) {
|
|
690
|
+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
691
|
+
foreach ( wp_unslash( $_GET ) as $key => $value ) {
|
|
692
|
+
if ( 'utm' === substr( $key, 0, 3 ) && is_string( $value ) && '' !== $value ) {
|
|
693
|
+
$params[ sanitize_text_field( $key ) ] = sanitize_text_field( $value );
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return $params;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Serve a `?checkout=1&type=…` trigger on any front-end URL by rendering the
|
|
701
|
+
* block it needs into the footer (hidden), so no page has to carry one.
|
|
702
|
+
* Rendering the real block brings everything the trigger relies on: the form
|
|
703
|
+
* it submits, the variation/tiers picker modals, and the modal assets. A page
|
|
704
|
+
* that does carry a matching block still wins — its form comes first in DOM
|
|
705
|
+
* order, so block-level context such as a coupon keeps applying.
|
|
706
|
+
*
|
|
707
|
+
* Runs on `wp` so the render-time asset enqueues land in the normal queue.
|
|
708
|
+
*/
|
|
709
|
+
public static function maybe_setup_url_triggered_checkout() {
|
|
710
|
+
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
|
711
|
+
// The trigger-param test is the cheapest and most selective guard, so it
|
|
712
|
+
// runs first: nearly all traffic carries no trigger, and is_checkout()
|
|
713
|
+
// below is the one call here that touches WooCommerce page-type state
|
|
714
|
+
// and its filters.
|
|
715
|
+
if ( ! isset( $_GET['checkout'] ) || ! isset( $_GET['type'] ) || ! is_string( $_GET['type'] ) ) {
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
if ( is_admin() || wp_doing_ajax() || is_feed() || ( function_exists( 'is_checkout' ) && is_checkout() ) ) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
if ( ! function_exists( 'wc_get_product' ) ) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
$type = sanitize_text_field( wp_unslash( $_GET['type'] ) );
|
|
725
|
+
if ( 'donate' === $type ) {
|
|
726
|
+
// The trigger script only fires when layout, frequency and amount are
|
|
727
|
+
// all present, so a request missing any of them would render a form
|
|
728
|
+
// nothing ever submits. Donations must also be on the WooCommerce
|
|
729
|
+
// platform for the block to produce a servable form.
|
|
730
|
+
if ( empty( $_GET['layout'] ) || empty( $_GET['frequency'] ) || empty( $_GET['amount'] ) ) {
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
if ( ! method_exists( '\Newspack\Donations', 'is_platform_wc' ) || ! \Newspack\Donations::is_platform_wc() ) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
// Defaults resolve to the site's donation settings, which is what the
|
|
737
|
+
// generator derived its frequency/amount options from.
|
|
738
|
+
self::$url_triggered_block_html = do_blocks( '<!-- wp:newspack-blocks/donate /-->' );
|
|
739
|
+
} elseif ( 'checkout_button' === $type ) {
|
|
740
|
+
$attrs = self::build_url_triggered_button_attrs_from_request();
|
|
741
|
+
if ( empty( $attrs ) ) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
self::$url_triggered_block_html = do_blocks( '<!-- wp:newspack-blocks/checkout-button ' . serialize_block_attributes( $attrs ) . ' /-->' );
|
|
745
|
+
} else {
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
|
749
|
+
if ( '' !== self::$url_triggered_block_html ) {
|
|
750
|
+
add_action( 'wp_footer', [ __CLASS__, 'render_url_triggered_block' ], 1 );
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Resolve checkout button attributes from the current request, validating the
|
|
756
|
+
* product and variation. Returns [] when the request can't be served.
|
|
757
|
+
*
|
|
758
|
+
* Reads $_GET rather than filter_input(): the guard in
|
|
759
|
+
* maybe_setup_url_triggered_checkout() tests $_GET, and filter_input()
|
|
760
|
+
* consults PHP's request snapshot instead — anything that adjusts the
|
|
761
|
+
* superglobal after parsing (a test, a mu-plugin rewriting the query) would
|
|
762
|
+
* pass the guard and read back empty.
|
|
763
|
+
*
|
|
764
|
+
* @return array Block attributes.
|
|
765
|
+
*/
|
|
766
|
+
public static function build_url_triggered_button_attrs_from_request() {
|
|
767
|
+
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
|
768
|
+
$product_id = isset( $_GET['product_id'] ) && is_scalar( $_GET['product_id'] ) ? absint( $_GET['product_id'] ) : 0;
|
|
769
|
+
$variation_id = isset( $_GET['variation_id'] ) && is_scalar( $_GET['variation_id'] ) ? absint( $_GET['variation_id'] ) : 0;
|
|
770
|
+
if ( ! $product_id ) {
|
|
771
|
+
return [];
|
|
772
|
+
}
|
|
773
|
+
$product = wc_get_product( $product_id );
|
|
774
|
+
if ( ! $product || 'publish' !== $product->get_status() ) {
|
|
775
|
+
return [];
|
|
776
|
+
}
|
|
777
|
+
if ( $variation_id ) {
|
|
778
|
+
$variation = wc_get_product( $variation_id );
|
|
779
|
+
if ( ! $variation || $variation->get_parent_id() !== $product_id || 'publish' !== $variation->get_status() ) {
|
|
780
|
+
return [];
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
// The coupon and label are non-HTML text values: sanitize_text_field()
|
|
784
|
+
// keeps their raw characters, where an entity-encoding filter would break
|
|
785
|
+
// the coupon's title lookup and show readers an encoded label. Escaping
|
|
786
|
+
// happens at output (view.php / the thank-you template). The destination
|
|
787
|
+
// is a URL: esc_url_raw() keeps its query intact and drops disallowed
|
|
788
|
+
// schemes before sanitize_after_success_url() validates the host.
|
|
789
|
+
$coupon = isset( $_GET['coupon'] ) && is_string( $_GET['coupon'] ) ? sanitize_text_field( wp_unslash( $_GET['coupon'] ) ) : '';
|
|
790
|
+
$button_label = isset( $_GET['after_success_button_label'] ) && is_string( $_GET['after_success_button_label'] ) ? sanitize_text_field( wp_unslash( $_GET['after_success_button_label'] ) ) : '';
|
|
791
|
+
$behavior = isset( $_GET['after_success_behavior'] ) && is_string( $_GET['after_success_behavior'] ) ? sanitize_text_field( wp_unslash( $_GET['after_success_behavior'] ) ) : '';
|
|
792
|
+
$after_url = isset( $_GET['after_success_url'] ) && is_string( $_GET['after_success_url'] ) ? esc_url_raw( wp_unslash( $_GET['after_success_url'] ) ) : '';
|
|
793
|
+
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
|
794
|
+
return self::build_url_triggered_button_attrs(
|
|
795
|
+
$product->get_type(),
|
|
796
|
+
$product_id,
|
|
797
|
+
$variation_id,
|
|
798
|
+
$coupon,
|
|
799
|
+
[
|
|
800
|
+
'behavior' => $behavior,
|
|
801
|
+
'url' => $after_url,
|
|
802
|
+
'button_label' => $button_label,
|
|
803
|
+
]
|
|
804
|
+
);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Block attributes serving a URL trigger for the given product shape.
|
|
809
|
+
*
|
|
810
|
+
* Mirrors what the block editor stores: a variable product carries
|
|
811
|
+
* `is_variable` with the parent as `product` and any lock as `variation`
|
|
812
|
+
* (view.php collapses the pair onto the variation), while grouped parents
|
|
813
|
+
* and specific products are `product` alone. A variation lock on a
|
|
814
|
+
* non-variable product has no serving form, so it is rejected.
|
|
815
|
+
*
|
|
816
|
+
* A coupon and after-success settings become block attributes, so they ride to
|
|
817
|
+
* the checkout as hidden fields exactly as block-configured ones do.
|
|
818
|
+
*
|
|
819
|
+
* Only `custom` after-success is accepted: `referrer` returns the reader where
|
|
820
|
+
* they came from, which a link opened from an email or a QR code has no
|
|
821
|
+
* referrer or history entry to satisfy.
|
|
822
|
+
*
|
|
823
|
+
* @param string $product_type Product type slug from WC_Product::get_type().
|
|
824
|
+
* @param int $product_id Requested product ID.
|
|
825
|
+
* @param int $variation_id Requested variation ID (0 for none).
|
|
826
|
+
* @param string $coupon Requested coupon code ('' for none).
|
|
827
|
+
* @param array $after_success {
|
|
828
|
+
* Optional. Requested after-checkout behavior.
|
|
829
|
+
* @type string $behavior 'custom' to send the reader onward; anything
|
|
830
|
+
* else leaves the thank-you screen alone.
|
|
831
|
+
* @type string $url Destination for the 'custom' behavior.
|
|
832
|
+
* @type string $button_label Label for the continue button.
|
|
833
|
+
* }
|
|
834
|
+
* @return array Block attributes, or [] when the combination can't be served.
|
|
835
|
+
*/
|
|
836
|
+
public static function build_url_triggered_button_attrs( $product_type, $product_id, $variation_id = 0, $coupon = '', $after_success = [] ) {
|
|
837
|
+
$is_variable = in_array( $product_type, [ 'variable', 'variable-subscription' ], true );
|
|
838
|
+
if ( $variation_id && ! $is_variable ) {
|
|
839
|
+
return [];
|
|
840
|
+
}
|
|
841
|
+
$attrs = [
|
|
842
|
+
'product' => (string) $product_id,
|
|
843
|
+
// The button is submitted programmatically and never shown.
|
|
844
|
+
'text' => __( 'Complete your purchase', 'newspack-blocks' ),
|
|
845
|
+
];
|
|
846
|
+
if ( $is_variable ) {
|
|
847
|
+
$attrs['is_variable'] = true;
|
|
848
|
+
if ( $variation_id ) {
|
|
849
|
+
$attrs['variation'] = (string) $variation_id;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
// Strict check so a coupon code of "0" still rides along.
|
|
853
|
+
if ( '' !== $coupon ) {
|
|
854
|
+
$attrs['coupon'] = $coupon;
|
|
855
|
+
}
|
|
856
|
+
// The destination is restricted to allowed hosts here (sanitize_after_success_url()
|
|
857
|
+
// with no token), before it becomes a block attribute. view.php mints an
|
|
858
|
+
// after_success_token for any afterSuccessURL it renders — including this
|
|
859
|
+
// synthesized one — so that token only ever vouches for a destination this
|
|
860
|
+
// pre-validation already accepts. Loosening the check here would widen what
|
|
861
|
+
// the minted token blesses; an off-site destination still has to come from
|
|
862
|
+
// a block an editor authored.
|
|
863
|
+
$after_success_url = isset( $after_success['url'] ) ? self::sanitize_after_success_url( $after_success['url'] ) : '';
|
|
864
|
+
if ( isset( $after_success['behavior'] ) && 'custom' === $after_success['behavior'] && '' !== $after_success_url ) {
|
|
865
|
+
$attrs['afterSuccessBehavior'] = 'custom';
|
|
866
|
+
$attrs['afterSuccessURL'] = $after_success_url;
|
|
867
|
+
if ( ! empty( $after_success['button_label'] ) ) {
|
|
868
|
+
$attrs['afterSuccessButtonLabel'] = $after_success['button_label'];
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return $attrs;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Output the synthesized block, hidden. The URL trigger drives it
|
|
876
|
+
* programmatically; any picker modals render separately via
|
|
877
|
+
* render_variation_selection(), outside this hidden wrapper.
|
|
878
|
+
*/
|
|
879
|
+
public static function render_url_triggered_block() {
|
|
880
|
+
if ( '' === self::$url_triggered_block_html ) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
echo '<div class="newspack-blocks__url-triggered-checkout" style="display:none">' . self::$url_triggered_block_html . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
|
884
|
+
}
|
|
885
|
+
|
|
664
886
|
/**
|
|
665
887
|
* Process abandon checkout for modal.
|
|
666
888
|
*/
|
|
@@ -1648,7 +1870,7 @@ final class Modal_Checkout {
|
|
|
1648
1870
|
|
|
1649
1871
|
$queried = get_queried_object();
|
|
1650
1872
|
|
|
1651
|
-
return $queried instanceof WP_Post ? (int) $queried->ID : 0;
|
|
1873
|
+
return $queried instanceof \WP_Post ? (int) $queried->ID : 0;
|
|
1652
1874
|
}
|
|
1653
1875
|
|
|
1654
1876
|
/**
|
|
@@ -1941,12 +2163,15 @@ final class Modal_Checkout {
|
|
|
1941
2163
|
return $url;
|
|
1942
2164
|
}
|
|
1943
2165
|
|
|
2166
|
+
// Encoded because add_query_arg() does not encode what it is given: a
|
|
2167
|
+
// destination carrying its own query string would otherwise split, and
|
|
2168
|
+
// its second param would become a param of the thank-you URL.
|
|
1944
2169
|
$args = array_merge(
|
|
1945
2170
|
[
|
|
1946
2171
|
'modal_checkout' => '1',
|
|
1947
2172
|
'email' => isset( $_REQUEST['billing_email'] ) ? rawurlencode( \sanitize_email( \wp_unslash( $_REQUEST['billing_email'] ) ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
1948
2173
|
],
|
|
1949
|
-
self::get_after_success_params()
|
|
2174
|
+
array_map( 'rawurlencode', self::get_after_success_params() )
|
|
1950
2175
|
);
|
|
1951
2176
|
|
|
1952
2177
|
// Pass order ID for modal checkout templates.
|
|
@@ -2401,9 +2626,26 @@ final class Modal_Checkout {
|
|
|
2401
2626
|
if ( '' === $coupon_code || ! function_exists( 'wc_coupons_enabled' ) || ! \wc_coupons_enabled() ) {
|
|
2402
2627
|
return;
|
|
2403
2628
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2629
|
+
try {
|
|
2630
|
+
$coupon = new \WC_Coupon( $coupon_code );
|
|
2631
|
+
$discounts = new \WC_Discounts( \WC()->cart );
|
|
2632
|
+
$applied = true === $discounts->is_coupon_valid( $coupon ) && \WC()->cart->apply_coupon( $coupon_code );
|
|
2633
|
+
} catch ( \Exception $e ) {
|
|
2634
|
+
// A persistent object cache can hold a code-to-ID mapping that
|
|
2635
|
+
// outlives the coupon post, and WooCommerce's data store throws
|
|
2636
|
+
// when it reads the missing post. Skip the coupon rather than
|
|
2637
|
+
// fataling the checkout the reader is standing on — but leave a
|
|
2638
|
+
// trail: without it, a cache stuck in this state silently charges
|
|
2639
|
+
// every reader on the promo link full price.
|
|
2640
|
+
if ( function_exists( 'wc_get_logger' ) ) {
|
|
2641
|
+
wc_get_logger()->warning(
|
|
2642
|
+
sprintf( 'Modal checkout: skipped auto-applying coupon "%s": %s', $coupon_code, $e->getMessage() ),
|
|
2643
|
+
[ 'source' => 'newspack-blocks' ]
|
|
2644
|
+
);
|
|
2645
|
+
}
|
|
2646
|
+
return;
|
|
2647
|
+
}
|
|
2648
|
+
if ( $applied ) {
|
|
2407
2649
|
// apply_coupon() queues a "Coupon code applied successfully." success
|
|
2408
2650
|
// notice; clear it so the auto-apply stays silent for the reader.
|
|
2409
2651
|
if ( function_exists( 'wc_clear_notices' ) ) {
|
|
@@ -292,6 +292,14 @@ class Newspack_Blocks_API {
|
|
|
292
292
|
],
|
|
293
293
|
];
|
|
294
294
|
|
|
295
|
+
// The meta bag is returned verbatim, and the Homepage Posts editor component
|
|
296
|
+
// assigns the subtitle with RawHTML. A value stored before the theme gained a
|
|
297
|
+
// sanitize_callback is still raw, so it is filtered here rather than at that
|
|
298
|
+
// sink -- this endpoint is the only thing between the two.
|
|
299
|
+
if ( isset( $data['meta']['newspack_post_subtitle'] ) ) {
|
|
300
|
+
$data['meta']['newspack_post_subtitle'] = Newspack_Blocks::sanitize_post_subtitle( $data['meta']['newspack_post_subtitle'] );
|
|
301
|
+
}
|
|
302
|
+
|
|
295
303
|
$sponsors = Newspack_Blocks::get_all_sponsors( $post->ID );
|
|
296
304
|
$author_info = Newspack_Blocks::prepare_authors();
|
|
297
305
|
$add_ons = [
|
|
@@ -1804,5 +1804,43 @@ class Newspack_Blocks {
|
|
|
1804
1804
|
|
|
1805
1805
|
return $combined_caption;
|
|
1806
1806
|
}
|
|
1807
|
+
|
|
1808
|
+
/**
|
|
1809
|
+
* Inline tags this plugin allows in a post subtitle.
|
|
1810
|
+
*
|
|
1811
|
+
* The theme owns the subtitle and sanitizes it on write, but a value stored before
|
|
1812
|
+
* that was in place is still raw, so the plugin filters it on the way out rather
|
|
1813
|
+
* than trusting the meta.
|
|
1814
|
+
*
|
|
1815
|
+
* @return array Allowed tags in wp_kses() form.
|
|
1816
|
+
*/
|
|
1817
|
+
public static function get_post_subtitle_allowed_tags() {
|
|
1818
|
+
return array(
|
|
1819
|
+
'b' => true,
|
|
1820
|
+
'strong' => true,
|
|
1821
|
+
'i' => true,
|
|
1822
|
+
'em' => true,
|
|
1823
|
+
'mark' => true,
|
|
1824
|
+
'u' => true,
|
|
1825
|
+
'small' => true,
|
|
1826
|
+
'sub' => true,
|
|
1827
|
+
'sup' => true,
|
|
1828
|
+
'a' => array(
|
|
1829
|
+
'href' => true,
|
|
1830
|
+
'target' => true,
|
|
1831
|
+
'rel' => true,
|
|
1832
|
+
),
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
/**
|
|
1837
|
+
* Limit a post subtitle to the inline tags this plugin renders.
|
|
1838
|
+
*
|
|
1839
|
+
* @param string $subtitle Raw subtitle.
|
|
1840
|
+
* @return string Sanitized subtitle.
|
|
1841
|
+
*/
|
|
1842
|
+
public static function sanitize_post_subtitle( $subtitle ) {
|
|
1843
|
+
return wp_kses( (string) $subtitle, self::get_post_subtitle_allowed_tags() );
|
|
1844
|
+
}
|
|
1807
1845
|
}
|
|
1808
1846
|
Newspack_Blocks::init();
|