From 7b355505bfa4055daec28172c88bf338d5cd50c4 Mon Sep 17 00:00:00 2001 From: WooCommerce Date: Wed, 15 Oct 2025 10:18:29 +0000 Subject: [PATCH] Updates to 8.0.0 --- build/index.asset.php | 2 +- build/index.js | 31 +- changelog.txt | 21 +- includes/class-wc-subscriptions-plugin.php | 5 + includes/class-wcs-webhooks.php | 2 - .../core/admin/class-wcs-admin-post-types.php | 2 - includes/core/class-wc-subscriptions-cart.php | 70 +- ...wc-subscriptions-extend-store-endpoint.php | 52 +- .../core/class-wc-subscriptions-order.php | 1 - .../core/class-wc-subscriptions-tracker.php | 279 +- ...ss-wcs-failed-scheduled-action-manager.php | 1 - .../class-wcs-object-data-cache-manager.php | 10 +- .../class-wc-subscriptions-email-preview.php | 7 +- ...class-wcs-email-cancelled-subscription.php | 1 - ...lass-wcs-email-completed-renewal-order.php | 1 - ...class-wcs-email-completed-switch-order.php | 1 - ...ail-customer-notification-auto-renewal.php | 1 - ...mer-notification-auto-trial-expiration.php | 1 - ...l-customer-notification-manual-renewal.php | 1 - ...r-notification-manual-trial-expiration.php | 1 - ...r-notification-subscription-expiration.php | 1 - ...s-email-customer-on-hold-renewal-order.php | 1 - ...ass-wcs-email-customer-renewal-invoice.php | 1 - .../class-wcs-email-expired-subscription.php | 1 - .../class-wcs-email-new-renewal-order.php | 1 - .../class-wcs-email-new-switch-order.php | 1 - .../class-wcs-email-on-hold-subscription.php | 1 - ...ass-wcs-email-processing-renewal-order.php | 1 - .../abstracts/abstract-wcs-sv-api-base.php | 4 +- ...ypal-reference-transaction-api-request.php | 2 +- ...-repair-suspended-paypal-subscriptions.php | 2 + .../core/upgrades/class-wcs-upgrade-2-0.php | 1 - includes/core/wcs-cart-functions.php | 5 +- includes/core/wcs-product-functions.php | 29 + includes/core/wcs-time-functions.php | 1 - includes/core/wcs-user-functions.php | 8 +- includes/gifting/class-wcs-gifting.php | 27 +- includes/gifting/class-wcsg-email.php | 7 +- .../class-wcsg-email-customer-new-account.php | 17 + ...wcsg-email-recipient-new-initial-order.php | 32 +- languages/woocommerce-subscriptions.pot | 529 +- phpstan.neon | 4347 ++++++++++++++++- src/Internal/README.md | 6 + src/Internal/Telemetry/Collector.php | 99 + src/Internal/Telemetry/Events.php | 45 + src/Internal/Telemetry/Orders.php | 1012 ++++ src/Internal/Telemetry/Products.php | 241 + src/Internal/Telemetry/Subscriptions.php | 556 +++ src/Internal/Utilities/Scheduled_Actions.php | 69 + .../recurring-itemized-tax-totals.php | 2 +- templates/checkout/recurring-tax-totals.php | 2 +- .../emails/recipient-email-order-details.php | 18 +- .../emails/recipient-new-initial-order.php | 9 +- .../add-to-cart/subscription.php | 19 +- .../add-to-cart/variable-subscription.php | 19 +- vendor/autoload.php | 7 +- vendor/autoload_packages.php | 13 - .../jetpack-autoloader/CHANGELOG.md | 537 -- .../automattic/jetpack-autoloader/README.md | 92 - .../src/AutoloadFileWriter.php | 101 - .../src/AutoloadGenerator.php | 403 -- .../src/AutoloadProcessor.php | 176 - .../src/CustomAutoloaderPlugin.php | 188 - .../src/ManifestGenerator.php | 115 - .../jetpack-autoloader/src/autoload.php | 5 - .../src/class-autoloader-handler.php | 139 - .../src/class-autoloader-locator.php | 82 - .../src/class-autoloader.php | 85 - .../src/class-container.php | 142 - .../src/class-hook-manager.php | 68 - .../src/class-latest-autoloader-guard.php | 157 - .../src/class-manifest-reader.php | 91 - .../src/class-path-processor.php | 186 - .../src/class-php-autoloader.php | 97 - .../src/class-plugin-locator.php | 145 - .../src/class-plugins-handler.php | 156 - .../src/class-shutdown-handler.php | 84 - .../src/class-version-loader.php | 176 - .../src/class-version-selector.php | 61 - .../automattic/jetpack-constants/CHANGELOG.md | 264 + .../LICENSE.txt | 0 vendor/automattic/jetpack-constants/README.md | 67 + .../SECURITY.md | 0 .../jetpack-constants/src/class-constants.php | 124 + vendor/composer/InstalledVersions.php | 45 +- vendor/composer/autoload_classmap.php | 12 +- vendor/composer/autoload_psr4.php | 1 - vendor/composer/autoload_real.php | 8 +- vendor/composer/autoload_static.php | 25 +- vendor/composer/installed.json | 55 +- vendor/composer/installed.php | 24 +- vendor/composer/jetpack_autoload_classmap.php | 577 --- vendor/composer/platform_check.php | 5 +- .../class-autoloader-handler.php | 147 - .../class-autoloader-locator.php | 90 - .../jetpack-autoloader/class-autoloader.php | 93 - vendor/jetpack-autoloader/class-container.php | 150 - .../jetpack-autoloader/class-hook-manager.php | 76 - .../class-latest-autoloader-guard.php | 165 - .../class-manifest-reader.php | 99 - .../class-path-processor.php | 194 - .../class-php-autoloader.php | 105 - .../class-plugin-locator.php | 153 - .../class-plugins-handler.php | 164 - .../class-shutdown-handler.php | 92 - .../class-version-loader.php | 184 - .../class-version-selector.php | 69 - woocommerce-subscriptions.php | 11 +- 108 files changed, 7630 insertions(+), 6281 deletions(-) create mode 100644 src/Internal/README.md create mode 100644 src/Internal/Telemetry/Collector.php create mode 100644 src/Internal/Telemetry/Events.php create mode 100644 src/Internal/Telemetry/Orders.php create mode 100644 src/Internal/Telemetry/Products.php create mode 100644 src/Internal/Telemetry/Subscriptions.php create mode 100644 src/Internal/Utilities/Scheduled_Actions.php delete mode 100644 vendor/autoload_packages.php delete mode 100644 vendor/automattic/jetpack-autoloader/CHANGELOG.md delete mode 100644 vendor/automattic/jetpack-autoloader/README.md delete mode 100644 vendor/automattic/jetpack-autoloader/src/AutoloadFileWriter.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/AutoloadGenerator.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/autoload.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-autoloader-handler.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-autoloader.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-container.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-hook-manager.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-latest-autoloader-guard.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-manifest-reader.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-path-processor.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-php-autoloader.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-plugin-locator.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-shutdown-handler.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-version-loader.php delete mode 100644 vendor/automattic/jetpack-autoloader/src/class-version-selector.php create mode 100644 vendor/automattic/jetpack-constants/CHANGELOG.md rename vendor/automattic/{jetpack-autoloader => jetpack-constants}/LICENSE.txt (100%) create mode 100644 vendor/automattic/jetpack-constants/README.md rename vendor/automattic/{jetpack-autoloader => jetpack-constants}/SECURITY.md (100%) create mode 100644 vendor/automattic/jetpack-constants/src/class-constants.php delete mode 100644 vendor/composer/jetpack_autoload_classmap.php delete mode 100644 vendor/jetpack-autoloader/class-autoloader-handler.php delete mode 100644 vendor/jetpack-autoloader/class-autoloader-locator.php delete mode 100644 vendor/jetpack-autoloader/class-autoloader.php delete mode 100644 vendor/jetpack-autoloader/class-container.php delete mode 100644 vendor/jetpack-autoloader/class-hook-manager.php delete mode 100644 vendor/jetpack-autoloader/class-latest-autoloader-guard.php delete mode 100644 vendor/jetpack-autoloader/class-manifest-reader.php delete mode 100644 vendor/jetpack-autoloader/class-path-processor.php delete mode 100644 vendor/jetpack-autoloader/class-php-autoloader.php delete mode 100644 vendor/jetpack-autoloader/class-plugin-locator.php delete mode 100644 vendor/jetpack-autoloader/class-plugins-handler.php delete mode 100644 vendor/jetpack-autoloader/class-shutdown-handler.php delete mode 100644 vendor/jetpack-autoloader/class-version-loader.php delete mode 100644 vendor/jetpack-autoloader/class-version-selector.php diff --git a/build/index.asset.php b/build/index.asset.php index a32ac5f..1673159 100644 --- a/build/index.asset.php +++ b/build/index.asset.php @@ -1 +1 @@ - array('react', 'wc-blocks-checkout', 'wc-price-format', 'wc-settings', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '33d4c418a7e0cdfdfdd5'); + array('react', 'wc-blocks-checkout', 'wc-blocks-data-store', 'wc-price-format', 'wc-settings', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '76dd98c6a2badbfb9781'); diff --git a/build/index.js b/build/index.js index 024b208..2b2ffd0 100644 --- a/build/index.js +++ b/build/index.js @@ -1,4 +1,4 @@ -(()=>{"use strict";var e={20:(e,r,s)=>{var t=s(609),n=Symbol.for("react.element"),i=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,c=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function a(e,r,s){var t,i={},a=null,p=null;for(t in void 0!==s&&(a=""+s),void 0!==r.key&&(a=""+r.key),void 0!==r.ref&&(p=r.ref),r)o.call(r,t)&&!l.hasOwnProperty(t)&&(i[t]=r[t]);if(e&&e.defaultProps)for(t in r=e.defaultProps)void 0===i[t]&&(i[t]=r[t]);return{$$typeof:n,type:e,key:a,ref:p,props:i,_owner:c.current}}r.Fragment=i,r.jsx=a,r.jsxs=a},609:e=>{e.exports=window.React},848:(e,r,s)=>{e.exports=s(20)}},r={};const s=window.wp.plugins,t=window.wc.blocksCheckout,n=window.wp.i18n,i=window.wc.priceFormat,o=window.wc.wcSettings;function c(e){return{day:(0,n._nx)("day","days",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions"),week:(0,n._nx)("week","weeks",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions"),month:(0,n._nx)("month","months",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions"),year:(0,n._nx)("year","years",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions")}}function l({billing_interval:e,billing_period:r},s,t){const i=c(e)[r];return s=s.trim(),1===e?`${t} ${s} ${i}`:(0,n.sprintf)( +(()=>{"use strict";var e={20:(e,s,i)=>{var n=i(609),t=Symbol.for("react.element"),r=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,c=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,a={key:!0,ref:!0,__self:!0,__source:!0};function l(e,s,i){var n,r={},l=null,p=null;for(n in void 0!==i&&(l=""+i),void 0!==s.key&&(l=""+s.key),void 0!==s.ref&&(p=s.ref),s)o.call(s,n)&&!a.hasOwnProperty(n)&&(r[n]=s[n]);if(e&&e.defaultProps)for(n in s=e.defaultProps)void 0===r[n]&&(r[n]=s[n]);return{$$typeof:t,type:e,key:l,ref:p,props:r,_owner:c.current}}s.Fragment=r,s.jsx=l,s.jsxs=l},609:e=>{e.exports=window.React},848:(e,s,i)=>{e.exports=i(20)}},s={};const i=window.wp.plugins,n=window.wc.blocksCheckout,t=window.wp.i18n,r=window.wc.priceFormat,o=window.wc.wcSettings,c=window.wp.data,a=window.wc.wcBlocksData;function l(e){return{day:(0,t._nx)("day","days",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions"),week:(0,t._nx)("week","weeks",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions"),month:(0,t._nx)("month","months",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions"),year:(0,t._nx)("year","years",e,"Used in recurring totals section in Cart. 2+ will need plural, 1 will need singular.","woocommerce-subscriptions")}}function p({billing_interval:e,billing_period:s},i,n){const r=l(e)[s];return i=i.trim(),1===e?`${n} ${i} ${r}`:(0,t.sprintf)( /* * translators: %1$s is the price of the product. %2$s is the separator used e.g "every" or "/", * %3$d is the length, %4$s is week, month, year @@ -7,29 +7,30 @@ * translators: %1$s is the price of the product. %2$s is the separator used e.g "every" or "/", * %3$d is the length, %4$s is week, month, year */ -(0,n.__)("%1$s %2$s %3$d %4$s","woocommerce-subscriptions"),t,s,e,i)}function a({subscriptionLength:e,billingInterval:r}){return e===r}var p=function s(t){var n=r[t];if(void 0!==n)return n.exports;var i=r[t]={exports:{}};return e[t](i,i.exports,s),i.exports}(848);const u=(0,o.getSetting)("displayCartPricesIncludingTax",!1),m=({currency:e,values:r})=>{const{total_discount:s,total_discount_tax:i}=r,o=parseInt(s,10);if(!o)return null;const c=parseInt(i,10),l=u?o+c:o;return(0,p.jsx)(t.TotalsItem,{className:"wc-block-components-totals-discount",currency:e,label:(0,n.__)("Discount","woocommerce-subscriptions"),value:-1*l})},_=({values:e,currency:r,selectedRate:s,needsShipping:i,calculatedShipping:c})=>{if(!i||!c)return null;const l=u?parseInt(e.total_shipping,10)+parseInt(e.total_shipping_tax,10):parseInt(e.total_shipping,10),a=0===l&&(0,o.isWcVersion)("9.0",">=")?(0,p.jsx)("strong",{children:(0,n.__)("Free","woocommerce-subscriptions")}):l;return(0,p.jsx)(t.TotalsItem,{value:a,label:(0,n.__)("Shipping","woocommerce-subscriptions"),currency:r,description:!!s&&(0,n.sprintf)( +(0,t.__)("%1$s %2$s %3$d %4$s","woocommerce-subscriptions"),n,i,e,r)}function u({subscriptionLength:e,billingInterval:s}){return e===s}const d=(0,o.getSetting)("countryData",{}),g=(0,o.getSetting)("countries",{}),m={...Object.fromEntries(Object.keys(d).filter((e=>!0===d[e].allowBilling)).map((e=>[e,g[e]||""]))),...Object.fromEntries(Object.keys(d).filter((e=>!0===d[e].allowShipping)).map((e=>[e,g[e]||""])))},_=Object.fromEntries(Object.keys(m).map((e=>[e,d[e].locale||{}]))),b={address:["first_name","last_name","company","address_1","address_2","city","postcode","country","state","phone"],contact:["email"],order:[]},h=Object.entries(_).reduce(((e,[s,i])=>(e[s]=Object.entries(i).reduce(((e,[s,i])=>(e[s]=(e=>{const s={};return void 0!==e.label&&(s.label=e.label),void 0!==e.required&&(s.required=e.required),void 0!==e.hidden&&(s.hidden=e.hidden),void 0===e.label||e.optionalLabel||(s.optionalLabel=(0,t.sprintf)(/* translators: %s Field label. */ /* translators: %s Field label. */ +(0,t.__)("%s (optional)","woocommerce-subscriptions"),e.label)),void 0!==e.optionalLabel&&(s.optionalLabel=e.optionalLabel),e.index&&("number"==typeof e.index&&(s.index=e.index),"string"==typeof e.index&&(s.index=parseInt(e.index,10))),e.hidden&&(s.required=!1),s})(i),e)),{}),e)),{}),w=["state","country","postcode","city"],y=e=>e.some((e=>!!e.shipping_rates.length)),f=(0,o.getSetting)("collectableMethodIds",[]),v=(0,o.getSetting)("localPickupEnabled",!1);var x=function i(n){var t=s[n];if(void 0!==t)return t.exports;var r=s[n]={exports:{}};return e[n](r,r.exports,i),r.exports}(848);const k=(0,o.getSetting)("displayCartPricesIncludingTax",!1),S=({currency:e,values:s,isLoading:i})=>{const{total_discount:r,total_discount_tax:o}=s,c=parseInt(r,10);if(!c)return null;const a=parseInt(o,10),l=k?c+a:c;return(0,x.jsx)(n.TotalsItem,{className:"wc-block-components-totals-discount",currency:e,label:(0,t.__)("Discount","woocommerce-subscriptions"),value:-1*l,showSkeleton:i})},j=({values:e,currency:s,shippingRatePackages:i,isLoading:n,needsShipping:r,calculatedShipping:l,shippingAddress:p})=>{const u=(0,c.useSelect)((e=>e(a.checkoutStore).prefersCollection()));if(!r||!l)return null;const d=(_=((e,s)=>e.map((e=>({...e,shipping_rates:e.shipping_rates.filter((e=>{const i=(n=e.method_id,!!v&&(Array.isArray(n)?!!n.find((e=>f.includes(e))):f.includes(n)));var n;return s?i:!i}))}))))(i,null!=u&&u),!!y(_)&&_.every((e=>e.shipping_rates.every((e=>!e.selected||(e=>f.includes(e.method_id))(e)))))),g=!!(m=p).country&&((e,s,i="")=>{const n=i&&void 0!==h[i]?h[i]:{};return e.map((e=>({key:e,...s&&e in s?s[e]:{},...n&&e in n?n[e]:{}}))).sort(((e,s)=>e.index-s.index))})((0,o.getSetting)("addressFieldsLocations",b).address,o.defaultFields,m.country).filter((({key:e})=>w.includes(e))).every((({key:e,hidden:s,required:i})=>!0===s||!1===i||e in m&&""!==m[e]));var m,_;return(0,x.jsx)(I,{label:d?(0,t.__)("Pickup","woocommerce-subscriptions"):(0,t.__)("Delivery","woocommerce-subscriptions"),placeholder:(0,x.jsx)("span",{className:"wc-block-components-shipping-placeholder__value",children:g?(0,t.__)("No available delivery option","woocommerce-subscriptions"):(0,t.__)("Enter address to calculate","woocommerce-subscriptions")}),isLoading:n,shippingRatePackages:i,currency:s,values:e})},I=({values:e,currency:s,shippingRatePackages:i,label:r,placeholder:c,isLoading:a})=>{const l=i?.flatMap((e=>e.shipping_rates)).find((({selected:e})=>e))?.name,p=!!y(u=i)&&u.some((e=>e.shipping_rates.some((e=>e.selected))));var u;const d=!p||i?.length>1?r:(0,t.__)("Shipping","woocommerce-subscriptions"),g=k?parseInt(e.total_shipping,10)+parseInt(e.total_shipping_tax,10):parseInt(e.total_shipping,10),m=0===g&&(0,o.isWcVersion)("9.0",">=")?(0,x.jsx)("strong",{children:(0,t.__)("Free","woocommerce-subscriptions")}):g;return(0,x.jsx)(n.TotalsItem,{value:p?m:c,label:d,currency:s,showSkeleton:a,description:!!l&&(0,t.sprintf)( // translators: %s selected shipping rate (ex: flat rate) // translators: %s selected shipping rate (ex: flat rate) -(0,n.__)("via %s","woocommerce-subscriptions"),s)})},g=({nextPaymentDate:e,subscriptionLength:r,billingPeriod:s,billingInterval:t})=>{const i=function({subscriptionLength:e,billingPeriod:r}){const s=c(e);return(0,n.sprintf)("For %1$d %2$s",e,s[r],"woocommerce-subscriptions")}({subscriptionLength:r,billingPeriod:s}),o=a({subscriptionLength:r,billingInterval:t})?(0,n.sprintf)(/* Translators: %1$s is a date. */ /* Translators: %1$s is a date. */ -(0,n.__)("Due: %1$s","woocommerce-subscriptions"),e):(0,n.sprintf)(/* Translators: %1$s is a date. */ /* Translators: %1$s is a date. */ -(0,n.__)("Starting: %1$s","woocommerce-subscriptions"),e);return(0,p.jsxs)("span",{children:[!!e&&o," ",!!r&&r>=t&&(0,p.jsx)("span",{className:"wcs-recurring-totals__subscription-length",children:i})]})},d=({currency:e,billingInterval:r,billingPeriod:s,nextPaymentDate:i,subscriptionLength:o,totals:c})=>{const l=a({billingInterval:r,subscriptionLength:o})?(0,n.__)("Total","woocommerce-subscriptions"):function({billingInterval:e,billingPeriod:r}){switch(e){case 1:if("day"===r)return(0,n.__)("Daily recurring total","woocommerce-subscriptions");if("week"===r)return(0,n.__)("Weekly recurring total","woocommerce-subscriptions");if("month"===r)return(0,n.__)("Monthly recurring total","woocommerce-subscriptions");if("year"===r)return(0,n.__)("Yearly recurring total","woocommerce-subscriptions");break;case 2:return(0,n.sprintf)(/* translators: %1$s is week, month, year */ /* translators: %1$s is week, month, year */ -(0,n.__)("Recurring total every 2nd %1$s","woocommerce-subscriptions"),r);case 3:return(0,n.sprintf)(/* Translators: %1$s is week, month, year */ /* Translators: %1$s is week, month, year */ -(0,n.__)("Recurring total every 3rd %1$s","woocommerce-subscriptions"),r);default:return(0,n.sprintf)(/* Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year */ /* Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year */ -(0,n.__)("Recurring total every %1$dth %2$s","woocommerce-subscriptions"),e,r)}}({billingInterval:r,billingPeriod:s});return(0,p.jsx)(t.TotalsItem,{className:"wcs-recurring-totals-panel__title",currency:e,label:l,value:c,description:(0,p.jsx)(g,{nextPaymentDate:i,subscriptionLength:o,billingInterval:r,billingPeriod:s})})},b=({subscription:e,needsShipping:r,calculatedShipping:s})=>{const{totals:o,billing_interval:c,billing_period:l,next_payment_date:a,subscription_length:g,shipping_rates:b}=e;if(!a)return null;const w=b?.[0]?.shipping_rates?.find((({selected:e})=>e))?.name,h=(0,i.getCurrencyFromPriceResponse)(o);return(0,p.jsxs)("div",{className:"wcs-recurring-totals-panel",children:[(0,p.jsx)(d,{billingInterval:c,billingPeriod:l,nextPaymentDate:a,subscriptionLength:g,totals:parseInt(o.total_price,10),currency:h}),(0,p.jsxs)(t.Panel,{className:"wcs-recurring-totals-panel__details",initialOpen:!1,title:(0,n.__)("Details","woocommerce-subscriptions"),children:[(0,p.jsxs)(t.TotalsWrapper,{children:[(0,p.jsx)(t.Subtotal,{currency:h,values:o}),(0,p.jsx)(m,{currency:h,values:o})]}),(0,p.jsx)(t.TotalsWrapper,{className:"wc-block-components-totals-shipping",children:(0,p.jsx)(_,{currency:h,needsShipping:r,calculatedShipping:s,values:o,selectedRate:w})}),!u&&(0,p.jsx)(t.TotalsWrapper,{children:(0,p.jsx)(t.TotalsTaxes,{currency:h,values:o})}),(0,p.jsx)(t.TotalsWrapper,{children:(0,p.jsx)(t.TotalsItem,{className:"wcs-recurring-totals-panel__details-total",currency:h,label:(0,n.__)("Total","woocommerce-subscriptions"),value:parseInt(o.total_price,10)})})]})]})},w=({extensions:e,cart:r})=>{const{subscriptions:s}=e,{cartNeedsShipping:t,cartHasCalculatedShipping:n}=r;return s&&0!==s.length?s.map((({key:e,...r})=>(0,p.jsx)(b,{subscription:r,needsShipping:t,calculatedShipping:n},e))):null},h=window.wp.element,x=({extensions:e,collapsible:r,collapse:s,showItems:t,noResultsMessage:n,renderOption:i,components:o,context:c})=>{const{subscriptions:l=[]}=e,{ShippingRatesControlPackage:a}=o,u=(0,h.useMemo)((()=>Object.values(l).map((e=>e.shipping_rates)).filter(Boolean).flat()),[l]),m=(0,h.useMemo)((()=>u.length>1||s),[u.length,s]),_=(0,h.useMemo)((()=>u.length>1||t),[u.length,t]);return u.map((({package_id:e,...s})=>(0,p.jsx)(a,{packageId:e,packageData:s,collapsible:r,collapse:m,showItems:_,noResultsMessage:n,renderOption:i,highlightChecked:"woocommerce/checkout"===c},e)))};(0,s.registerPlugin)("woocommerce-subscriptions",{render:()=>(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(t.ExperimentalOrderShippingPackages,{children:(0,p.jsx)(x,{})}),(0,p.jsx)(t.ExperimentalOrderMeta,{children:(0,p.jsx)(w,{})})]}),scope:"woocommerce-checkout"}),(0,t.registerCheckoutFilters)("woocommerce-subscriptions",{totalLabel:(e,{subscriptions:r})=>r?.length>0?(0,n.__)("Total due today","woocommerce-subscriptions"):e,subtotalPriceFormat:(e,{subscriptions:r})=>{if(r?.billing_period&&r?.billing_interval){const{billing_interval:s,subscription_length:t}=r;return a({subscriptionLength:t,billingInterval:s})?l(r,1===t? +(0,t.__)("via %s","woocommerce-subscriptions"),l)})},L=({nextPaymentDate:e,subscriptionLength:s,billingPeriod:i,billingInterval:n})=>{const r=function({subscriptionLength:e,billingPeriod:s}){const i=l(e);return(0,t.sprintf)("For %1$d %2$s",e,i[s],"woocommerce-subscriptions")}({subscriptionLength:s,billingPeriod:i}),o=u({subscriptionLength:s,billingInterval:n})?(0,t.sprintf)(/* Translators: %1$s is a date. */ /* Translators: %1$s is a date. */ +(0,t.__)("Due: %1$s","woocommerce-subscriptions"),e):(0,t.sprintf)(/* Translators: %1$s is a date. */ /* Translators: %1$s is a date. */ +(0,t.__)("Starting: %1$s","woocommerce-subscriptions"),e);return(0,x.jsxs)("span",{children:[!!e&&o," ",!!s&&s>=n&&(0,x.jsx)("span",{className:"wcs-recurring-totals__subscription-length",children:r})]})},P=({currency:e,billingInterval:s,billingPeriod:i,nextPaymentDate:r,subscriptionLength:o,totals:c,isLoading:a})=>{const l=u({billingInterval:s,subscriptionLength:o})?(0,t.__)("Total","woocommerce-subscriptions"):function({billingInterval:e,billingPeriod:s}){switch(e){case 1:if("day"===s)return(0,t.__)("Daily recurring total","woocommerce-subscriptions");if("week"===s)return(0,t.__)("Weekly recurring total","woocommerce-subscriptions");if("month"===s)return(0,t.__)("Monthly recurring total","woocommerce-subscriptions");if("year"===s)return(0,t.__)("Yearly recurring total","woocommerce-subscriptions");break;case 2:return(0,t.sprintf)(/* translators: %1$s is week, month, year */ /* translators: %1$s is week, month, year */ +(0,t.__)("Recurring total every 2nd %1$s","woocommerce-subscriptions"),s);case 3:return(0,t.sprintf)(/* Translators: %1$s is week, month, year */ /* Translators: %1$s is week, month, year */ +(0,t.__)("Recurring total every 3rd %1$s","woocommerce-subscriptions"),s);default:return(0,t.sprintf)(/* Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year */ /* Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year */ +(0,t.__)("Recurring total every %1$dth %2$s","woocommerce-subscriptions"),e,s)}}({billingInterval:s,billingPeriod:i});return(0,x.jsx)(n.TotalsItem,{className:"wcs-recurring-totals-panel__title",currency:e,label:l,value:c,showSkeleton:a,description:(0,x.jsx)(L,{nextPaymentDate:r,subscriptionLength:o,billingInterval:s,billingPeriod:i})})},O=({subscription:e,needsShipping:s,calculatedShipping:i,shippingAddress:o})=>{const{isLoading:l}=(()=>{const{cartIsLoading:e,isLoadingRates:s,hasPendingItemsOperations:i,isApplyingCoupon:n,isRemovingCoupon:t}=(0,c.useSelect)((e=>{const s=e(a.cartStore);return{cartIsLoading:!s.hasFinishedResolution("getCartData",[]),isLoadingRates:s.isAddressFieldsForShippingRatesUpdating(),hasPendingItemsOperations:s.hasPendingItemsOperations(),isApplyingCoupon:s.isApplyingCoupon(),isRemovingCoupon:s.isRemovingCoupon()}}),[]),r=(0,c.useSelect)((e=>e(a.checkoutStore).isCalculating()),[]);return{isLoading:e||s||n||t||r||i}})(),{totals:p,billing_interval:u,billing_period:d,next_payment_date:g,subscription_length:m,shipping_rates:_}=e;if(!g)return null;const b=(0,r.getCurrencyFromPriceResponse)(p);return(0,x.jsxs)("div",{className:"wcs-recurring-totals-panel",children:[(0,x.jsx)(P,{billingInterval:u,billingPeriod:d,nextPaymentDate:g,subscriptionLength:m,totals:parseInt(p.total_price,10),currency:b,isLoading:l}),(0,x.jsxs)(n.Panel,{className:"wcs-recurring-totals-panel__details",initialOpen:!1,title:(0,t.__)("Details","woocommerce-subscriptions"),children:[(0,x.jsxs)(n.TotalsWrapper,{children:[(0,x.jsx)(n.Subtotal,{currency:b,values:p,showSkeleton:l}),(0,x.jsx)(S,{currency:b,values:p,isLoading:l})]}),(0,x.jsx)(n.TotalsWrapper,{className:"wc-block-components-totals-shipping",children:(0,x.jsx)(j,{currency:b,needsShipping:s,calculatedShipping:i,values:p,shippingAddress:o,shippingRatePackages:_,isLoading:l})}),!k&&(0,x.jsx)(n.TotalsWrapper,{children:(0,x.jsx)(n.TotalsTaxes,{currency:b,values:p})}),(0,x.jsx)(n.TotalsWrapper,{children:(0,x.jsx)(n.TotalsItem,{className:"wcs-recurring-totals-panel__details-total",currency:b,label:(0,t.__)("Total","woocommerce-subscriptions"),value:parseInt(p.total_price,10),showSkeleton:l})})]})]})},R=({extensions:e,cart:s})=>{const{subscriptions:i}=e,{cartNeedsShipping:n,cartHasCalculatedShipping:t,shippingAddress:r}=s;return i&&0!==i.length?i.map((({key:e,...s})=>(0,x.jsx)(O,{subscription:s,needsShipping:n,calculatedShipping:t,shippingAddress:r},e))):null},C=window.wp.element,$=({extensions:e,collapsible:s,collapse:i,showItems:n,noResultsMessage:t,renderOption:r,components:o,context:c})=>{const{subscriptions:a=[]}=e,{ShippingRatesControlPackage:l}=o,p=(0,C.useMemo)((()=>Object.values(a).map((e=>e.shipping_rates)).filter(Boolean).flat()),[a]),u=(0,C.useMemo)((()=>p.length>1||i),[p.length,i]),d=(0,C.useMemo)((()=>p.length>1||n),[p.length,n]);return p.filter((e=>!e.match_initial_rates&&e.needs_shipping)).map((({package_id:e,...i})=>(0,x.jsx)(l,{packageId:e,packageData:i,collapsible:s,collapse:u,showItems:d,noResultsMessage:t,renderOption:r,highlightChecked:"woocommerce/checkout"===c},e)))};(0,i.registerPlugin)("woocommerce-subscriptions",{render:()=>(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(n.ExperimentalOrderShippingPackages,{children:(0,x.jsx)($,{})}),(0,x.jsx)(n.ExperimentalOrderMeta,{children:(0,x.jsx)(R,{})})]}),scope:"woocommerce-checkout"}),(0,n.registerCheckoutFilters)("woocommerce-subscriptions",{totalLabel:(e,{subscriptions:s})=>s?.length>0?(0,t.__)("Total due today","woocommerce-subscriptions"):e,subtotalPriceFormat:(e,{subscriptions:s})=>{if(s?.billing_period&&s?.billing_interval){const{billing_interval:i,subscription_length:n}=s;return u({subscriptionLength:n,billingInterval:i})?p(s,1===n? // translators: the word used to describe billing frequency, e.g. "for" 1 day or "for" 1 month. // translators: the word used to describe billing frequency, e.g. "for" 1 day or "for" 1 month. -(0,n.__)("for 1","woocommerce-subscriptions"): +(0,t.__)("for 1","woocommerce-subscriptions"): // translators: the word used to describe billing frequency, e.g. "for" 6 days or "for" 2 weeks. // translators: the word used to describe billing frequency, e.g. "for" 6 days or "for" 2 weeks. -(0,n.__)("for","woocommerce-subscriptions"),e):l(r, +(0,t.__)("for","woocommerce-subscriptions"),e):p(s, // translators: the word used to describe billing frequency, e.g. "every" 6 days or "every" 2 weeks. // translators: the word used to describe billing frequency, e.g. "every" 6 days or "every" 2 weeks. -(0,n.__)("every","woocommerce-subscriptions"),e)}return e},saleBadgePriceFormat:(e,{subscriptions:r})=>r?.billing_period&&r?.billing_interval?l(r,"/",e):e,itemName:(e,{subscriptions:r})=>r?.is_resubscribe?(0,n.sprintf)( +(0,t.__)("every","woocommerce-subscriptions"),e)}return e},saleBadgePriceFormat:(e,{subscriptions:s})=>s?.billing_period&&s?.billing_interval?p(s,"/",e):e,itemName:(e,{subscriptions:s})=>s?.is_resubscribe?(0,t.sprintf)( // translators: %s Product name. // translators: %s Product name. -(0,n.__)("%s (resubscription)","woocommerce-subscriptions"),e):r?.switch_type?(0,n.sprintf)( +(0,t.__)("%s (resubscription)","woocommerce-subscriptions"),e):s?.switch_type?(0,t.sprintf)( // translators: %1$s Product name, %2$s Switch type (upgraded, downgraded, or crossgraded). // translators: %1$s Product name, %2$s Switch type (upgraded, downgraded, or crossgraded). -(0,n.__)("%1$s (%2$s)","woocommerce-subscriptions"),e,function(e){switch(e){case"upgraded":return(0,n.__)("Upgrade","woocommerce-subscriptions");case"downgraded":return(0,n.__)("Downgrade","woocommerce-subscriptions");case"crossgraded":return(0,n.__)("Crossgrade","woocommerce-subscriptions");default:return""}}(r.switch_type)):e,cartItemPrice:(e,{subscriptions:r},{context:s})=>r?.sign_up_fees?"cart"===s?(0,n.sprintf)(/* translators: %s is the subscription price to pay immediately (ie: $10). */ /* translators: %s is the subscription price to pay immediately (ie: $10). */ -(0,n.__)("Due today %s","woocommerce-subscriptions"),e):(0,n.sprintf)(/* translators: %s is the subscription price to pay immediately (ie: $10). */ /* translators: %s is the subscription price to pay immediately (ie: $10). */ -(0,n.__)("%s due today","woocommerce-subscriptions"),e):e,placeOrderButtonLabel:e=>{const r=(0,o.getSetting)("subscriptions_data");return r?.place_order_override?r?.place_order_override:e}})})(); \ No newline at end of file +(0,t.__)("%1$s (%2$s)","woocommerce-subscriptions"),e,function(e){switch(e){case"upgraded":return(0,t.__)("Upgrade","woocommerce-subscriptions");case"downgraded":return(0,t.__)("Downgrade","woocommerce-subscriptions");case"crossgraded":return(0,t.__)("Crossgrade","woocommerce-subscriptions");default:return""}}(s.switch_type)):e,cartItemPrice:(e,{subscriptions:s},{context:i})=>s?.sign_up_fees?"cart"===i?(0,t.sprintf)(/* translators: %s is the subscription price to pay immediately (ie: $10). */ /* translators: %s is the subscription price to pay immediately (ie: $10). */ +(0,t.__)("Due today %s","woocommerce-subscriptions"),e):(0,t.sprintf)(/* translators: %s is the subscription price to pay immediately (ie: $10). */ /* translators: %s is the subscription price to pay immediately (ie: $10). */ +(0,t.__)("%s due today","woocommerce-subscriptions"),e):e,placeOrderButtonLabel:e=>{const s=(0,o.getSetting)("subscriptions_data");return s?.place_order_override?s?.place_order_override:e}})})(); \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 3fc9a21..791b42c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,26 @@ *** WooCommerce Subscriptions Changelog *** -2025-09-16 - version 7.9.0 +2025-10-15 - version 8.0.0 +* Add: Blocks Checkout now displays a single shipping method selection for both initial and recurring carts, similar to Classic Checkout. This can be disabled using the `wcs_cart_totals_shipping_html_price_only` filter. +* Update: Exclude orders with a "processing" status from the "subscription_orders" telemetry data. +* Fix: Reactivating limited subscriptions from product page is now supported. +* Fix: Gifting email previews. +* Fix: Shipping label on blocks checkout no more shows up as "Free" when there's no shipping method available. +* Dev: Opt-in tracking data. Data sent to WooCommerce: + * WooCommerce Subscriptions setting values + * Order totals of subscription-related orders by order type and payment gateway, aggregated by month + * Number of subscription-related orders by order type and payment gateway, aggregated by month + * Number of products in parent subscription orders, aggregated by month + * Number of non-zero value parent subscription orders, aggregated by month + * Number of subscription products by billing interval + * Number of giftable subscription products + * Number of subscriptions by payment method, billing period, and renewal type + * Number of gifted subscriptions + * Number of subscribers + * Purchase event for subscription products + * To disable this tracking, opt-out of WooCommerce tracking, see https://woocommerce.com/usage-tracking/ +2025-09-16 - version 7.9.0 * Add: REST API endpoint to retrieve subscriptions associated with a specific order ID. * Fix: Keep subscription with successful renewals active when parent order fails. * Fix: Error when renewing subscriptions with downloadable gifts. diff --git a/includes/class-wc-subscriptions-plugin.php b/includes/class-wc-subscriptions-plugin.php index f765e63..570aa13 100644 --- a/includes/class-wc-subscriptions-plugin.php +++ b/includes/class-wc-subscriptions-plugin.php @@ -8,6 +8,8 @@ defined( 'ABSPATH' ) || exit; +use Automattic\WooCommerce_Subscriptions\Internal\Telemetry\Events as WC_Tracks_Events; + /** * @method static WC_Subscriptions_Plugin instance() */ @@ -33,6 +35,9 @@ class WC_Subscriptions_Plugin extends WC_Subscriptions_Core_Plugin { WCS_Subscriber_Role_Manager::init(); WCS_Upgrade_Notice_Manager::init(); + $tracks_events = new WC_Tracks_Events(); + $tracks_events->setup(); + if ( defined( 'WP_CLI' ) && WP_CLI ) { new WC_Subscriptions_CLI(); } diff --git a/includes/class-wcs-webhooks.php b/includes/class-wcs-webhooks.php index 504d1fc..9936f3e 100644 --- a/includes/class-wcs-webhooks.php +++ b/includes/class-wcs-webhooks.php @@ -138,9 +138,7 @@ class WCS_Webhooks { throw new \Exception( 'The Legacy REST API plugin is not installed on this site. More information: https://developer.woocommerce.com/2023/10/03/the-legacy-rest-api-will-move-to-a-dedicated-extension-in-woocommerce-9-0/ ' ); } - // @phpstan-ignore-next-line WC()->api->WC_API_Subscriptions->register_routes( array() ); - // @phpstan-ignore-next-line $payload = WC()->api->WC_API_Subscriptions->get_subscription( $resource_id ); break; case 'wp_api_v1': diff --git a/includes/core/admin/class-wcs-admin-post-types.php b/includes/core/admin/class-wcs-admin-post-types.php index e70f049..992812a 100644 --- a/includes/core/admin/class-wcs-admin-post-types.php +++ b/includes/core/admin/class-wcs-admin-post-types.php @@ -1868,7 +1868,6 @@ class WCS_Admin_Post_Types { * @return string[] $pieces Updated associative array of clauses for the query. */ private function orders_table_clauses_low_performance( $pieces ) { - // @phpstan-ignore-next-line $order_datastore = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::class ); $order_table = $order_datastore::get_orders_table_name(); $meta_table = $order_datastore::get_meta_table_name(); @@ -1899,7 +1898,6 @@ class WCS_Admin_Post_Types { private function orders_table_clauses_high_performance( $pieces ) { global $wpdb; - // @phpstan-ignore-next-line $order_datastore = wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::class ); $order_table = $order_datastore::get_orders_table_name(); $meta_table = $order_datastore::get_meta_table_name(); diff --git a/includes/core/class-wc-subscriptions-cart.php b/includes/core/class-wc-subscriptions-cart.php index 8565e15..3ae4800 100644 --- a/includes/core/class-wc-subscriptions-cart.php +++ b/includes/core/class-wc-subscriptions-cart.php @@ -1088,21 +1088,11 @@ class WC_Subscriptions_Cart { self::set_cached_recurring_cart( $recurring_cart ); foreach ( $recurring_cart->get_shipping_packages() as $recurring_cart_package_key => $recurring_cart_package ) { - $package_index = isset( $recurring_cart_package['package_index'] ) ? $recurring_cart_package['package_index'] : 0; - $package = WC()->shipping->calculate_shipping_for_package( $recurring_cart_package ); - - $package_rates_match = false; - if ( isset( $standard_packages[ $package_index ] ) ) { - // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - $package_rates_match = apply_filters( 'wcs_recurring_shipping_package_rates_match_standard_rates', $package['rates'] == $standard_packages[ $package_index ]['rates'], $package['rates'], $standard_packages[ $package_index ]['rates'], $recurring_cart_key ); + if ( self::package_rates_match_initial_rates( $standard_packages, $recurring_cart_package, $recurring_cart_key, $recurring_cart ) ) { + continue; } - if ( $package_rates_match ) { - // The recurring package rates match the initial package rates, there won't be a selected shipping method for this recurring cart package move on to the next package. - if ( apply_filters( 'wcs_cart_totals_shipping_html_price_only', true, $package, $recurring_cart ) ) { - continue; - } - } + $package = WC()->shipping->calculate_shipping_for_package( $recurring_cart_package ); // If the chosen shipping method is not available for this recurring cart package, display an error and unset the selected method. if ( ! isset( $package['rates'][ $shipping_methods[ $recurring_cart_package_key ] ] ) ) { @@ -1127,6 +1117,47 @@ class WC_Subscriptions_Cart { self::set_cached_recurring_cart( $cached_recurring_cart ); } + /** + * Checks if the recurring package rates match the initial package rates. + * + * @param array $standard_packages The standard packages. + * @param array $recurring_cart_package The recurring cart package. + * @param string $recurring_cart_key The recurring cart key. + * @param object $recurring_cart The recurring cart. + * @return bool Whether the recurring package rates match the initial package rates. + */ + public static function package_rates_match_initial_rates( $standard_packages, $recurring_cart_package, $recurring_cart_key, $recurring_cart ) { + $package_index = isset( $recurring_cart_package['package_index'] ) ? $recurring_cart_package['package_index'] : 0; + $package = WC()->shipping->calculate_shipping_for_package( $recurring_cart_package ); + + $package_rates_match = false; + if ( isset( $standard_packages[ $package_index ] ) ) { + // Ignore item names during the comparison. + $package_rates = array_map( + [ __CLASS__, 'remove_item_names_from_rate' ], + $package['rates'] + ); + $initial_rates = array_map( + [ __CLASS__, 'remove_item_names_from_rate' ], + $standard_packages[ $package_index ]['rates'] + ); + + // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual -- Order of array values is not important. + $package_rates_match = apply_filters( 'wcs_recurring_shipping_package_rates_match_standard_rates', $package_rates == $initial_rates, $package['rates'], $standard_packages[ $package_index ]['rates'], $recurring_cart_key ); + } + + if ( $package_rates_match ) { + /** + * The recurring package rates match the initial package rates, there won't be a selected shipping method for this recurring cart package move on to the next package. + * + * phpcs:disable WooCommerce.Commenting.CommentHooks.MissingSinceComment + */ + return apply_filters( 'wcs_cart_totals_shipping_html_price_only', true, $package, $recurring_cart ); + } + + return false; + } + /** * Checks the cart to see if it contains a specific product. * @@ -2539,4 +2570,17 @@ class WC_Subscriptions_Cart { return true; } + + /** + * Remove the item names from the shipping rate + * to check if the rates match. + * + * @param WC_Shipping_Rate $rate The rate. + * @return WC_Shipping_Rate The rate. + */ + private static function remove_item_names_from_rate( $rate ) { + $rate->add_meta_data( 'Items', null ); + + return $rate; + } } diff --git a/includes/core/class-wc-subscriptions-extend-store-endpoint.php b/includes/core/class-wc-subscriptions-extend-store-endpoint.php index 3df0371..78b25f5 100644 --- a/includes/core/class-wc-subscriptions-extend-store-endpoint.php +++ b/includes/core/class-wc-subscriptions-extend-store-endpoint.php @@ -60,6 +60,8 @@ class WC_Subscriptions_Extend_Store_Endpoint { // @phpstan-ignore class.notFound self::$currency_formatter = function_exists( 'woocommerce_store_api_get_formatter' ) ? woocommerce_store_api_get_formatter( 'currency' ) : Package::container()->get( ExtendRestApi::class )->get_formatter( 'currency' ); self::extend_store(); + + add_action( 'woocommerce_store_api_cart_select_shipping_rate', [ __CLASS__, 'initial_shipment_select_shipping_rate' ], 10, 2 ); } /** @@ -331,6 +333,7 @@ class WC_Subscriptions_Extend_Store_Endpoint { } $future_subscriptions = array(); + $standard_packages = WC()->shipping->get_packages(); if ( ! empty( wc()->cart->recurring_carts ) ) { foreach ( wc()->cart->recurring_carts as $cart_key => $cart ) { @@ -359,7 +362,18 @@ class WC_Subscriptions_Extend_Store_Endpoint { 'tax_lines' => self::get_tax_lines( $cart ), ) ), - 'shipping_rates' => array_values( array_map( array( self::$schema->get( 'cart-shipping-rate' ), 'get_item_response' ), $shipping_packages ) ), + 'shipping_rates' => array_values( + array_map( + function ( $package ) use ( $cart, $cart_key, $standard_packages ) { + $shipping_package = self::$schema->get( 'cart-shipping-rate' )->get_item_response( $package ); + $shipping_package['match_initial_rates'] = WC_Subscriptions_Cart::package_rates_match_initial_rates( $standard_packages, $package, $cart_key, $cart ); + $shipping_package['needs_shipping'] = WC_Subscriptions_Cart::cart_contains_subscriptions_needing_shipping( $cart ); + + return $shipping_package; + }, + $shipping_packages + ) + ), ); } } @@ -367,6 +381,42 @@ class WC_Subscriptions_Extend_Store_Endpoint { return $future_subscriptions; } + /** + * Select the initial shipment shipping rate. + * + * @param string $package_id Package ID. + * @param string $rate_id Rate ID. + */ + public static function initial_shipment_select_shipping_rate( $package_id, $rate_id ) { + WC()->cart->calculate_totals(); + + $standard_packages = WC()->shipping->get_packages(); + + if ( ! is_numeric( $package_id ) || key( $standard_packages ) !== (int) $package_id ) { + return; + } + + foreach ( WC()->cart->recurring_carts as $recurring_cart_key => $recurring_cart ) { + if ( false === $recurring_cart->needs_shipping() || 0 === $recurring_cart->next_payment_date ) { + continue; + } + + WC_Subscriptions_Cart::set_calculation_type( 'recurring_total' ); + WC_Subscriptions_Cart::set_recurring_cart_key( $recurring_cart_key ); + WC_Subscriptions_Cart::set_cached_recurring_cart( $recurring_cart ); + + foreach ( $recurring_cart->get_shipping_packages() as $recurring_cart_package_key => $recurring_cart_package ) { + if ( WC_Subscriptions_Cart::package_rates_match_initial_rates( $standard_packages, $recurring_cart_package, $recurring_cart_key, $recurring_cart ) ) { + $session_data = wc()->session->get( 'chosen_shipping_methods' ) ? wc()->session->get( 'chosen_shipping_methods' ) : []; + + $session_data[ $recurring_cart_package_key ] = $rate_id; + + wc()->session->set( 'chosen_shipping_methods', $session_data ); + } + } + } + } + /** * Format sign-up fees. * diff --git a/includes/core/class-wc-subscriptions-order.php b/includes/core/class-wc-subscriptions-order.php index b5bd3d7..e9204d7 100644 --- a/includes/core/class-wc-subscriptions-order.php +++ b/includes/core/class-wc-subscriptions-order.php @@ -2478,7 +2478,6 @@ f * if ( isset( $order->$meta_key ) ) { // WC 2.1+ magic __isset() & __get() methods $meta_value = $order->$meta_key; - // @phpstan-ignore-next-line } elseif ( is_array( $order->order_custom_fields ) && isset( $order->order_custom_fields[ '_' . $meta_key ][0] ) && $order->order_custom_fields[ '_' . $meta_key ][0] ) { // < WC 2.1+ $meta_value = maybe_unserialize( $order->order_custom_fields[ '_' . $meta_key ][0] ); } else { diff --git a/includes/core/class-wc-subscriptions-tracker.php b/includes/core/class-wc-subscriptions-tracker.php index d504221..df39ad4 100644 --- a/includes/core/class-wc-subscriptions-tracker.php +++ b/includes/core/class-wc-subscriptions-tracker.php @@ -5,12 +5,17 @@ * @class WC_Subscriptions_Tracker * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.6.4 * @package WooCommerce Subscriptions/Classes - * @category Class */ defined( 'ABSPATH' ) || exit; +use Automattic\WooCommerce_Subscriptions\Internal\Telemetry\Collector; + class WC_Subscriptions_Tracker { + /** + * Handles the collection of additional pieces of data. + */ + private static Collector $telemetry_collector; /** * Initialize the Tracker. @@ -18,6 +23,8 @@ class WC_Subscriptions_Tracker { public static function init() { // Only add data if Tracker enabled if ( 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) ) { + self::$telemetry_collector = new Collector(); + self::$telemetry_collector->setup(); add_filter( 'woocommerce_tracker_data', [ __CLASS__, 'add_subscriptions_tracking_data' ], 10, 1 ); } } @@ -32,6 +39,11 @@ class WC_Subscriptions_Tracker { $data['extensions']['wc_subscriptions']['settings'] = self::get_subscriptions_options(); $data['extensions']['wc_subscriptions']['subscriptions'] = self::get_subscriptions(); $data['extensions']['wc_subscriptions']['subscription_orders'] = self::get_subscription_orders(); + + // Insert any additional telemetry that we have been collecting. + $additional_telemetry = self::$telemetry_collector->get_telemetry_data(); + $data['extensions']['wc_subscriptions'] = array_merge_recursive( $data['extensions']['wc_subscriptions'], $additional_telemetry ); + return $data; } @@ -41,47 +53,86 @@ class WC_Subscriptions_Tracker { * @return array Subscriptions options data. */ private static function get_subscriptions_options() { + $customer_notifications_offset = get_option( WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$offset_setting_string, [] ); + return [ // Staging and live site 'wc_subscriptions_staging' => WCS_Staging::is_duplicate_site() ? 'staging' : 'live', 'wc_subscriptions_live_url' => esc_url( WCS_Staging::get_site_url_from_source( 'subscriptions_install' ) ), - // Button text, roles + // Button text + // Add to Cart Button Text 'add_to_cart_button_text' => get_option( WC_Subscriptions_Admin::$option_prefix . '_add_to_cart_button_text' ), + // Place Order Button Text 'order_button_text' => get_option( WC_Subscriptions_Admin::$option_prefix . '_order_button_text' ), + + // Roles + // Subscriber Default Role 'subscriber_role' => get_option( WC_Subscriptions_Admin::$option_prefix . '_subscriber_role' ), + // Inactive Subscriber Role 'cancelled_role' => get_option( WC_Subscriptions_Admin::$option_prefix . '_cancelled_role' ), // Renewals + // Accept Manual Renewals 'accept_manual_renewals' => get_option( WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals' ), + // Turn off Automatic Payments 'turn_off_automatic_payments' => 'no' === get_option( WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals' ) ? 'none' : get_option( WC_Subscriptions_Admin::$option_prefix . '_turn_off_automatic_payments', 'none' ), + // Auto Renewal Toggle 'enable_auto_renewal_toggle' => get_option( WC_Subscriptions_Admin::$option_prefix . '_enable_auto_renewal_toggle' ), // Early renewal + // Accept Early Renewal Payments 'enable_early_renewal' => get_option( WC_Subscriptions_Admin::$option_prefix . '_enable_early_renewal' ), + // Accept Early Renewal Payments via a Modal 'enable_early_renewal_via_modal' => 'no' === get_option( WC_Subscriptions_Admin::$option_prefix . '_enable_early_renewal' ) ? 'none' : get_option( WC_Subscriptions_Admin::$option_prefix . '_enable_early_renewal_via_modal', 'none' ), // Switching + // Between Subscription Variations and Between Grouped Subscriptions are condensed into this setting. 'allow_switching' => get_option( WC_Subscriptions_Admin::$option_prefix . '_allow_switching' ), + // Prorate Recurring Payment 'apportion_recurring_price' => get_option( WC_Subscriptions_Admin::$option_prefix . '_apportion_recurring_price', 'none' ), + // Prorate Sign up Fee 'apportion_sign_up_fee' => get_option( WC_Subscriptions_Admin::$option_prefix . '_apportion_sign_up_fee', 'none' ), + // Prorate Subscription Length 'apportion_length' => get_option( WC_Subscriptions_Admin::$option_prefix . '_apportion_length', 'none' ), + // Switch Button Text 'switch_button_text' => get_option( WC_Subscriptions_Admin::$option_prefix . '_switch_button_text', 'none' ), + // Gifting + // Enable gifting + 'gifting_enable_gifting' => get_option( WC_Subscriptions_Admin::$option_prefix . '_gifting_enable_gifting' ), + 'gifting_default_option' => get_option( WC_Subscriptions_Admin::$option_prefix . '_gifting_default_option' ), + // Gifting Checkbox Text + 'gifting_gifting_checkbox_text' => get_option( WC_Subscriptions_Admin::$option_prefix . '_gifting_gifting_checkbox_text' ), + // Downloadable Products + 'gifting_downloadable_products' => get_option( WC_Subscriptions_Admin::$option_prefix . '_gifting_downloadable_products' ), + // Synchronization + // Synchronise renewals 'sync_payments' => get_option( WC_Subscriptions_Admin::$option_prefix . '_sync_payments' ), + // Prorate First Renewal 'prorate_synced_payments' => $prorate_synced_payments = ( 'no' === get_option( WC_Subscriptions_Admin::$option_prefix . '_sync_payments' ) ? 'none' : get_option( WC_Subscriptions_Admin::$option_prefix . '_prorate_synced_payments', 'none' ) ), + // Sign-up grace period 'days_no_fee' => 'recurring' === $prorate_synced_payments ? get_option( WC_Subscriptions_Admin::$option_prefix . '_days_no_fee', 'none' ) : 'none', // Miscellaneous + // Customer Suspensions 'max_customer_suspensions' => get_option( WC_Subscriptions_Admin::$option_prefix . '_max_customer_suspensions' ), + // Mixed Checkout 'multiple_purchase' => get_option( WC_Subscriptions_Admin::$option_prefix . '_multiple_purchase' ), + // $0 Initial Checkout 'allow_zero_initial_order_without_payment_method' => get_option( WC_Subscriptions_Admin::$option_prefix . '_zero_initial_payment_requires_payment' ), + // Drip Downloadable Content 'drip_downloadable_content_on_renewal' => get_option( WC_Subscriptions_Admin::$option_prefix . '_drip_downloadable_content_on_renewal' ), + // Retry Failed Payments 'enable_retry' => get_option( WC_Subscriptions_Admin::$option_prefix . '_enable_retry' ), // Notifications - 'enable_notification_reminders' => get_option( WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$switch_setting_string, 'no' ), + // Enable Reminders + 'enable_notification_reminders' => get_option( WC_Subscriptions_Admin::$option_prefix . WC_Subscriptions_Email_Notifications::$switch_setting_string ), + // Reminder Timing + 'customer_notifications_offset_number' => $customer_notifications_offset['number'] ?? 'none', + 'customer_notifications_offset_unit' => $customer_notifications_offset['unit'] ?? 'none', ]; } @@ -119,80 +170,21 @@ class WC_Subscriptions_Tracker { * @return array Subscription order counts and totals by type (initial, switch, renewal, resubscribe). Values are returned as strings. */ private static function get_subscription_orders() { - $order_totals = []; - $relation_types = [ - 'switch', - 'renewal', - 'resubscribe', - ]; + $order_totals = array(); - // Get the subtotal and count for each subscription type. - foreach ( $relation_types as $relation_type ) { - // Get orders with the given relation type. - $relation_orders = wcs_get_orders_with_meta_query( - [ - 'type' => 'shop_order', - 'status' => [ 'wc-completed', 'wc-processing', 'wc-refunded' ], - 'limit' => -1, - 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - [ - 'key' => '_subscription_' . $relation_type, - 'compare' => 'EXISTS', - ], - ], - ] - ); + // Get the subtotal and count for all subscription types in one query + $counts_and_totals = self::get_order_count_and_total_by_meta_key(); - // Sum the totals and count the orders. - $count = count( $relation_orders ); - $total = array_reduce( - $relation_orders, - function( $total, $order ) { - return $total + $order->get_total(); - }, - 0 - ); - - $order_totals[ $relation_type . '_gross' ] = $total; - $order_totals[ $relation_type . '_count' ] = $count; + foreach ( $counts_and_totals as $type => $data ) { + $order_totals[ $type . '_gross' ] = $data['total']; + $order_totals[ $type . '_count' ] = $data['count']; } - // Finally, get the initial revenue and count. - // Get the orders for all initial subscription orders (no switch, renewal or resubscribe meta key). - $initial_subscription_orders = wcs_get_orders_with_meta_query( - [ - 'type' => 'shop_order', - 'status' => [ 'wc-completed', 'wc-processing', 'wc-refunded' ], - 'limit' => -1, - 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - [ - 'key' => '_subscription_switch', - 'compare' => 'NOT EXISTS', - ], - [ - 'key' => '_subscription_renewal', - 'compare' => 'NOT EXISTS', - ], - [ - 'key' => '_subscription_resubscribe', - 'compare' => 'NOT EXISTS', - ], - ], - ] - ); + // Get initial orders (orders without switch, renewal, or resubscribe meta keys). + $count_and_total = self::get_initial_order_count_and_total(); - // Sum the totals and count the orders. - $initial_order_count = count( $initial_subscription_orders ); - $initial_order_total = array_reduce( - $initial_subscription_orders, - function( $total, $order ) { - return $total + $order->get_total(); - }, - 0 - ); - - $order_totals['initial_gross'] = $initial_order_total; - $order_totals['initial_count'] = $initial_order_count; + $order_totals['initial_gross'] = $count_and_total['total']; + $order_totals['initial_count'] = $count_and_total['count']; // Ensure all values are strings. $order_totals = array_map( 'strval', $order_totals ); @@ -200,6 +192,149 @@ class WC_Subscriptions_Tracker { return $order_totals; } + /** + * Gets order count and total for subscription-related orders. + * + * @return array Array with counts and totals for switch, renewal, and resubscribe orders. + */ + private static function get_order_count_and_total_by_meta_key() { + global $wpdb; + + $order_statuses = array( 'wc-completed', 'wc-refunded' ); + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber + if ( wcs_is_custom_order_tables_usage_enabled() ) { + // HPOS: Use wc_orders and wc_orders_meta tables. + $orders_table = $wpdb->prefix . 'wc_orders'; + $meta_table = $wpdb->prefix . 'wc_orders_meta'; + + $query = $wpdb->prepare( + "SELECT + order_relation.meta_key as 'type', + SUM( orders.total_amount ) AS 'total', + COUNT( orders.id ) as 'count' + FROM {$orders_table} AS orders + RIGHT JOIN {$meta_table} AS order_relation ON order_relation.order_id = orders.id + WHERE order_relation.meta_key IN ( '_subscription_switch', '_subscription_renewal', '_subscription_resubscribe' ) + AND orders.status in (%s, %s) + AND orders.type = 'shop_order' + GROUP BY order_relation.meta_key", + $order_statuses + ); + } else { + // CPT: Use posts and postmeta tables. + $query = $wpdb->prepare( + "SELECT + order_relation.meta_key as 'type', + SUM( order_total.meta_value ) AS 'total', + COUNT( orders.ID ) as 'count' + FROM {$wpdb->prefix}posts AS orders + RIGHT JOIN {$wpdb->prefix}postmeta AS order_relation ON order_relation.post_id = orders.ID + RIGHT JOIN {$wpdb->prefix}postmeta AS order_total ON order_total.post_id = orders.ID + WHERE order_relation.meta_key IN ( '_subscription_switch', '_subscription_renewal', '_subscription_resubscribe' ) + AND orders.post_status in (%s, %s) + AND order_total.meta_key = '_order_total' + GROUP BY order_relation.meta_key", + $order_statuses + ); + } + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber + + $results = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + + $totals = array( + 'switch' => array( + 'count' => 0, + 'total' => 0.0, + ), + 'renewal' => array( + 'count' => 0, + 'total' => 0.0, + ), + 'resubscribe' => array( + 'count' => 0, + 'total' => 0.0, + ), + ); + + if ( $results ) { + foreach ( $results as $result ) { + $type = str_replace( '_subscription_', '', $result['type'] ); + if ( isset( $totals[ $type ] ) ) { + $totals[ $type ] = array( + 'count' => (int) $result['count'], + 'total' => (float) $result['total'], + ); + } + } + } + + // Log if any type has no data + foreach ( $totals as $type => $data ) { + if ( 0 === $data['count'] && 0.0 === $data['total'] ) { + wc_get_logger()->warning( "WC_Subscriptions_Tracker::get_order_count_and_total_by_meta_key() returned 0 count and total for {$type} orders" ); + } + } + + return $totals; + } + + /** + * Gets count and total for initial orders (orders without subscription relation meta keys). + * + * @return array Array with 'count' and 'total' keys. + */ + private static function get_initial_order_count_and_total() { + global $wpdb; + + $order_statuses = array( 'wc-completed', 'wc-refunded' ); + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber + if ( wcs_is_custom_order_tables_usage_enabled() ) { + // HPOS: Use wc_orders table + $orders_table = $wpdb->prefix . 'wc_orders'; + + $query = $wpdb->prepare( + "SELECT + SUM( orders.total_amount ) AS 'total', COUNT( DISTINCT orders.id ) as 'count' + FROM {$orders_table} AS orders + RIGHT JOIN {$orders_table} AS subscriptions ON subscriptions.parent_order_id = orders.id + WHERE orders.status in ( %s, %s ) + AND subscriptions.type = 'shop_subscription' + AND orders.type = 'shop_order'", + $order_statuses + ); + } else { + // CPT: Use posts and postmeta tables. + $query = $wpdb->prepare( + "SELECT + SUM( order_total.meta_value ) AS 'total', COUNT( * ) as 'count' + FROM {$wpdb->posts} AS orders + RIGHT JOIN {$wpdb->posts} AS subscriptions ON subscriptions.post_parent = orders.ID + RIGHT JOIN {$wpdb->postmeta} AS order_total ON order_total.post_id = orders.ID + WHERE orders.post_status in ( %s, %s ) + AND subscriptions.post_type = 'shop_subscription' + AND orders.post_type = 'shop_order' + AND order_total.meta_key = '_order_total'", + $order_statuses + ); + } + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber + + $result = $wpdb->get_row( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + + $totals = array( + 'count' => (int) ( $result ? $result['count'] : 0 ), + 'total' => (float) ( $result ? $result['total'] : 0 ), + ); + + if ( 0 === $totals['count'] && 0.0 === $totals['total'] ) { + wc_get_logger()->warning( 'WC_Subscriptions_Tracker::get_initial_order_count_and_total() returned 0 count and total' ); + } + + return $totals; + } + /** * Gets first and last subscription created dates. * diff --git a/includes/core/class-wcs-failed-scheduled-action-manager.php b/includes/core/class-wcs-failed-scheduled-action-manager.php index dac3372..f67779a 100644 --- a/includes/core/class-wcs-failed-scheduled-action-manager.php +++ b/includes/core/class-wcs-failed-scheduled-action-manager.php @@ -121,7 +121,6 @@ class WCS_Failed_Scheduled_Action_Manager { // Log any exceptions caught by the exception listener in action logs. if ( ! empty( $context['exceptions'] ) ) { foreach ( $context['exceptions'] as $exception_message ) { - // @phpstan-ignore-next-line ActionScheduler_Logger::instance()->log( $action_id, $exception_message ); } } diff --git a/includes/core/class-wcs-object-data-cache-manager.php b/includes/core/class-wcs-object-data-cache-manager.php index 84c47b8..60bfb03 100644 --- a/includes/core/class-wcs-object-data-cache-manager.php +++ b/includes/core/class-wcs-object-data-cache-manager.php @@ -92,11 +92,9 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager { } $force_all_fields = 'all_fields' === $generate_type; - // @phpstan-ignore-next-line - $changes = $subscription->get_changes(); - $base_data = $subscription->get_base_data(); - // @phpstan-ignore-next-line - $meta_data = $subscription->get_meta_data(); + $changes = $subscription->get_changes(); + $base_data = $subscription->get_base_data(); + $meta_data = $subscription->get_meta_data(); // Deleted meta won't be included in the changes, so we need to fetch the previous value via the raw meta data. $data_store = $subscription->get_data_store(); @@ -144,7 +142,6 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager { } elseif ( $meta->get_changes() ) { // If the value is being updated. $this->object_changes[ $subscription->get_id() ][ $data_key ] = [ - // @phpstan-ignore-next-line 'new' => $meta->value, 'previous' => isset( $previous_meta['value'] ) ? $previous_meta['value'] : null, 'type' => 'update', @@ -152,7 +149,6 @@ class WCS_Object_Data_Cache_Manager extends WCS_Post_Meta_Cache_Manager { } elseif ( $force_all_fields ) { // If we're forcing all fields to be recorded. $this->object_changes[ $subscription->get_id() ][ $data_key ] = [ - // @phpstan-ignore-next-line 'new' => $meta->value, 'type' => 'add', ]; diff --git a/includes/core/emails/class-wc-subscriptions-email-preview.php b/includes/core/emails/class-wc-subscriptions-email-preview.php index 0923f8c..b8c67f4 100644 --- a/includes/core/emails/class-wc-subscriptions-email-preview.php +++ b/includes/core/emails/class-wc-subscriptions-email-preview.php @@ -49,6 +49,10 @@ class WC_Subscriptions_Email_Preview { case 'WCS_Email_Customer_Notification_Auto_Renewal': $email->set_object( $this->get_dummy_subscription() ); break; + case 'WCSG_Email_Recipient_New_Initial_Order': + $email->set_object( $this->get_dummy_subscription() ); + $email->subscriptions = [ $this->get_dummy_subscription() ]; + break; case 'WCS_Email_Customer_Payment_Retry': case 'WCS_Email_Payment_Retry': $email->retry = $this->get_dummy_retry( $email->object ); @@ -191,8 +195,7 @@ class WC_Subscriptions_Email_Preview { * @return bool Whether the email being previewed is a subscription email. */ private function is_subscription_email() { - return isset( WC_Subscriptions_Email::$email_classes[ $this->email_type ] ) - || isset( WC_Subscriptions_Email_Notifications::$email_classes[ $this->email_type ] ) + return isset( apply_filters( 'wcs_email_classes', array_merge( WC_Subscriptions_Email::$email_classes, WC_Subscriptions_Email_Notifications::$email_classes ) )[ $this->email_type ] ) || in_array( $this->email_type, [ 'WCS_Email_Customer_Payment_Retry', 'WCS_Email_Payment_Retry' ], true ); } diff --git a/includes/core/emails/class-wcs-email-cancelled-subscription.php b/includes/core/emails/class-wcs-email-cancelled-subscription.php index ab7d399..56bc85c 100644 --- a/includes/core/emails/class-wcs-email-cancelled-subscription.php +++ b/includes/core/emails/class-wcs-email-cancelled-subscription.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.1 * @package WooCommerce_Subscriptions/Classes/Emails * @author Prospress - * @extends WC_Email */ class WCS_Email_Cancelled_Subscription extends WC_Email { diff --git a/includes/core/emails/class-wcs-email-completed-renewal-order.php b/includes/core/emails/class-wcs-email-completed-renewal-order.php index 5e53c06..db9b5fd 100644 --- a/includes/core/emails/class-wcs-email-completed-renewal-order.php +++ b/includes/core/emails/class-wcs-email-completed-renewal-order.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.0 * @package WooCommerce/Classes/Emails * @author Prospress - * @extends WC_Email */ class WCS_Email_Completed_Renewal_Order extends WC_Email_Customer_Completed_Order { diff --git a/includes/core/emails/class-wcs-email-completed-switch-order.php b/includes/core/emails/class-wcs-email-completed-switch-order.php index 4af213f..eb058c5 100644 --- a/includes/core/emails/class-wcs-email-completed-switch-order.php +++ b/includes/core/emails/class-wcs-email-completed-switch-order.php @@ -12,7 +12,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.0 * @package WooCommerce/Classes/Emails * @author Prospress - * @extends WC_Email */ class WCS_Email_Completed_Switch_Order extends WC_Email_Customer_Completed_Order { diff --git a/includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php b/includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php index 5377f64..7906087 100644 --- a/includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php +++ b/includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WCS_Email_Customer_Notification_Auto_Renewal * @version 1.0.0 * @package WooCommerce_Subscriptions/Classes/Emails - * @extends WC_Email */ class WCS_Email_Customer_Notification_Auto_Renewal extends WCS_Email_Customer_Notification { diff --git a/includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php b/includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php index 2128e5f..ebf3a7e 100644 --- a/includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php +++ b/includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WCS_Email_Customer_Notification_Free_Trial_Expiry * @version 1.0.0 * @package WooCommerce_Subscriptions/Classes/Emails - * @extends WC_Email */ class WCS_Email_Customer_Notification_Auto_Trial_Expiration extends WCS_Email_Customer_Notification { diff --git a/includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php b/includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php index 7bda8f0..d1160f9 100644 --- a/includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php +++ b/includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WCS_Email_Customer_Notification_Manual_Renewal * @version 1.0.0 * @package WooCommerce_Subscriptions/Classes/Emails - * @extends WC_Email */ class WCS_Email_Customer_Notification_Manual_Renewal extends WCS_Email_Customer_Notification { diff --git a/includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php b/includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php index c8d943d..6e7f8e6 100644 --- a/includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php +++ b/includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WCS_Email_Customer_Notification_Free_Trial_Expiry * @version 1.0.0 * @package WooCommerce_Subscriptions/Classes/Emails - * @extends WC_Email */ class WCS_Email_Customer_Notification_Manual_Trial_Expiration extends WCS_Email_Customer_Notification { diff --git a/includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php b/includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php index a3a9410..18bc018 100644 --- a/includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php +++ b/includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @class WCS_Email_Customer_Notification_Subscription_Expiring * @version 1.0.0 * @package WooCommerce_Subscriptions/Classes/Emails - * @extends WC_Email */ class WCS_Email_Customer_Notification_Subscription_Expiration extends WCS_Email_Customer_Notification { diff --git a/includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php b/includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php index 3a20b0e..615a166 100644 --- a/includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php +++ b/includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php @@ -10,7 +10,6 @@ defined( 'ABSPATH' ) || exit; // Exit if accessed directly. * @version 1.0.0 - Migrated from WooCommerce Subscriptions v3.0.0 * @package WooCommerce_Subscriptions/Includes/Emails * @author WooCommerce. - * @extends WC_Email_Customer_On_Hold_Order */ class WCS_Email_Customer_On_Hold_Renewal_Order extends WC_Email_Customer_On_Hold_Order { diff --git a/includes/core/emails/class-wcs-email-customer-renewal-invoice.php b/includes/core/emails/class-wcs-email-customer-renewal-invoice.php index 135e43a..4500e90 100644 --- a/includes/core/emails/class-wcs-email-customer-renewal-invoice.php +++ b/includes/core/emails/class-wcs-email-customer-renewal-invoice.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.4 * @package WooCommerce_Subscriptions/Includes/Emails * @author Prospress - * @extends WC_Email_Customer_Invoice */ class WCS_Email_Customer_Renewal_Invoice extends WC_Email_Customer_Invoice { diff --git a/includes/core/emails/class-wcs-email-expired-subscription.php b/includes/core/emails/class-wcs-email-expired-subscription.php index a805cea..8521e25 100644 --- a/includes/core/emails/class-wcs-email-expired-subscription.php +++ b/includes/core/emails/class-wcs-email-expired-subscription.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.1 * @package WooCommerce_Subscriptions/Classes/Emails * @author Prospress - * @extends WC_Email */ class WCS_Email_Expired_Subscription extends WC_Email { diff --git a/includes/core/emails/class-wcs-email-new-renewal-order.php b/includes/core/emails/class-wcs-email-new-renewal-order.php index e94a347..282f013 100644 --- a/includes/core/emails/class-wcs-email-new-renewal-order.php +++ b/includes/core/emails/class-wcs-email-new-renewal-order.php @@ -9,7 +9,6 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WCS_Email_New_Renewal_Order * @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.4 - * @extends WC_Email_New_Order */ class WCS_Email_New_Renewal_Order extends WC_Email_New_Order { diff --git a/includes/core/emails/class-wcs-email-new-switch-order.php b/includes/core/emails/class-wcs-email-new-switch-order.php index a70e867..195f862 100644 --- a/includes/core/emails/class-wcs-email-new-switch-order.php +++ b/includes/core/emails/class-wcs-email-new-switch-order.php @@ -9,7 +9,6 @@ if ( ! defined( 'ABSPATH' ) ) { * * @class WCS_Email_New_Switch_Order * @version 1.0.0 - Migrated from WooCommerce Subscriptions v1.5 - * @extends WC_Email_New_Order */ class WCS_Email_New_Switch_Order extends WC_Email_New_Order { diff --git a/includes/core/emails/class-wcs-email-on-hold-subscription.php b/includes/core/emails/class-wcs-email-on-hold-subscription.php index e242992..a06723a 100644 --- a/includes/core/emails/class-wcs-email-on-hold-subscription.php +++ b/includes/core/emails/class-wcs-email-on-hold-subscription.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.1 * @package WooCommerce_Subscriptions/Classes/Emails * @author Prospress - * @extends WC_Email */ class WCS_Email_On_Hold_Subscription extends WC_Email { diff --git a/includes/core/emails/class-wcs-email-processing-renewal-order.php b/includes/core/emails/class-wcs-email-processing-renewal-order.php index ff3f9c9..5690cb6 100644 --- a/includes/core/emails/class-wcs-email-processing-renewal-order.php +++ b/includes/core/emails/class-wcs-email-processing-renewal-order.php @@ -11,7 +11,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.0.0 * @package WooCommerce/Classes/Emails * @author Prospress - * @extends WC_Email */ class WCS_Email_Processing_Renewal_Order extends WC_Email_Customer_Processing_Order { diff --git a/includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php b/includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php index f4ef0c7..2b4f6fd 100644 --- a/includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php +++ b/includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php @@ -299,7 +299,7 @@ abstract class WCS_SV_API_Base { * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v4.1.0 * @param string $uri current request URI - * @param \WCS_SV_API_Base $this class instance + * @param \WCS_SV_API_Base $instance class instance */ return apply_filters( 'wc_' . $this->get_api_id() . '_api_request_uri', $uri, $this ); } @@ -335,7 +335,7 @@ abstract class WCS_SV_API_Base { * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.2.0 * @param array $args request arguments - * @param \WCS_SV_API_Base $this class instance + * @param \WCS_SV_API_Base $instance class instance */ return apply_filters( 'wc_' . $this->get_api_id() . '_http_request_args', $args, $this ); } diff --git a/includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php b/includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php index 74a4fe8..3f00b4b 100644 --- a/includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php +++ b/includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php @@ -590,7 +590,7 @@ class WCS_PayPal_Reference_Transaction_API_Request { * Use this to modify the PayPal request parameters prior to validation * * @param array $parameters - * @param \WC_PayPal_Express_API_Request $this instance + * @param \WC_PayPal_Reference_Transaction_API_Request $instance instance */ $this->parameters = apply_filters( 'wcs_paypal_request_params', $this->parameters, $this ); diff --git a/includes/core/upgrades/class-wcs-repair-suspended-paypal-subscriptions.php b/includes/core/upgrades/class-wcs-repair-suspended-paypal-subscriptions.php index 0d213e6..749851e 100644 --- a/includes/core/upgrades/class-wcs-repair-suspended-paypal-subscriptions.php +++ b/includes/core/upgrades/class-wcs-repair-suspended-paypal-subscriptions.php @@ -43,6 +43,8 @@ class WCS_Repair_Suspended_PayPal_Subscriptions extends WCS_Background_Upgrader * @param int $subscription_id The ID of a shop_subscription/WC_Subscription object. */ protected function update_item( $subscription_id ) { + $subscription = null; + try { $subscription = wcs_get_subscription( $subscription_id ); diff --git a/includes/core/upgrades/class-wcs-upgrade-2-0.php b/includes/core/upgrades/class-wcs-upgrade-2-0.php index 034e2ae..cd21bf8 100644 --- a/includes/core/upgrades/class-wcs-upgrade-2-0.php +++ b/includes/core/upgrades/class-wcs-upgrade-2-0.php @@ -884,7 +884,6 @@ class WCS_Upgrade_2_0 { * @param WC_Subscription $new_subscription A subscription object * @param WC_Order $switch_order The original order used to purchase the subscription * @param int $subscription_item_id The order item ID of the item added to the subscription by self::add_product() - * @return null * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0 */ private static function migrate_switch_meta( $new_subscription, $switch_order, $subscription_item_id ) { diff --git a/includes/core/wcs-cart-functions.php b/includes/core/wcs-cart-functions.php index 22e23f7..d543b68 100644 --- a/includes/core/wcs-cart-functions.php +++ b/includes/core/wcs-cart-functions.php @@ -79,11 +79,12 @@ function wcs_cart_totals_shipping_html() { $chosen_recurring_method = empty( $package['rates'] ) ? '' : current( $package['rates'] )->id; } + $is_package_found = isset( $package['rates'][ $chosen_initial_method ] ) && isset( $initial_packages[ $package_index ] ); $shipping_selection_displayed = false; $only_one_shipping_option = count( $package['rates'] ) === 1; - $recurring_rates_match_initial_rates = isset( $package['rates'][ $chosen_initial_method ] ) && isset( $initial_packages[ $package_index ] ) && $package['rates'] == $initial_packages[ $package_index ]['rates']; // phpcs:ignore WordPress.PHP.StrictComparisons + $recurring_rates_match_initial_rates = WC_Subscriptions_Cart::package_rates_match_initial_rates( $initial_packages, $package, $recurring_cart_package_key, $recurring_cart ); - if ( $only_one_shipping_option || ( $recurring_rates_match_initial_rates && apply_filters( 'wcs_cart_totals_shipping_html_price_only', true, $package, $recurring_cart ) ) ) { + if ( $only_one_shipping_option || ( $is_package_found && $recurring_rates_match_initial_rates ) ) { $shipping_method = ( 1 === count( $package['rates'] ) ) ? current( $package['rates'] ) : $package['rates'][ $chosen_initial_method ]; // packages match, display shipping amounts only ?> diff --git a/includes/core/wcs-product-functions.php b/includes/core/wcs-product-functions.php index daa5976..48c7b8e 100644 --- a/includes/core/wcs-product-functions.php +++ b/includes/core/wcs-product-functions.php @@ -500,3 +500,32 @@ function wcs_get_subscription_grouping_key( $product, $renewal_time = 0 ) { return apply_filters( 'wcs_subscription_product_grouping_key', $key, $product, $renewal_time ); } + +/** + * Get the reactivate link for a subscription product if the user already has a + * pending cancellation subscription. + * + * @param int $user_id The user ID + * @param WC_Product $product The product + * @return string The reactivate link + */ +function wcs_get_user_reactivate_link_for_product( int $user_id, WC_Product $product ): string { + $reactivate_link = ''; + + $user_subscriptions = wcs_get_subscriptions( + [ + 'customer_id' => $user_id, + 'product_id' => $product->get_id(), + 'status' => 'pending-cancel', + ] + ); + + foreach ( $user_subscriptions as $subscription ) { + if ( $subscription->can_be_updated_to( 'active' ) && ! $subscription->needs_payment() ) { + $reactivate_link = wcs_get_users_change_status_link( $subscription->get_id(), 'active', $subscription->get_status() ); + break; + } + } + + return $reactivate_link; +} diff --git a/includes/core/wcs-time-functions.php b/includes/core/wcs-time-functions.php index 0bd607f..3ab51e3 100644 --- a/includes/core/wcs-time-functions.php +++ b/includes/core/wcs-time-functions.php @@ -336,7 +336,6 @@ function wcs_estimate_periods_between( $start_timestamp, $end_timestamp, $unit_o break; } - // @phpstan-ignore-next-line $periods_until = ( 'ceil' == $rounding_method ) ? ceil( $seconds_until_timestamp / $denominator ) : floor( $seconds_until_timestamp / $denominator ); } diff --git a/includes/core/wcs-user-functions.php b/includes/core/wcs-user-functions.php index 38f550e..64797ce 100644 --- a/includes/core/wcs-user-functions.php +++ b/includes/core/wcs-user-functions.php @@ -359,7 +359,7 @@ function wcs_user_has_capability( $allcaps, $caps, $args ) { $user_id = $args[1]; $subscription = wcs_get_subscription( $args[2] ); - if ( $user_id === $subscription->get_user_id() ) { + if ( $subscription && $user_id === $subscription->get_user_id() ) { $allcaps['edit_shop_subscription_status'] = true; } break; @@ -367,7 +367,7 @@ function wcs_user_has_capability( $allcaps, $caps, $args ) { $user_id = $args[1]; $subscription = wcs_get_subscription( $args[2] ); - if ( $user_id === $subscription->get_user_id() ) { + if ( $subscription && $user_id === $subscription->get_user_id() ) { $allcaps['edit_shop_subscription_line_items'] = true; } break; @@ -375,7 +375,7 @@ function wcs_user_has_capability( $allcaps, $caps, $args ) { $user_id = $args[1]; $subscription = wcs_get_subscription( $args[2] ); - if ( $user_id === $subscription->get_user_id() ) { + if ( $subscription && $user_id === $subscription->get_user_id() ) { $allcaps['switch_shop_subscription'] = true; } break; @@ -383,7 +383,7 @@ function wcs_user_has_capability( $allcaps, $caps, $args ) { $user_id = $args[1]; $subscription = wcs_get_subscription( $args[2] ); - if ( $user_id === $subscription->get_user_id() ) { + if ( $subscription && $user_id === $subscription->get_user_id() ) { $allcaps['subscribe_again'] = true; } break; diff --git a/includes/gifting/class-wcs-gifting.php b/includes/gifting/class-wcs-gifting.php index 6af06c0..25c4018 100644 --- a/includes/gifting/class-wcs-gifting.php +++ b/includes/gifting/class-wcs-gifting.php @@ -803,31 +803,12 @@ class WCS_Gifting { * @since 7.8.0 - Originally implemented in WooCommerce Subscriptions Gifting 2.1.0. */ public static function get_gifted_subscriptions_count() { - global $wpdb; - - if ( function_exists( 'wcs_is_custom_order_tables_usage_enabled' ) && wcs_is_custom_order_tables_usage_enabled() ) { - $count = $wpdb->get_var( - " - SELECT COUNT(DISTINCT o.id) FROM {$wpdb->prefix}wc_orders o - INNER JOIN {$wpdb->prefix}wc_orders_meta om ON (o.id = om.order_id) - WHERE o.type = 'shop_subscription' - AND o.status NOT IN ( 'auto-draft', 'trash' ) - AND om.meta_key = '_recipient_user' - " - ); - } else { - $count = $wpdb->get_var( - " - SELECT COUNT(DISTINCT p.ID) FROM {$wpdb->posts} p - INNER JOIN {$wpdb->postmeta} pm ON (p.ID = pm.post_id) - WHERE p.post_type = 'shop_subscription' - AND p.post_status NOT IN ( 'auto-draft', 'trash' ) - AND pm.meta_key = '_recipient_user' - " - ); + if ( ! class_exists( \Automattic\WooCommerce_Subscriptions\Internal\Telemetry\Subscriptions::class ) ) { + return 0; } - return absint( $count ); + $telemetry = new \Automattic\WooCommerce_Subscriptions\Internal\Telemetry\Subscriptions(); + return $telemetry->get_gifted_subscriptions_count(); } /** diff --git a/includes/gifting/class-wcsg-email.php b/includes/gifting/class-wcsg-email.php index 24eee42..8c88179 100644 --- a/includes/gifting/class-wcsg-email.php +++ b/includes/gifting/class-wcsg-email.php @@ -54,6 +54,7 @@ class WCSG_Email { */ public static function init() { add_filter( 'woocommerce_email_classes', __CLASS__ . '::add_new_recipient_customer_email', 11, 1 ); + add_filter( 'wcs_email_classes', __CLASS__ . '::add_new_recipient_customer_email', 11, 1 ); add_action( 'woocommerce_init', __CLASS__ . '::hook_email' ); add_action( 'wcs_gifting_email_order_details', array( __CLASS__, 'order_details' ), 10, 4 ); add_action( 'woocommerce_subscriptions_gifting_recipient_email_details', array( __CLASS__, 'get_related_subscriptions_table' ), 10, 3 ); @@ -66,12 +67,6 @@ class WCSG_Email { * @param WC_Email[] $email_classes E-mail classes. */ public static function add_new_recipient_customer_email( $email_classes ) { - - require_once 'emails/class-wcsg-email-customer-new-account.php'; - require_once 'emails/class-wcsg-email-completed-renewal-order.php'; - require_once 'emails/class-wcsg-email-processing-renewal-order.php'; - require_once 'emails/class-wcsg-email-recipient-new-initial-order.php'; - $email_classes['WCSG_Email_Customer_New_Account'] = new WCSG_Email_Customer_New_Account(); $email_classes['WCSG_Email_Completed_Renewal_Order'] = new WCSG_Email_Completed_Renewal_Order(); $email_classes['WCSG_Email_Processing_Renewal_Order'] = new WCSG_Email_Processing_Renewal_Order(); diff --git a/includes/gifting/emails/class-wcsg-email-customer-new-account.php b/includes/gifting/emails/class-wcsg-email-customer-new-account.php index e14b98b..4758f57 100644 --- a/includes/gifting/emails/class-wcsg-email-customer-new-account.php +++ b/includes/gifting/emails/class-wcsg-email-customer-new-account.php @@ -100,6 +100,11 @@ class WCSG_Email_Customer_New_Account extends WC_Email { * Returns content for the HTML version of the e-mail. */ public function get_content_html() { + // Handle the email preview. + if ( empty( $this->subscription_owner ) ) { + $this->set_preview_data(); + } + ob_start(); wc_get_template( $this->template_html, @@ -125,6 +130,11 @@ class WCSG_Email_Customer_New_Account extends WC_Email { * Returns content for the plain text version of the e-mail. */ public function get_content_plain() { + // Handle the email preview. + if ( empty( $this->subscription_owner ) ) { + $this->set_preview_data(); + } + ob_start(); wc_get_template( $this->template_plain, @@ -145,4 +155,11 @@ class WCSG_Email_Customer_New_Account extends WC_Email { ); return ob_get_clean(); } + + /** + * Set WooCommerce email preview data. + */ + public function set_preview_data() { + $this->subscription_owner = $this->object->get_billing_first_name() . ' ' . $this->object->get_billing_last_name(); + } } diff --git a/includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php b/includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php index bab32db..165731e 100644 --- a/includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php +++ b/includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php @@ -35,6 +35,13 @@ class WCSG_Email_Recipient_New_Initial_Order extends WC_Email { */ public $wcsg_sending_recipient_email; + /** + * Recipient user. + * + * @var WP_User + */ + public $recipient_user; + /** * Create an instance of the class. */ @@ -65,8 +72,8 @@ class WCSG_Email_Recipient_New_Initial_Order extends WC_Email { public function trigger( $recipient_user, $recipient_subscriptions ) { if ( $recipient_user ) { - $this->object = get_user_by( 'id', $recipient_user ); - $this->recipient = stripslashes( $this->object->user_email ); + $this->recipient_user = get_user_by( 'id', $recipient_user ); + $this->recipient = stripslashes( $this->recipient_user->user_email ); $subscription = wcs_get_subscription( $recipient_subscriptions[0] ); $this->subscription_owner = WCS_Gifting::get_user_display_name( $subscription->get_user_id() ); $this->subscriptions = $recipient_subscriptions; @@ -86,13 +93,18 @@ class WCSG_Email_Recipient_New_Initial_Order extends WC_Email { * Returns the content for the HTML version of the e-mail. */ public function get_content_html() { + // Handle the email preview. + if ( empty( $this->subscription_owner ) ) { + $this->set_preview_data(); + } + ob_start(); wc_get_template( $this->template_html, array( 'email_heading' => $this->get_heading(), 'blogname' => $this->get_blogname(), - 'recipient_user' => $this->object, + 'recipient_user' => $this->recipient_user, 'subscription_purchaser' => $this->subscription_owner, 'subscriptions' => $this->subscriptions, 'sent_to_admin' => false, @@ -110,6 +122,11 @@ class WCSG_Email_Recipient_New_Initial_Order extends WC_Email { * Returns the content for the plain text version of the e-mail. */ public function get_content_plain() { + // Handle the email preview. + if ( empty( $this->subscription_owner ) ) { + $this->set_preview_data(); + } + ob_start(); wc_get_template( $this->template_plain, @@ -127,7 +144,14 @@ class WCSG_Email_Recipient_New_Initial_Order extends WC_Email { '', $this->template_base ); - return ob_get_clean(); + return ob_get_clean(); + } + + /** + * Set WooCommerce email preview data. + */ + public function set_preview_data() { + $this->subscription_owner = WCS_Gifting::get_user_display_name( $this->subscriptions[0]->get_user_id() ); } } diff --git a/languages/woocommerce-subscriptions.pot b/languages/woocommerce-subscriptions.pot index aab2900..459bcaa 100644 --- a/languages/woocommerce-subscriptions.pot +++ b/languages/woocommerce-subscriptions.pot @@ -2,14 +2,14 @@ # This file is distributed under the GNU General Public License v3.0. msgid "" msgstr "" -"Project-Id-Version: WooCommerce Subscriptions 7.9.0\n" +"Project-Id-Version: WooCommerce Subscriptions 8.0.0\n" "Report-Msgid-Bugs-To: https://woocommerce.com/contact-us\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2025-09-16T18:10:01+00:00\n" +"POT-Creation-Date: 2025-10-15T04:57:29+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.12.0\n" "X-Domain: woocommerce-subscriptions\n" @@ -790,8 +790,8 @@ msgstr "" #: includes/api/legacy/class-wc-rest-subscriptions-controller.php:349 #: includes/api/v1/class-wc-rest-subscriptions-v1-controller.php:504 #: includes/api/v2/class-wc-rest-subscriptions-v2-controller.php:396 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:186 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:460 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:188 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:510 msgid "The number of billing periods between subscription renewals." msgstr "" @@ -799,8 +799,8 @@ msgstr "" #: includes/api/legacy/class-wc-rest-subscriptions-controller.php:354 #: includes/api/v1/class-wc-rest-subscriptions-v1-controller.php:509 #: includes/api/v2/class-wc-rest-subscriptions-v2-controller.php:401 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:179 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:453 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:181 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:503 msgid "Billing period for the subscription." msgstr "" @@ -979,7 +979,7 @@ msgstr "" #: includes/api/legacy/class-wc-rest-subscriptions-controller.php:382 #: includes/api/v1/class-wc-rest-subscriptions-v1-controller.php:537 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:447 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:497 msgid "The subscription's next payment date." msgstr "" @@ -1113,26 +1113,26 @@ msgid "%1$sWooCommerce Subscriptions is inactive.%2$s This version of Subscripti msgstr "" #. translators: 1-2: opening/closing tags, 3: Subscriptions version. -#: includes/class-wc-subscriptions-plugin.php:63 +#: includes/class-wc-subscriptions-plugin.php:68 #, php-format msgid "%1$sWarning!%2$s We can see the %1$sWooCommerce Subscriptions Early Renewal%2$s plugin is active. Version %3$s of %1$sWooCommerce Subscriptions%2$s comes with that plugin's functionality packaged into the core plugin. Please deactivate WooCommerce Subscriptions Early Renewal to avoid any conflicts." msgstr "" -#: includes/class-wc-subscriptions-plugin.php:67 +#: includes/class-wc-subscriptions-plugin.php:72 msgid "Installed Plugins" msgstr "" #. translators: $1-$2: opening and closing tags, $3-$4: opening and closing tags. -#: includes/class-wc-subscriptions-plugin.php:209 +#: includes/class-wc-subscriptions-plugin.php:214 #, php-format msgid "%1$sWooCommerce Subscriptions Installed%2$s – %3$sYou're ready to start selling subscriptions!%4$s" msgstr "" -#: includes/class-wc-subscriptions-plugin.php:227 +#: includes/class-wc-subscriptions-plugin.php:232 msgid "Add a Subscription Product" msgstr "" -#: includes/class-wc-subscriptions-plugin.php:228 +#: includes/class-wc-subscriptions-plugin.php:233 #: includes/core/class-wc-subscriptions-core-plugin.php:577 #: includes/core/upgrades/templates/wcs-about-2-0.php:35 #: includes/core/upgrades/templates/wcs-about.php:34 @@ -1342,7 +1342,7 @@ msgid "Welcome to WooCommerce Subscriptions %s!" msgstr "" #: includes/class-wcs-upgrade-notice-manager.php:112 -#: includes/core/class-wcs-failed-scheduled-action-manager.php:233 +#: includes/core/class-wcs-failed-scheduled-action-manager.php:232 msgid "Learn more" msgstr "" @@ -1458,7 +1458,7 @@ msgid "Optionally include an amount to be charged at the outset of the subscript msgstr "" #: includes/core/admin/class-wc-subscriptions-admin.php:375 -#: includes/core/class-wc-subscriptions-cart.php:2427 +#: includes/core/class-wc-subscriptions-cart.php:2458 #: templates/admin/html-variation-price.php:79 msgid "Free trial" msgstr "" @@ -1968,10 +1968,10 @@ msgid "Items" msgstr "" #: includes/core/admin/class-wcs-admin-post-types.php:469 -#: build/index.js:15 -#: build/index.js:18 -#: client/core/recurring-totals/index.js:196 -#: client/core/recurring-totals/index.js:295 +#: build/index.js:16 +#: build/index.js:19 +#: client/core/recurring-totals/index.js:285 +#: client/core/recurring-totals/index.js:396 msgid "Total" msgstr "" @@ -2142,6 +2142,8 @@ msgstr "" #: includes/core/admin/class-wcs-admin-post-types.php:1385 #: includes/core/wcs-user-functions.php:311 #: includes/gifting/class-wcsg-recipient-management.php:154 +#: templates/single-product/add-to-cart/subscription.php:39 +#: templates/single-product/add-to-cart/variable-subscription.php:38 msgid "Reactivate" msgstr "" @@ -2480,9 +2482,9 @@ msgid "Customer add payment method page →" msgstr "" #: includes/core/admin/meta-boxes/class-wcs-meta-box-subscription-data.php:256 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:298 -#: build/index.js:10 -#: client/core/recurring-totals/index.js:108 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:300 +#: build/index.js:11 +#: client/core/recurring-totals/index.js:177 msgid "Shipping" msgstr "" @@ -2826,7 +2828,7 @@ msgid "That product can not be added to your cart as it already contains a subsc msgstr "" #: includes/core/class-wc-subscriptions-cart-validator.php:195 -#: includes/core/class-wc-subscriptions-cart.php:1473 +#: includes/core/class-wc-subscriptions-cart.php:1504 msgid "That subscription product can not be added to your cart as it already contains a subscription renewal." msgstr "" @@ -2834,16 +2836,16 @@ msgstr "" msgid "Initial Shipment" msgstr "" -#: includes/core/class-wc-subscriptions-cart.php:1110 +#: includes/core/class-wc-subscriptions-cart.php:1100 msgid "Invalid recurring shipping method." msgstr "" -#: includes/core/class-wc-subscriptions-cart.php:2158 +#: includes/core/class-wc-subscriptions-cart.php:2189 msgid "now" msgstr "" #. translators: placeholder is a number of days. -#: includes/core/class-wc-subscriptions-cart.php:2320 +#: includes/core/class-wc-subscriptions-cart.php:2351 #: includes/core/wcs-time-functions.php:58 #, php-format msgid "%s day" @@ -2852,7 +2854,7 @@ msgstr[0] "" msgstr[1] "" #. translators: placeholder is a number of weeks. -#: includes/core/class-wc-subscriptions-cart.php:2324 +#: includes/core/class-wc-subscriptions-cart.php:2355 #: includes/core/wcs-time-functions.php:60 #, php-format msgid "%s week" @@ -2861,7 +2863,7 @@ msgstr[0] "" msgstr[1] "" #. translators: placeholder is a number of months. -#: includes/core/class-wc-subscriptions-cart.php:2328 +#: includes/core/class-wc-subscriptions-cart.php:2359 #: includes/core/wcs-time-functions.php:62 #, php-format msgid "%s month" @@ -2870,7 +2872,7 @@ msgstr[0] "" msgstr[1] "" #. translators: placeholder is a number of years. -#: includes/core/class-wc-subscriptions-cart.php:2332 +#: includes/core/class-wc-subscriptions-cart.php:2363 #: includes/core/wcs-time-functions.php:64 #, php-format msgid "%s year" @@ -2879,56 +2881,56 @@ msgstr[0] "" msgstr[1] "" #. translators: 1$: day of the week (e.g. "every Wednesday"). -#: includes/core/class-wc-subscriptions-cart.php:2354 +#: includes/core/class-wc-subscriptions-cart.php:2385 #, php-format msgid "every %1$s" msgstr "" #. translators: 1$: period, 2$: day of the week (e.g. "every 2nd week on Wednesday"). -#: includes/core/class-wc-subscriptions-cart.php:2358 +#: includes/core/class-wc-subscriptions-cart.php:2389 #, php-format msgid "every %1$s on %2$s" msgstr "" -#: includes/core/class-wc-subscriptions-cart.php:2367 +#: includes/core/class-wc-subscriptions-cart.php:2398 msgid "on the last day of each month" msgstr "" #. translators: 1$: day of the month (e.g. "23rd") (e.g. "every 23rd of each month"). -#: includes/core/class-wc-subscriptions-cart.php:2371 +#: includes/core/class-wc-subscriptions-cart.php:2402 #, php-format msgid "on the %1$s of each month" msgstr "" #. translators: 1$: interval (e.g. "3rd") (e.g. "on the last day of every 3rd month"). -#: includes/core/class-wc-subscriptions-cart.php:2379 +#: includes/core/class-wc-subscriptions-cart.php:2410 #, php-format msgid "on the last day of every %1$s month" msgstr "" #. translators: on the, 1$: day of every, 2$: month (e.g. "on the 23rd day of every 2nd month"). -#: includes/core/class-wc-subscriptions-cart.php:2385 +#: includes/core/class-wc-subscriptions-cart.php:2416 #, php-format msgid "on the %1$s day of every %2$s month" msgstr "" #. translators: on, 1$: , 2$: each year (e.g. "on March 15th each year"). -#: includes/core/class-wc-subscriptions-cart.php:2396 +#: includes/core/class-wc-subscriptions-cart.php:2427 #, php-format msgid "on %1$s %2$s each year" msgstr "" #. translators: 1$: month (e.g. "March"), 2$: day of the month (e.g. "23rd), 3$: interval year (r.g March 23rd every 2nd year"). -#: includes/core/class-wc-subscriptions-cart.php:2403 +#: includes/core/class-wc-subscriptions-cart.php:2434 #, php-format msgid "on %1$s %2$s every %3$s year" msgstr "" -#: includes/core/class-wc-subscriptions-cart.php:2437 +#: includes/core/class-wc-subscriptions-cart.php:2468 msgid "Sign up fee" msgstr "" -#: includes/core/class-wc-subscriptions-cart.php:2447 +#: includes/core/class-wc-subscriptions-cart.php:2478 msgid "Renews" msgstr "" @@ -3237,8 +3239,8 @@ msgid "Renewal Discount" msgstr "" #: includes/core/class-wc-subscriptions-coupon.php:700 -#: build/index.js:10 -#: client/core/recurring-totals/index.js:62 +#: build/index.js:11 +#: client/core/recurring-totals/index.js:72 msgid "Discount" msgstr "" @@ -3287,48 +3289,48 @@ msgstr "" msgid "N/A" msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:192 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:194 msgid "Subscription Product length." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:198 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:200 msgid "Subscription Product trial period." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:205 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:207 msgid "Subscription Product trial interval." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:211 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:213 msgid "Subscription Product signup fees." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:217 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:219 msgid "Subscription Product signup fees taxes." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:223 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:225 msgid "Indicates whether this product is being used to resubscribe the customer to an existing, expired subscription." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:232 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:234 msgid "Indicates whether this product a subscription update, downgrade, cross grade or none of the above." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:241 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:243 msgid "Synchronization data for the subscription." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:245 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:247 msgid "Synchronization day if subscription is annual." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:249 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:251 msgid "Synchronization month if subscription is annual." msgstr "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:304 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:306 #, php-format msgid "Shipment every %d year" msgid_plural "Shipment every %d years" @@ -3336,12 +3338,12 @@ msgstr[0] "" msgstr[1] "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:304 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:306 msgid "Yearly Shipment" msgstr "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:308 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:310 #, php-format msgid "Shipment every %d month" msgid_plural "Shipment every %d months" @@ -3349,12 +3351,12 @@ msgstr[0] "" msgstr[1] "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:308 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:310 msgid "Monthly Shipment" msgstr "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:312 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:314 #, php-format msgid "Shipment every %d week" msgid_plural "Shipment every %d weeks" @@ -3362,12 +3364,12 @@ msgstr[0] "" msgstr[1] "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:312 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:314 msgid "Weekly Shipment" msgstr "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:316 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:318 #, php-format msgid "Shipment every %d day" msgid_plural "Shipment every %d days" @@ -3375,96 +3377,96 @@ msgstr[0] "" msgstr[1] "" #. translators: %d subscription interval. -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:316 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:318 msgid "Daily Shipment" msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:441 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:491 msgid "Subscription key" msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:466 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:516 msgid "Subscription length." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:472 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:522 msgid "Cart total amounts provided using the smallest unit of the currency." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:478 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:528 msgid "Total price of items in the cart." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:484 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:534 msgid "Total tax on items in the cart." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:490 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:540 msgid "Total price of any applied fees." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:496 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:546 msgid "Total tax on fees." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:502 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:552 msgid "Total discount from applied coupons." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:508 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:558 msgid "Total tax removed due to discount from applied coupons." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:514 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:564 msgid "Total price of shipping. If shipping has not been calculated, a null response will be sent." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:520 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:570 msgid "Total tax on shipping. If shipping has not been calculated, a null response will be sent." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:526 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:576 msgid "Total price the customer will pay." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:532 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:582 msgid "Total tax applied to items and shipping." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:538 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:588 msgid "Lines of taxes applied to items and shipping." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:546 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:596 msgid "The name of the tax." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:552 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:602 msgid "The amount of tax charged." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:561 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:611 msgid "Currency code (in ISO format) for returned prices." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:567 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:617 msgid "Currency symbol for the currency which can be used to format returned prices." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:573 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:623 msgid "Currency minor unit (number of digits after the decimal separator) for returned prices." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:579 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:629 msgid "Decimal separator for the currency which can be used to format returned prices." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:585 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:635 msgid "Thousand separator for the currency which can be used to format returned prices." msgstr "" -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:591 -#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:597 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:641 +#: includes/core/class-wc-subscriptions-extend-store-endpoint.php:647 msgid "Price prefix for the currency which can be used to format returned prices." msgstr "" @@ -3678,49 +3680,49 @@ msgstr "" msgid "Subscription cancelled for refunded order %1$s#%2$s%3$s." msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2595 +#: includes/core/class-wc-subscriptions-order.php:2594 msgctxt "An order type" msgid "Original" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2596 +#: includes/core/class-wc-subscriptions-order.php:2595 msgctxt "An order type" msgid "Subscription Parent" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2597 +#: includes/core/class-wc-subscriptions-order.php:2596 msgctxt "An order type" msgid "Subscription Renewal" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2598 +#: includes/core/class-wc-subscriptions-order.php:2597 msgctxt "An order type" msgid "Subscription Resubscribe" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2599 +#: includes/core/class-wc-subscriptions-order.php:2598 msgctxt "An order type" msgid "Subscription Switch" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2600 +#: includes/core/class-wc-subscriptions-order.php:2599 msgctxt "An order type" msgid "Non-subscription" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2609 +#: includes/core/class-wc-subscriptions-order.php:2608 msgid "All orders types" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2642 +#: includes/core/class-wc-subscriptions-order.php:2641 msgid "Renewal Order" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2644 +#: includes/core/class-wc-subscriptions-order.php:2643 msgid "Resubscribe Order" msgstr "" -#: includes/core/class-wc-subscriptions-order.php:2646 +#: includes/core/class-wc-subscriptions-order.php:2645 msgid "Parent Order" msgstr "" @@ -4080,7 +4082,7 @@ msgstr "" msgid "Admin turned on automatic renewals by changing payment method to \"%s\" via the Edit Subscription screen." msgstr "" -#: includes/core/class-wcs-failed-scheduled-action-manager.php:228 +#: includes/core/class-wcs-failed-scheduled-action-manager.php:227 msgid "Ignore this error" msgstr "" @@ -4431,266 +4433,266 @@ msgstr "" msgid "Please upgrade the WooCommerce Subscriptions plugin to version 2.0 or newer immediately. If you need assistance, after upgrading to Subscriptions v2.0, please %1$sopen a support ticket%2$s." msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:26 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:25 msgid "Cancelled Subscription" msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:27 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:26 msgid "Cancelled Subscription emails are sent when a customer's subscription is cancelled (either by a store manager, or the customer)." msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:29 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:28 msgid "Subscription Cancelled" msgstr "" #. translators: placeholder is {site_title}, a variable that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:31 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:30 #, php-format msgctxt "default email subject for cancelled emails sent to the admin" msgid "[%s] Subscription Cancelled" msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:58 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:57 msgid "Always Send" msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:60 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:59 msgid "Send this email whenever a subscription is updated to \"Pending Cancellation\" or \"Cancelled\"." msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:168 -#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:210 -#: includes/core/emails/class-wcs-email-expired-subscription.php:141 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:140 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:167 +#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:209 +#: includes/core/emails/class-wcs-email-expired-subscription.php:140 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:139 msgctxt "an email notification" msgid "Enable/Disable" msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:170 -#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:212 -#: includes/core/emails/class-wcs-email-expired-subscription.php:143 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:142 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:169 +#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:211 +#: includes/core/emails/class-wcs-email-expired-subscription.php:142 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:141 msgid "Enable this email notification" msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:174 -#: includes/core/emails/class-wcs-email-expired-subscription.php:147 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:146 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:173 +#: includes/core/emails/class-wcs-email-expired-subscription.php:146 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:145 msgctxt "of an email" msgid "Recipient(s)" msgstr "" #. translators: placeholder is admin email -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:177 -#: includes/core/emails/class-wcs-email-expired-subscription.php:150 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:149 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:176 +#: includes/core/emails/class-wcs-email-expired-subscription.php:149 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:148 #, php-format msgid "Enter recipients (comma separated) for this email. Defaults to %s." msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:182 -#: includes/core/emails/class-wcs-email-expired-subscription.php:155 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:154 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:181 +#: includes/core/emails/class-wcs-email-expired-subscription.php:154 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:153 msgctxt "of an email" msgid "Subject" msgstr "" #. translators: %s: default e-mail subject. -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:185 -#: includes/core/emails/class-wcs-email-expired-subscription.php:158 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:157 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:184 +#: includes/core/emails/class-wcs-email-expired-subscription.php:157 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:156 #, php-format msgid "This controls the email subject line. Leave blank to use the default subject: %s." msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:190 -#: includes/core/emails/class-wcs-email-expired-subscription.php:163 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:162 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:189 +#: includes/core/emails/class-wcs-email-expired-subscription.php:162 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:161 msgctxt "Name the setting that controls the main heading contained within the email notification" msgid "Email Heading" msgstr "" #. translators: %s: default e-mail heading. -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:193 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:192 #, php-format msgid "This controls the main heading contained within the email notification. Leave blank to use the default heading: %s." msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:198 -#: includes/core/emails/class-wcs-email-expired-subscription.php:171 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:170 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:197 +#: includes/core/emails/class-wcs-email-expired-subscription.php:170 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:169 msgctxt "text, html or multipart" msgid "Email type" msgstr "" -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:200 +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:199 #: includes/core/emails/class-wcs-email-customer-notification.php:68 -#: includes/core/emails/class-wcs-email-expired-subscription.php:173 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:172 +#: includes/core/emails/class-wcs-email-expired-subscription.php:172 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:171 msgid "Choose which format of email to send." msgstr "" +#: includes/core/emails/class-wcs-email-cancelled-subscription.php:203 +#: includes/core/emails/class-wcs-email-expired-subscription.php:176 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:175 +msgctxt "email type" +msgid "Plain text" +msgstr "" + #: includes/core/emails/class-wcs-email-cancelled-subscription.php:204 #: includes/core/emails/class-wcs-email-expired-subscription.php:177 #: includes/core/emails/class-wcs-email-on-hold-subscription.php:176 msgctxt "email type" -msgid "Plain text" +msgid "HTML" msgstr "" #: includes/core/emails/class-wcs-email-cancelled-subscription.php:205 #: includes/core/emails/class-wcs-email-expired-subscription.php:178 #: includes/core/emails/class-wcs-email-on-hold-subscription.php:177 msgctxt "email type" -msgid "HTML" -msgstr "" - -#: includes/core/emails/class-wcs-email-cancelled-subscription.php:206 -#: includes/core/emails/class-wcs-email-expired-subscription.php:179 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:178 -msgctxt "email type" msgid "Multipart" msgstr "" -#: includes/core/emails/class-wcs-email-completed-renewal-order.php:25 +#: includes/core/emails/class-wcs-email-completed-renewal-order.php:24 msgid "Completed Renewal Order" msgstr "" -#: includes/core/emails/class-wcs-email-completed-renewal-order.php:26 +#: includes/core/emails/class-wcs-email-completed-renewal-order.php:25 msgid "Renewal order complete emails are sent to the customer when a subscription renewal order is marked complete and usually indicates that the item for that renewal period has been shipped." msgstr "" -#: includes/core/emails/class-wcs-email-completed-renewal-order.php:29 +#: includes/core/emails/class-wcs-email-completed-renewal-order.php:28 msgctxt "Default email heading for email to customer on completed renewal order" msgid "Your renewal order is complete" msgstr "" #. translators: $1: {site_title}, $2: {order_date}, variables that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-completed-renewal-order.php:31 +#: includes/core/emails/class-wcs-email-completed-renewal-order.php:30 #, php-format msgctxt "Default email subject for email to customer on completed renewal order" msgid "Your %1$s renewal order from %2$s is complete" msgstr "" -#: includes/core/emails/class-wcs-email-completed-switch-order.php:31 +#: includes/core/emails/class-wcs-email-completed-switch-order.php:30 msgid "Subscription Switch Complete" msgstr "" -#: includes/core/emails/class-wcs-email-completed-switch-order.php:32 +#: includes/core/emails/class-wcs-email-completed-switch-order.php:31 msgid "Subscription switch complete emails are sent to the customer when a subscription is switched successfully." msgstr "" -#: includes/core/emails/class-wcs-email-completed-switch-order.php:35 +#: includes/core/emails/class-wcs-email-completed-switch-order.php:34 msgid "Your subscription change is complete" msgstr "" -#: includes/core/emails/class-wcs-email-completed-switch-order.php:36 +#: includes/core/emails/class-wcs-email-completed-switch-order.php:35 msgid "Your {site_title} subscription change from {order_date} is complete" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:25 +#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:24 msgid "Customer Notification: Automatic renewal notice" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:26 +#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:25 msgid "Customer Notification: Automatic renewal notice emails are sent when customer's subscription is about to be renewed automatically." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:28 +#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:27 msgid "Automatic renewal notice" msgstr "" #. translators: $1: {site_title}, $2: {customers_first_name}, $3: {time_until_renewal}, variables that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:32 +#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:31 #, php-format msgctxt "default email subject for subscription's automatic renewal notice" msgid "[%1$s] %2$s, your subscription automatically renews in %3$s!" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:58 +#: includes/core/emails/class-wcs-email-customer-notification-auto-renewal.php:57 msgid "Thank you for being a loyal customer, {customers_first_name} — we appreciate your business." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:25 +#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:24 msgid "Customer Notification: Free trial expiration: automatic payment notice" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:26 +#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:25 msgid "Free trial expiry notification emails are sent when customer's free trial for an automatically renewd subscription is about to expire." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:28 +#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:27 msgid "Free trial expiration: automatic payment notice" msgstr "" #. translators: $1: {site_title}, $2: {customers_first_name}, variables that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:30 +#: includes/core/emails/class-wcs-email-customer-notification-auto-trial-expiration.php:29 #, php-format msgctxt "default email subject for free trial expiry notification emails sent to the customer" msgid "[%1$s] %2$s, your paid subscription starts soon!" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:25 +#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:24 msgid "Customer Notification: Manual renewal notice" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:26 +#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:25 msgid "Customer Notification: Manual renewal notice are sent when customer's subscription needs to be manually renewed." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:28 +#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:27 msgid "Manual renewal notice" msgstr "" #. translators: $1: {site_title}, $2: {customers_first_name}, variables that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:30 +#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:29 #, php-format msgctxt "default email subject for notification for a manually renewed subscription sent to the customer" msgid "[%1$s] %2$s, your subscription is ready to be renewed!" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:52 +#: includes/core/emails/class-wcs-email-customer-notification-manual-renewal.php:51 msgid "Thanks again for choosing {site_title}." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:26 +#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:25 msgid "Customer Notification: Free trial expiration: manual payment required" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:27 +#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:26 msgid "Free trial expiry notification emails are sent when customer's free trial for a manually renewed subscription is about to expire." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:29 +#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:28 msgid "Free trial expiration: manual payment required" msgstr "" #. translators: $1: {site_title}, $2: {customers_first_name}, variables that will be substituted when email is sent out. -#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:31 +#: includes/core/emails/class-wcs-email-customer-notification-manual-trial-expiration.php:30 #, php-format msgctxt "default email subject for an email notification for a manually renewed subscription with free trial expiry emails sent to the customer" msgid "[%1$s] %2$s, your free trial is almost up!" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:25 +#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:24 msgid "Customer Notification: Subscription expiration notice" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:26 +#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:25 msgid "Subscription expiration notification emails are sent when customer's subscription is about to expire." msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:28 +#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:27 msgid "Subscription expiration notice" msgstr "" #. translators: $1: {site_title}, $2: {customers_first_name}, variables that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:30 +#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:29 #, php-format msgctxt "default email subject for subscription expiry notification email sent to the customer" msgid "[%1$s] %2$s, your subscription is about to expire!" msgstr "" -#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:52 +#: includes/core/emails/class-wcs-email-customer-notification-subscription-expiration.php:51 msgid "Thank you for choosing {site_title}, {customers_first_name}." msgstr "" @@ -4766,129 +4768,129 @@ msgstr "" msgid "Skipped sending \"%1$s\": %2$s" msgstr "" -#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:23 +#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:22 msgid "On-hold Renewal Order" msgstr "" -#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:24 +#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:23 msgid "This is an order notification sent to customers containing order details after a renewal order is placed on-hold." msgstr "" -#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:25 +#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:24 msgid "Your {site_title} renewal order has been received!" msgstr "" -#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:26 +#: includes/core/emails/class-wcs-email-customer-on-hold-renewal-order.php:25 msgid "Thank you for your renewal order" msgstr "" -#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:40 +#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:39 msgid "Customer Renewal Invoice" msgstr "" -#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:41 +#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:40 msgid "Sent to a customer when the subscription is due for renewal and the renewal requires a manual payment, either because it uses manual renewals or the automatic recurring payment failed for the initial attempt and all automatic retries (if any). The email contains renewal order information and payment links." msgstr "" -#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:48 +#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:47 msgid "Invoice for renewal order {order_number} from {order_date}" msgstr "" -#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:49 +#: includes/core/emails/class-wcs-email-customer-renewal-invoice.php:48 msgid "Invoice for renewal order {order_number}" msgstr "" -#: includes/core/emails/class-wcs-email-expired-subscription.php:26 +#: includes/core/emails/class-wcs-email-expired-subscription.php:25 msgid "Expired Subscription" msgstr "" -#: includes/core/emails/class-wcs-email-expired-subscription.php:27 +#: includes/core/emails/class-wcs-email-expired-subscription.php:26 msgid "Expired Subscription emails are sent when a customer's subscription expires." msgstr "" -#: includes/core/emails/class-wcs-email-expired-subscription.php:29 +#: includes/core/emails/class-wcs-email-expired-subscription.php:28 msgid "Subscription Expired" msgstr "" #. translators: placeholder is {site_title}, a variable that will be substituted when email is sent out -#: includes/core/emails/class-wcs-email-expired-subscription.php:31 +#: includes/core/emails/class-wcs-email-expired-subscription.php:30 #, php-format msgctxt "default email subject for expired emails sent to the admin" msgid "[%s] Subscription Expired" msgstr "" -#: includes/core/emails/class-wcs-email-expired-subscription.php:78 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:77 +#: includes/core/emails/class-wcs-email-expired-subscription.php:77 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:76 msgid "Subscription argument passed in is not an object." msgstr "" #. translators: %s: default e-mail heading. -#: includes/core/emails/class-wcs-email-expired-subscription.php:166 -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:165 +#: includes/core/emails/class-wcs-email-expired-subscription.php:165 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:164 #, php-format msgid "This controls the main heading contained within the email notification. Leave blank to use the default heading: %s." msgstr "" -#: includes/core/emails/class-wcs-email-new-renewal-order.php:22 +#: includes/core/emails/class-wcs-email-new-renewal-order.php:21 msgid "New Renewal Order" msgstr "" -#: includes/core/emails/class-wcs-email-new-renewal-order.php:23 +#: includes/core/emails/class-wcs-email-new-renewal-order.php:22 msgid "New renewal order emails are sent when a subscription renewal payment is processed." msgstr "" -#: includes/core/emails/class-wcs-email-new-renewal-order.php:25 +#: includes/core/emails/class-wcs-email-new-renewal-order.php:24 msgid "New subscription renewal order" msgstr "" -#: includes/core/emails/class-wcs-email-new-renewal-order.php:26 +#: includes/core/emails/class-wcs-email-new-renewal-order.php:25 msgid "[{site_title}] New subscription renewal order ({order_number}) - {order_date}" msgstr "" -#: includes/core/emails/class-wcs-email-new-switch-order.php:27 -#: includes/core/emails/class-wcs-email-new-switch-order.php:30 +#: includes/core/emails/class-wcs-email-new-switch-order.php:26 +#: includes/core/emails/class-wcs-email-new-switch-order.php:29 msgid "Subscription Switched" msgstr "" -#: includes/core/emails/class-wcs-email-new-switch-order.php:28 +#: includes/core/emails/class-wcs-email-new-switch-order.php:27 msgid "Subscription switched emails are sent when a customer switches a subscription." msgstr "" -#: includes/core/emails/class-wcs-email-new-switch-order.php:31 +#: includes/core/emails/class-wcs-email-new-switch-order.php:30 msgid "[{site_title}] Subscription Switched ({order_number}) - {order_date}" msgstr "" -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:26 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:25 msgid "Suspended Subscription" msgstr "" -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:27 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:26 msgid "Suspended Subscription emails are sent when a customer manually suspends their subscription." msgstr "" -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:29 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:28 msgid "Subscription Suspended" msgstr "" -#: includes/core/emails/class-wcs-email-on-hold-subscription.php:30 +#: includes/core/emails/class-wcs-email-on-hold-subscription.php:29 msgctxt "default email subject for suspended emails sent to the admin" msgid "[{site_title}] Subscription Suspended" msgstr "" -#: includes/core/emails/class-wcs-email-processing-renewal-order.php:24 +#: includes/core/emails/class-wcs-email-processing-renewal-order.php:23 msgid "Processing Renewal order" msgstr "" -#: includes/core/emails/class-wcs-email-processing-renewal-order.php:25 +#: includes/core/emails/class-wcs-email-processing-renewal-order.php:24 msgid "This is an order notification sent to the customer after payment for a subscription renewal order is completed. It contains the renewal order details." msgstr "" -#: includes/core/emails/class-wcs-email-processing-renewal-order.php:28 +#: includes/core/emails/class-wcs-email-processing-renewal-order.php:27 #: includes/gifting/emails/class-wcsg-email-processing-renewal-order.php:33 msgid "Thank you for your order" msgstr "" -#: includes/core/emails/class-wcs-email-processing-renewal-order.php:29 +#: includes/core/emails/class-wcs-email-processing-renewal-order.php:28 msgid "Your {site_title} renewal order receipt from {order_date}" msgstr "" @@ -5437,7 +5439,7 @@ msgstr "" msgid "%1$sWarning!%2$s We discovered an issue in %1$sWooCommerce Subscriptions 2.3.0 - 2.3.2%2$s that may cause your subscription renewal order and customer subscription caches to contain invalid data. For information about how to update the cached data, please %3$sopen a new support ticket%4$s." msgstr "" -#: includes/core/upgrades/class-wcs-repair-suspended-paypal-subscriptions.php:54 +#: includes/core/upgrades/class-wcs-repair-suspended-paypal-subscriptions.php:56 msgid "Subscription suspended by Database repair script. This subscription was suspended via PayPal." msgstr "" @@ -5997,34 +5999,34 @@ msgid "There was an error with the update. Please refresh the page and try again msgstr "" #. translators: %s: shipping method label. -#: includes/core/wcs-cart-functions.php:94 -#: includes/core/wcs-cart-functions.php:100 +#: includes/core/wcs-cart-functions.php:95 +#: includes/core/wcs-cart-functions.php:101 #, php-format msgid "Shipping via %s" msgstr "" -#: includes/core/wcs-cart-functions.php:259 +#: includes/core/wcs-cart-functions.php:260 msgctxt "shipping method price" msgid "Free" msgstr "" -#: includes/core/wcs-cart-functions.php:284 +#: includes/core/wcs-cart-functions.php:285 msgid "[Remove]" msgstr "" -#: includes/core/wcs-cart-functions.php:314 +#: includes/core/wcs-cart-functions.php:315 msgid "Free shipping coupon" msgstr "" #. translators: placeholder is price string, denotes tax included in cart/order total -#: includes/core/wcs-cart-functions.php:352 +#: includes/core/wcs-cart-functions.php:353 #, php-format msgctxt "includes tax" msgid "(includes %s)" msgstr "" #. translators: placeholder is a date -#: includes/core/wcs-cart-functions.php:427 +#: includes/core/wcs-cart-functions.php:428 #, php-format msgid "First renewal: %s" msgstr "" @@ -6410,8 +6412,8 @@ msgid "no" msgstr "" #: includes/core/wcs-user-functions.php:319 -#: templates/single-product/add-to-cart/subscription.php:29 -#: templates/single-product/add-to-cart/variable-subscription.php:28 +#: templates/single-product/add-to-cart/subscription.php:41 +#: templates/single-product/add-to-cart/variable-subscription.php:40 msgid "Resubscribe" msgstr "" @@ -6711,14 +6713,14 @@ msgid "File %d" msgstr "" #. Translators: placeholder is a subscription ID. -#: includes/gifting/class-wcsg-email.php:402 +#: includes/gifting/class-wcsg-email.php:397 #, php-format msgctxt "Used in email heading before line items table, placeholder is subscription ID" msgid "Subscription #%s" msgstr "" #. Translators: placeholder is an order ID. -#: includes/gifting/class-wcsg-email.php:405 +#: includes/gifting/class-wcsg-email.php:400 #, php-format msgctxt "Used in email heading before line items table, placeholder is order ID" msgid "Order #%s" @@ -6834,19 +6836,19 @@ msgstr "" msgid "Your {blogname} renewal order receipt from {order_date}" msgstr "" -#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:44 +#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:51 msgid "New Initial Order - Recipient" msgstr "" -#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:45 +#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:52 msgid "This email is sent to recipients notifying them of subscriptions purchased for them." msgstr "" -#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:47 +#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:54 msgid "New Order" msgstr "" -#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:48 +#: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php:55 msgid "Your new subscriptions at {site_title}" msgstr "" @@ -8238,14 +8240,14 @@ msgstr "" #: templates/gifting/emails/plain/recipient-new-initial-order.php:16 #: templates/gifting/emails/plain/recipient-new-initial-order.php:24 #: templates/gifting/emails/recipient-new-initial-order.php:23 -#: templates/gifting/emails/recipient-new-initial-order.php:42 +#: templates/gifting/emails/recipient-new-initial-order.php:43 msgid "subscription" msgid_plural "subscriptions" msgstr[0] "" msgstr[1] "" #: templates/gifting/emails/plain/recipient-new-initial-order.php:21 -#: templates/gifting/emails/recipient-new-initial-order.php:33 +#: templates/gifting/emails/recipient-new-initial-order.php:34 msgid "We noticed you didn't have an account so we created one for you. Your account login details will have been sent to you in a separate email." msgstr "" @@ -8284,7 +8286,7 @@ msgid "Period" msgstr "" #. Translators: 1) is either the singular or plural form of "subscription", 2) is an tag pointing to "My Account", 3) is the closing tag. -#: templates/gifting/emails/recipient-new-initial-order.php:41 +#: templates/gifting/emails/recipient-new-initial-order.php:42 #, php-format msgid "You may access your account area to view your new %1$s here: %2$sMy Account%3$s." msgstr "" @@ -8527,8 +8529,8 @@ msgstr "" msgid "Subscription totals" msgstr "" -#: templates/single-product/add-to-cart/subscription.php:31 -#: templates/single-product/add-to-cart/variable-subscription.php:30 +#: templates/single-product/add-to-cart/subscription.php:44 +#: templates/single-product/add-to-cart/variable-subscription.php:43 msgid "You have an active subscription to this product already." msgstr "" @@ -8536,11 +8538,11 @@ msgstr "" msgid "This product is currently out of stock and unavailable." msgstr "" -#: templates/single-product/add-to-cart/variable-subscription.php:34 +#: templates/single-product/add-to-cart/variable-subscription.php:47 msgid "You have added a variation of this product to the cart already." msgstr "" -#: templates/single-product/add-to-cart/variable-subscription.php:45 +#: templates/single-product/add-to-cart/variable-subscription.php:58 msgid "Clear" msgstr "" @@ -8646,139 +8648,166 @@ msgstr[1] "" msgid "%1$s %2$s %3$d %4$s" msgstr "" -#: build/index.js:10 -#: client/core/recurring-totals/index.js:101 +#. translators: %s Field label. +#: build/index.js:11 +#: client/core/utils/address.js:94 +#, js-format +msgid "%s (optional)" +msgstr "" + +#: build/index.js:11 +#: client/core/recurring-totals/index.js:123 +msgid "Pickup" +msgstr "" + +#: build/index.js:11 +#: client/core/recurring-totals/index.js:124 +msgid "Delivery" +msgstr "" + +#: build/index.js:11 +#: client/core/recurring-totals/index.js:129 +msgid "No available delivery option" +msgstr "" + +#: build/index.js:11 +#: client/core/recurring-totals/index.js:133 +msgid "Enter address to calculate" +msgstr "" + +#: build/index.js:11 +#: client/core/recurring-totals/index.js:186 msgid "Free" msgstr "" #. translators: %s selected shipping rate (ex: flat rate) -#: build/index.js:13 -#: client/core/recurring-totals/index.js:114 +#: build/index.js:14 +#: client/core/recurring-totals/index.js:201 #, js-format msgid "via %s" msgstr "" #. Translators: %1$s is a date. -#: build/index.js:14 -#: client/core/recurring-totals/index.js:148 +#: build/index.js:15 +#: client/core/recurring-totals/index.js:235 #, js-format msgid "Due: %1$s" msgstr "" #. Translators: %1$s is a date. -#: build/index.js:15 -#: client/core/recurring-totals/index.js:153 +#: build/index.js:16 +#: client/core/recurring-totals/index.js:240 #, js-format msgid "Starting: %1$s" msgstr "" -#: build/index.js:15 +#: build/index.js:16 #: client/core/utils/index.js:65 msgid "Daily recurring total" msgstr "" -#: build/index.js:15 +#: build/index.js:16 #: client/core/utils/index.js:70 msgid "Weekly recurring total" msgstr "" -#: build/index.js:15 +#: build/index.js:16 #: client/core/utils/index.js:75 msgid "Monthly recurring total" msgstr "" -#: build/index.js:15 +#: build/index.js:16 #: client/core/utils/index.js:80 msgid "Yearly recurring total" msgstr "" #. translators: %1$s is week, month, year -#: build/index.js:16 +#: build/index.js:17 #: client/core/utils/index.js:89 #, js-format msgid "Recurring total every 2nd %1$s" msgstr "" #. Translators: %1$s is week, month, year -#: build/index.js:17 +#: build/index.js:18 #: client/core/utils/index.js:99 #, js-format msgid "Recurring total every 3rd %1$s" msgstr "" #. Translators: %1$d is number of weeks, months, days, years. %2$s is week, month, year -#: build/index.js:18 +#: build/index.js:19 #: client/core/utils/index.js:108 #, js-format msgid "Recurring total every %1$dth %2$s" msgstr "" -#: build/index.js:18 -#: client/core/recurring-totals/index.js:271 +#: build/index.js:19 +#: client/core/recurring-totals/index.js:362 msgid "Details" msgstr "" -#: build/index.js:18 +#: build/index.js:19 #: client/core/filters/index.js:33 msgid "Total due today" msgstr "" #. translators: the word used to describe billing frequency, e.g. "for" 1 day or "for" 1 month. -#: build/index.js:21 +#: build/index.js:22 #: client/core/filters/index.js:60 msgid "for 1" msgstr "" #. translators: the word used to describe billing frequency, e.g. "for" 6 days or "for" 2 weeks. -#: build/index.js:24 +#: build/index.js:25 #: client/core/filters/index.js:67 msgid "for" msgstr "" #. translators: the word used to describe billing frequency, e.g. "every" 6 days or "every" 2 weeks. -#: build/index.js:27 +#: build/index.js:28 #: client/core/filters/index.js:74 msgid "every" msgstr "" #. translators: %s Product name. -#: build/index.js:30 +#: build/index.js:31 #: client/core/filters/index.js:93 #, js-format msgid "%s (resubscription)" msgstr "" #. translators: %1$s Product name, %2$s Switch type (upgraded, downgraded, or crossgraded). -#: build/index.js:33 +#: build/index.js:34 #: client/core/filters/index.js:100 #, js-format msgid "%1$s (%2$s)" msgstr "" -#: build/index.js:33 +#: build/index.js:34 #: client/core/utils/index.js:185 msgid "Upgrade" msgstr "" -#: build/index.js:33 +#: build/index.js:34 #: client/core/utils/index.js:188 msgid "Downgrade" msgstr "" -#: build/index.js:33 +#: build/index.js:34 #: client/core/utils/index.js:191 msgid "Crossgrade" msgstr "" #. translators: %s is the subscription price to pay immediately (ie: $10). -#: build/index.js:34 +#: build/index.js:35 #: client/core/filters/index.js:112 #, js-format msgid "Due today %s" msgstr "" #. translators: %s is the subscription price to pay immediately (ie: $10). -#: build/index.js:35 +#: build/index.js:36 #: client/core/filters/index.js:117 #, js-format msgid "%s due today" diff --git a/phpstan.neon b/phpstan.neon index 0f1fefe..c10b5db 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,57 +1,4292 @@ parameters: - excludePaths: - analyse: - - includes/api/legacy/* - - includes/core/legacy/* - - templates/* - - includes/core/upgrades/* - - includes/core/emails/* - - includes/core/gateways/paypal/* - - includes/core/data-stores/* - - includes/core/class-wcs-template-loader.php - ignoreErrors: - - '#Access to an undefined property WooCommerce::\$#' - - '#Access to an undefined property WC_Cart::\$#' - - '#Access to an undefined property WP_User::\$#' - - '#Access to an undefined property WC_Checkout::\$#' - - '#Access to an undefined property WC_Shipping_Rate::\$#' - - '#Access to an undefined property WC_Subscription_Legacy::\$#' - - '#Access to an undefined property WC_Product_Variable_Subscription_Legacy::\$#' - - '#Access to an undefined property WC_Product_Subscription_Variation_Legacy::\$#' - - '#Access to an undefined property WC_Product_Subscription_Legacy::\$#' - - '#Access to an undefined property WCS_PayPal_Reference_Transaction_API::\$#' - - '#Access to an undefined property WC_Email::\$#' - - '#Access to an undefined property WC_Subscriptions_Deprecation_Handler::\$#' - - '#Access to an undefined property WC_Session::\$#' - - '#Access to an undefined static property WC_Subscriptions_Deprecation_Handler::\$#' - - '#Access to an undefined property WooCommerce::\$payment_gateways#' - - '#Call to an undefined method WC_Order_Item::get_product#' - - '#Call to an undefined method WC_Order_Item::get_variation_id#' - - '#Call to an undefined method WCS_Retry_Store::#' - - '#Call to an undefined method WC_Data_Store::#' - - '#Call to an undefined method WC_Session::#' - - '#Call to an undefined method WC_Order_Data_Store_CPT::delete_all_metadata_by_key#' - - '#Call to an undefined method object::get_coupons#' - - '#Call to an undefined method object::get_changes#' - - '#Call to method .* on an unknown class WC_PayPal_Express_API#' - - '#Call to method .* on an unknown class OrdersTableQuery#' - - '#Call to method .* on an unknown class ActionScheduler_Action#' - - '#Call to static method .* on an unknown class ActionScheduler_.*#' - - '#Access to property .* on an unknown class WC_Gateway#' - - '#Access to an undefined property object::\$discount_cart#' - - '#Access to an undefined property object::\$value#' - - '#Variable \$this might not be defined#' - - '#Function as_.*_action not found#' - - '#Function as_.*_actions not found#' - - '#Parameter .* has invalid type WC_Gateway#' - - '#Parameter .* has invalid type ActionScheduler_.*#' - - '#Class WC_Payments_Subscription_Service not found#' - - '#Class .*OrdersTableDataStore not found#' - - '#Parameter .* has invalid type OrdersTableQuery.#' - - '#Constant WC_VERSION not found#' - - '#Method .* has invalid return type ActionScheduler_.*#' - - '#Function wc_memberships.* not found#' - - '#Parameter .* of method .* has invalid type WC_Memberships_Membership_Plan#' - - '#Access to an undefined property WCSG_Email_Completed_Renewal_Order::\$#' - - '#Access to an undefined property WC_Subscription::\$recipient_user#' - - '#Cannot access property \$order_date on bool.*#' + excludePaths: + analyse: + - includes/api/legacy/* + - includes/core/legacy/* + - includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + ignoreErrors: + - '#Constant WC_VERSION not found#' + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 2 + path: includes/admin/reports/class-wcs-report-cache-manager.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 2 + path: includes/admin/reports/class-wcs-report-cache-manager.php + + - + message: "#^Function as_unschedule_action not found\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-cache-manager.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$active_subscriptions\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$customer_id\\.$#" + count: 4 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$initial_order_count\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$initial_order_total\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$renewal_switch_count\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$renewal_switch_total\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Access to an undefined property WP_User\\:\\:\\$total_subscriptions\\.$#" + count: 1 + path: includes/admin/reports/class-wcs-report-subscription-by-customer.php + + - + message: "#^Variable \\$this might not be defined\\.$#" + count: 1 + path: includes/admin/views/html-report-by-period.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 3 + path: includes/api/class-wc-rest-subscriptions-controller.php + + - + message: "#^Access to an undefined property WC_API_Subscriptions_Customers\\:\\:\\$base\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Access to an undefined property WC_API_Subscriptions_Customers\\:\\:\\$server\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Access to constant READABLE on an unknown class WC_API_SERVER\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Access to private property WooCommerce\\:\\:\\$api\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Access to property \\$WC_API_Subscriptions on an unknown class WC_API\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions_Customers\\:\\:validate_request\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Parameter \\$server of method WC_API_Subscriptions_Customers\\:\\:__construct\\(\\) has invalid type WC_API_Server\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^WC_API_Subscriptions_Customers\\:\\:__construct\\(\\) calls parent\\:\\:__construct\\(\\) but WC_API_Subscriptions_Customers does not extend any class\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions-customers.php + + - + message: "#^Access to an undefined property WC_API_Subscriptions\\:\\:\\$post_type\\.$#" + count: 7 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to an undefined property WC_API_Subscriptions\\:\\:\\$server\\.$#" + count: 5 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant ACCEPT_DATA on an unknown class WC_API_Server\\.$#" + count: 4 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant CREATABLE on an unknown class WC_API_Server\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant DELETABLE on an unknown class WC_API_SERVER\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant DELETABLE on an unknown class WC_API_Server\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant EDITABLE on an unknown class WC_API_SERVER\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant EDITABLE on an unknown class WC_API_Server\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to constant READABLE on an unknown class WC_API_Server\\.$#" + count: 7 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to private property WooCommerce\\:\\:\\$api\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to property \\$WC_API_Customers on an unknown class WC_API\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:create_order\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:create_order_note\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:delete\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:delete_order_note\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:edit_order\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:edit_order_note\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:get_order\\(\\)\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:get_order_note\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:get_order_notes\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:get_orders_count\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:is_readable\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:merge_query_args\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to an undefined method WC_API_Subscriptions\\:\\:validate_request\\(\\)\\.$#" + count: 4 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to method getCode\\(\\) on an unknown class WC_API_Exception\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to method getErrorCode\\(\\) on an unknown class WC_API_Exception\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Call to method getMessage\\(\\) on an unknown class WC_API_Exception\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Caught class WC_API_Exception not found\\.$#" + count: 2 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Default value of the parameter \\#4 \\$page \\(int\\) of method WC_API_Subscriptions\\:\\:get_subscriptions\\(\\) is incompatible with type null\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Instantiated class WC_API_Exception not found\\.$#" + count: 6 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^PHPDoc tag @param has invalid value \\(array data raw order data\\)\\: Unexpected token \"data\", expected variable at offset 67$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$fields$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$id$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^is_wp_error\\(WC_Subscription\\) will always evaluate to false\\.$#" + count: 1 + path: includes/api/legacy/class-wc-api-subscriptions.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 1 + path: includes/api/legacy/class-wc-rest-subscriptions-controller.php + + - + message: "#^Call to an undefined static method WC_REST_Orders_Controller\\:\\:create_order\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-rest-subscriptions-controller.php + + - + message: "#^Call to an undefined static method WC_REST_Orders_Controller\\:\\:update_order\\(\\)\\.$#" + count: 1 + path: includes/api/legacy/class-wc-rest-subscriptions-controller.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/api/v1/class-wc-rest-subscriptions-v1-controller.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product_id\\(\\)\\.$#" + count: 1 + path: includes/api/v1/class-wc-rest-subscriptions-v1-controller.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_variation_id\\(\\)\\.$#" + count: 1 + path: includes/api/v1/class-wc-rest-subscriptions-v1-controller.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 3 + path: includes/api/v2/class-wc-rest-subscriptions-v2-controller.php + + - + message: "#^Call to static method is_true\\(\\) on an unknown class Automattic\\\\Jetpack\\\\Constants\\.$#" + count: 1 + path: includes/class-wcs-api.php + + - + message: "#^Access to private property WooCommerce\\:\\:\\$api\\.$#" + count: 2 + path: includes/class-wcs-webhooks.php + + - + message: "#^Access to property \\$WC_API_Subscriptions on an unknown class WC_API\\.$#" + count: 2 + path: includes/class-wcs-webhooks.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 1 + path: includes/core/abstracts/abstract-wcs-background-repairer.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 1 + path: includes/core/abstracts/abstract-wcs-background-updater.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 1 + path: includes/core/abstracts/abstract-wcs-background-updater.php + + - + message: "#^Function as_unschedule_action not found\\.$#" + count: 1 + path: includes/core/abstracts/abstract-wcs-background-updater.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 1 + path: includes/core/admin/class-wcs-admin-post-types.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_subscriptions_count_by_status\\(\\)\\.$#" + count: 1 + path: includes/core/admin/class-wcs-admin-post-types.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:untrash_order\\(\\)\\.$#" + count: 1 + path: includes/core/admin/class-wcs-admin-post-types.php + + - + message: "#^Class Automattic\\\\WooCommerce\\\\Internal\\\\DataStores\\\\Orders\\\\OrdersTableDataStore not found\\.$#" + count: 2 + path: includes/core/admin/class-wcs-admin-post-types.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 2 + path: includes/core/admin/class-wcs-admin-system-status.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_subscriptions_count_by_status\\(\\)\\.$#" + count: 1 + path: includes/core/admin/class-wcs-admin-system-status.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$cart_contents_total\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$coupon_discount_amounts\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$dp\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$end_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$fee_total\\.$#" + count: 3 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$fees\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$next_payment_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_cart_key\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 17 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$shipping_tax_total\\.$#" + count: 3 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$shipping_taxes\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$shipping_total\\.$#" + count: 3 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$start_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$tax_display_cart\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$tax_total\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$total\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$trial_end_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WC_Checkout\\:\\:\\$shipping_methods\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$shipping\\.$#" + count: 9 + path: includes/core/class-wc-subscriptions-cart.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-change-payment-gateway.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$end_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$next_payment_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_cart_key\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$shipping_tax_total\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$shipping_taxes\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$shipping_total\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$start_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$tax_total\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$taxes\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$total\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$trial_end_date\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$checkout\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$shipping\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-checkout.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$coupon_discount_amounts\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-coupon.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$dp\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-coupon.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$subtotal\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-coupon.php + + - + message: "#^Access to an undefined property object\\:\\:\\$discount_cart\\.$#" + count: 6 + path: includes/core/class-wc-subscriptions-coupon.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-coupon.php + + - + message: "#^Function as_unschedule_all_actions not found\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-email-notifications.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-extend-store-endpoint.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$shipping\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-extend-store-endpoint.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 5 + path: includes/core/class-wc-subscriptions-manager.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:untrash_order\\(\\)\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-manager.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 2 + path: includes/core/class-wc-subscriptions-order.php + + - + message: "#^Call to method get\\(\\) on an unknown class OrdersTableQuery\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-order.php + + - + message: "#^Call to method get_table_name\\(\\) on an unknown class OrdersTableQuery\\.$#" + count: 4 + path: includes/core/class-wc-subscriptions-order.php + + - + message: "#^Cannot access property \\$order_custom_fields on bool\\|WC_Order\\|WC_Order_Refund\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-order.php + + - + message: "#^Parameter \\$order_query of method WC_Subscriptions_Order\\:\\:filter_orders_query_by_parent_orders\\(\\) has invalid type OrdersTableQuery\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-order.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-synchroniser.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_subscriptions_count_by_status\\(\\)\\.$#" + count: 1 + path: includes/core/class-wc-subscriptions-tracker.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 2 + path: includes/core/class-wcs-action-scheduler-customer-notifications.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 1 + path: includes/core/class-wcs-action-scheduler-customer-notifications.php + + - + message: "#^Function as_unschedule_all_actions not found\\.$#" + count: 1 + path: includes/core/class-wcs-action-scheduler-customer-notifications.php + + - + message: "#^Call to static method instance\\(\\) on an unknown class ActionScheduler_Versions\\.$#" + count: 1 + path: includes/core/class-wcs-action-scheduler.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 3 + path: includes/core/class-wcs-action-scheduler.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 2 + path: includes/core/class-wcs-action-scheduler.php + + - + message: "#^Function as_unschedule_all_actions not found\\.$#" + count: 1 + path: includes/core/class-wcs-action-scheduler.php + + - + message: "#^Function as_has_scheduled_action not found\\.$#" + count: 2 + path: includes/core/class-wcs-batch-processing-controller.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 2 + path: includes/core/class-wcs-batch-processing-controller.php + + - + message: "#^Function as_unschedule_all_actions not found\\.$#" + count: 3 + path: includes/core/class-wcs-batch-processing-controller.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 3 + path: includes/core/class-wcs-cached-data-manager.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$cart_contents_count\\.$#" + count: 1 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Access to an undefined property WC_Session\\:\\:\\$cart\\.$#" + count: 1 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Access to an undefined property WC_Session\\:\\:\\$order_awaiting_payment\\.$#" + count: 1 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product_id\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_variation_id\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Call to an undefined method WC_Session\\:\\:destroy_session\\(\\)\\.$#" + count: 3 + path: includes/core/class-wcs-cart-renewal.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 2 + path: includes/core/class-wcs-change-payment-method-admin.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 2 + path: includes/core/class-wcs-download-handler.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-download-handler.php + + - + message: "#^Call to method get_args\\(\\) on an unknown class ActionScheduler_Action\\.$#" + count: 2 + path: includes/core/class-wcs-failed-scheduled-action-manager.php + + - + message: "#^Call to method get_hook\\(\\) on an unknown class ActionScheduler_Action\\.$#" + count: 3 + path: includes/core/class-wcs-failed-scheduled-action-manager.php + + - + message: "#^Call to static method instance\\(\\) on an unknown class ActionScheduler_Logger\\.$#" + count: 1 + path: includes/core/class-wcs-failed-scheduled-action-manager.php + + - + message: "#^Call to static method instance\\(\\) on an unknown class ActionScheduler_Store\\.$#" + count: 1 + path: includes/core/class-wcs-failed-scheduled-action-manager.php + + - + message: "#^Method WCS_Failed_Scheduled_Action_Manager\\:\\:get_action\\(\\) has invalid return type ActionScheduler_Action\\.$#" + count: 1 + path: includes/core/class-wcs-failed-scheduled-action-manager.php + + - + message: "#^Parameter \\$action of method WCS_Failed_Scheduled_Action_Manager\\:\\:get_context_from_action_error\\(\\) has invalid type ActionScheduler_Action\\.$#" + count: 1 + path: includes/core/class-wcs-failed-scheduled-action-manager.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-limiter.php + + - + message: "#^Access to an undefined property object\\:\\:\\$value\\.$#" + count: 2 + path: includes/core/class-wcs-object-data-cache-manager.php + + - + message: "#^Call to an undefined method object\\:\\:get_changes\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-object-data-cache-manager.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-remove-item.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/core/class-wcs-renewal-cart-stock-manager.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$tax_display_cart\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Access to static property \\$template_path on an unknown class PP_One_Page_Checkout\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'admin\\-new\\-renewal\\-order\\.php' \\('admin\\-new\\-renewal\\-order\\.php', 'admin\\-new\\-renewal\\-order\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'admin\\-new\\-switch\\-order\\.php' \\('admin\\-new\\-switch\\-order\\.php', 'admin\\-new\\-switch\\-order\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'admin\\-payment\\-retry\\.php' \\('admin\\-payment\\-retry\\.php', 'admin\\-payment\\-retry\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'cancelled\\-subscription\\.php' \\('cancelled\\-subscription\\.php', 'cancelled\\-subscription\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'customer\\-completed\\-renewal\\-order\\.php' \\('customer\\-completed\\-renewal\\-order\\.php', 'customer\\-completed\\-renewal\\-order\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'customer\\-completed\\-switch\\-order\\.php' \\('customer\\-completed\\-switch\\-order\\.php', 'customer\\-completed\\-switch\\-order\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'customer\\-on\\-hold\\-renewal\\-order\\.php' \\('customer\\-on\\-hold\\-renewal\\-order\\.php', 'customer\\-on\\-hold\\-renewal\\-order\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'customer\\-payment\\-retry\\.php' \\('customer\\-payment\\-retry\\.php', 'customer\\-payment\\-retry\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'customer\\-processing\\-renewal\\-order\\.php' \\('customer\\-processing\\-renewal\\-order\\.php', 'customer\\-processing\\-renewal\\-order\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'customer\\-renewal\\-invoice\\.php' \\('customer\\-renewal\\-invoice\\.php', 'customer\\-renewal\\-invoice\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'email\\-order\\-details\\.php' \\('email\\-order\\-details\\.php', 'email\\-order\\-details\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'expired\\-subscription\\.php' \\('expired\\-subscription\\.php', 'expired\\-subscription\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'on\\-hold\\-subscription\\.php' \\('on\\-hold\\-subscription\\.php', 'on\\-hold\\-subscription\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Array has 2 duplicate keys with value 'subscription\\-info\\.php' \\('subscription\\-info\\.php', 'subscription\\-info\\.php'\\)\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Binary operation \"\\.\" between non\\-falsy\\-string and array results in an error\\.$#" + count: 1 + path: includes/core/class-wcs-template-loader.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:init\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-data-store-controller.php + + - + message: "#^Class Automattic\\\\WooCommerce\\\\Internal\\\\DataStores\\\\Orders\\\\OrdersTableDataStoreMeta not found\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-data-store-controller.php + + - + message: "#^Class Automattic\\\\WooCommerce\\\\Internal\\\\Utilities\\\\DatabaseUtil not found\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-data-store-controller.php + + - + message: "#^Access to an undefined property WCS_Orders_Table_Subscription_Data_Store\\:\\:\\$data_store_meta\\.$#" + count: 6 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Access to an undefined property WCS_Orders_Table_Subscription_Data_Store\\:\\:\\$internal_meta_keys\\.$#" + count: 3 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:clear_caches\\(\\)\\.$#" + count: 2 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:delete_order_data_from_custom_order_tables\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:get_cpt_data_store_instance\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:get_props_to_update\\(\\)\\.$#" + count: 2 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:persist_updates\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WCS_Orders_Table_Subscription_Data_Store\\:\\:trash_order\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:update_user_by_order_id\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined static method WCS_Orders_Table_Subscription_Data_Store\\:\\:get_meta_table_name\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined static method WCS_Orders_Table_Subscription_Data_Store\\:\\:get_orders_table_name\\(\\)\\.$#" + count: 4 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to static method get_constant\\(\\) on an unknown class Automattic\\\\Jetpack\\\\Constants\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Class Automattic\\\\WooCommerce\\\\Internal\\\\DataStores\\\\Orders\\\\DataSynchronizer not found\\.$#" + count: 2 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^WCS_Orders_Table_Subscription_Data_Store\\:\\:create\\(\\) calls parent\\:\\:create\\(\\) but WCS_Orders_Table_Subscription_Data_Store does not extend any class\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^WCS_Orders_Table_Subscription_Data_Store\\:\\:get_total_refunded\\(\\) calls parent\\:\\:get_total_refunded\\(\\) but WCS_Orders_Table_Subscription_Data_Store does not extend any class\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^WCS_Orders_Table_Subscription_Data_Store\\:\\:get_total_shipping_refunded\\(\\) calls parent\\:\\:get_total_shipping_refunded\\(\\) but WCS_Orders_Table_Subscription_Data_Store does not extend any class\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^WCS_Orders_Table_Subscription_Data_Store\\:\\:get_total_tax_refunded\\(\\) calls parent\\:\\:get_total_tax_refunded\\(\\) but WCS_Orders_Table_Subscription_Data_Store does not extend any class\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^WCS_Orders_Table_Subscription_Data_Store\\:\\:init_order_record\\(\\) calls parent\\:\\:init_order_record\\(\\) but WCS_Orders_Table_Subscription_Data_Store does not extend any class\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^WCS_Orders_Table_Subscription_Data_Store\\:\\:persist_order_to_db\\(\\) calls parent\\:\\:persist_order_to_db\\(\\) but WCS_Orders_Table_Subscription_Data_Store does not extend any class\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-orders-table-subscription-data-store.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:delete_all_metadata_by_key\\(\\)\\.$#" + count: 1 + path: includes/core/data-stores/class-wcs-related-order-store-cached-cpt.php + + - + message: "#^Access to an undefined static property WC_Subscriptions_Deprecation_Handler\\:\\:\\$version\\.$#" + count: 2 + path: includes/core/deprecated/deprecation-handlers/class-wc-subscriptions-deprecation-handler.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_subscriptions_count_by_status\\(\\)\\.$#" + count: 1 + path: includes/core/deprecated/deprecation-handlers/class-wc-subscriptions-deprecation-handler.php + + - + message: "#^Access to an undefined property WC_Email\\:\\:\\$retry\\.$#" + count: 2 + path: includes/core/emails/class-wc-subscriptions-email-preview.php + + - + message: "#^Access to an undefined property WC_Email\\:\\:\\$subscriptions\\.$#" + count: 2 + path: includes/core/emails/class-wc-subscriptions-email-preview.php + + - + message: "#^Call to an undefined method WC_Email\\:\\:get_time_until_date\\(\\)\\.$#" + count: 1 + path: includes/core/emails/class-wc-subscriptions-email-preview.php + + - + message: "#^Call to an undefined method WCS_Email_Customer_Notification\\:\\:get_relevant_date_type\\(\\)\\.$#" + count: 4 + path: includes/core/emails/class-wcs-email-customer-notification.php + + - + message: "#^Cannot call method get_customer_id\\(\\) on bool\\|object\\.$#" + count: 2 + path: includes/core/emails/class-wcs-email-customer-notification.php + + - + message: "#^Cannot call method get_parent\\(\\) on bool\\|object\\.$#" + count: 2 + path: includes/core/emails/class-wcs-email-customer-notification.php + + - + message: "#^Cannot call method get_view_order_url\\(\\) on bool\\|object\\.$#" + count: 2 + path: includes/core/emails/class-wcs-email-customer-notification.php + + - + message: "#^Cannot call method payment_method_supports\\(\\) on bool\\|object\\.$#" + count: 2 + path: includes/core/emails/class-wcs-email-customer-notification.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 1 + path: includes/core/gateways/class-wc-subscriptions-core-payment-gateways.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 2 + path: includes/core/gateways/class-wc-subscriptions-core-payment-gateways.php + + - + message: "#^Access to property \\$id on an unknown class WC_Gateway\\.$#" + count: 2 + path: includes/core/gateways/class-wc-subscriptions-core-payment-gateways.php + + - + message: "#^Class WC_Payments_Subscription_Service not found\\.$#" + count: 1 + path: includes/core/gateways/class-wc-subscriptions-core-payment-gateways.php + + - + message: "#^Parameter \\$gateway of method WC_Subscriptions_Core_Payment_Gateways\\:\\:gateway_supports_subscriptions\\(\\) has invalid type WC_Gateway\\.$#" + count: 1 + path: includes/core/gateways/class-wc-subscriptions-core-payment-gateways.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 2 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method are_reference_transactions_enabled\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method create_billing_agreement\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method do_express_checkout\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method do_reference_transaction\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method get_express_checkout_details\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method get_paypal_args\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method get_transaction_types\\(\\) on an unknown class WC_PayPal_Express_API\\.$#" + count: 4 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method valid_response\\(\\) on an unknown class WC_PayPal_Express_API\\.$#" + count: 2 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Class WCS_PayPal_Reference_Transaction_IPN_Handler referenced with incorrect case\\: WCS_Paypal_Reference_Transaction_IPN_Handler\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Class WCS_PayPal_Standard_IPN_Handler referenced with incorrect case\\: WCS_Paypal_Standard_IPN_Handler\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Method WCS_PayPal\\:\\:get_api\\(\\) has invalid return type WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Method WCS_PayPal\\:\\:get_ipn_handler\\(\\) has invalid return type WC_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Property WCS_PayPal\\:\\:\\$api has unknown class WCS_PayPal_Express_API as its type\\.$#" + count: 1 + path: includes/core/gateways/paypal/class-wcs-paypal.php + + - + message: "#^Call to method get_id\\(\\) on an unknown class SV_WC_Plugin\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Call to method get_plugin_name\\(\\) on an unknown class SV_WC_Plugin\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Call to method get_version\\(\\) on an unknown class SV_WC_Plugin\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Method WCS_SV_API_Base\\:\\:get_new_request\\(\\) has invalid return type SV_WC_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Method WCS_SV_API_Base\\:\\:get_plugin\\(\\) has invalid return type SV_WC_Plugin\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Method WCS_SV_API_Base\\:\\:set_request_header\\(\\) should return string but return statement is missing\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Method WCS_SV_API_Base\\:\\:set_response_handler\\(\\) should return array but return statement is missing\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/abstracts/abstract-wcs-sv-api-base.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 4 + path: includes/core/gateways/paypal/includes/admin/class-wcs-paypal-admin.php + + - + message: "#^Action callback returns array but should not return anything\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/admin/class-wcs-paypal-admin.php + + - + message: "#^Method WCS_PayPal_Change_Payment_Method_Admin\\:\\:validate_payment_meta\\(\\) should return array but return statement is missing\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/admin/class-wcs-paypal-change-payment-method-admin.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$payment_method_id$#" + count: 1 + path: includes/core/gateways/paypal/includes/admin/class-wcs-paypal-change-payment-method-admin.php + + - + message: "#^@param WC_PayPal_Reference_Transaction_API_Request \\$instance does not accept actual type of parameter\\: \\$this\\(WCS_PayPal_Reference_Transaction_API_Request\\)\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php + + - + message: "#^Binary operation \"\\+\" between float and string results in an error\\.$#" + count: 3 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php + + - + message: "#^Method WCS_PayPal_Reference_Transaction_API_Request\\:\\:get_method\\(\\) should return null but return statement is missing\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$type$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-request.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$response$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api-response.php + + - + message: "#^Access to an undefined property WCS_PayPal_Reference_Transaction_API\\:\\:\\$order\\.$#" + count: 3 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Call to method create_billing_agreement\\(\\) on an unknown class WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Call to method do_express_checkout\\(\\) on an unknown class WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Call to method do_reference_transaction\\(\\) on an unknown class WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Call to method get_express_checkout_details\\(\\) on an unknown class WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Call to method manage_recurring_payments_profile_status\\(\\) on an unknown class WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Call to method set_express_checkout\\(\\) on an unknown class WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 2 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Method WCS_PayPal_Reference_Transaction_API\\:\\:do_reference_transaction\\(\\) has invalid return type SV_WC_Payment_Gateway_API_Response\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Method WCS_PayPal_Reference_Transaction_API\\:\\:get_express_checkout_details\\(\\) has invalid return type WC_PayPal_Reference_Transaction_API_Checkout_Response\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Method WCS_PayPal_Reference_Transaction_API\\:\\:get_new_request\\(\\) has invalid return type WC_PayPal_Reference_Transaction_API_Request\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^Method WCS_PayPal_Reference_Transaction_API\\:\\:manage_recurring_payments_profile_status\\(\\) has invalid return type SV_WC_Payment_Gateway_API_Response\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^PHPDoc tag @throws with type SV_WC_Payment_Gateway_Exception is not subtype of Throwable$#" + count: 2 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-api.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$posted$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-reference-transaction-ipn-handler.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$item_name$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-change-payment-method.php + + - + message: "#^Default value of the parameter \\#2 \\$error \\(string\\) of method WCS_PayPal_Standard_IPN_Failure_Handler\\:\\:log_ipn_errors\\(\\) is incompatible with type array\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-failure-handler.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 2 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Access to an undefined property object\\:\\:\\$subscription_key\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Binary operation \"\\-\" between string and 1 results in an error\\.$#" + count: 2 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Undefined variable\\: \\$ipn_id$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Variable \\$ipn_id in empty\\(\\) is never defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Variable \\$ipn_id in isset\\(\\) is never defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Variable \\$ipn_transaction_id might not be defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Variable \\$transaction_order might not be defined\\.$#" + count: 4 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-ipn-handler.php + + - + message: "#^Variable \\$item_names might not be defined\\.$#" + count: 2 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-request.php + + - + message: "#^Variable \\$next_payment_timestamp in empty\\(\\) always exists and is not falsy\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-request.php + + - + message: "#^Variable \\$second_trial_period might not be defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-request.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$total\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-switcher.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-standard-switcher.php + + - + message: "#^Call to method manage_recurring_payments_profile_status\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/class-wcs-paypal-status-manager.php + + - + message: "#^Binary operation \"\\.\\=\" between array and ' AND `meta_key` NOT…' results in an error\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/deprecated/class-wc-paypal-standard-subscriptions.php + + - + message: "#^Call to an undefined static method WCS_PayPal_Supports\\:\\:add_feature_support\\(\\)\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/deprecated/class-wc-paypal-standard-subscriptions.php + + - + message: "#^Call to method manage_recurring_payments_profile_status\\(\\) on an unknown class WCS_PayPal_Express_API\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/deprecated/class-wc-paypal-standard-subscriptions.php + + - + message: "#^Class WCS_PayPal_Standard_IPN_Handler referenced with incorrect case\\: WCS_Paypal_Standard_IPN_Handler\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/deprecated/class-wc-paypal-standard-subscriptions.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$item_name$#" + count: 1 + path: includes/core/gateways/paypal/includes/deprecated/class-wc-paypal-standard-subscriptions.php + + - + message: "#^Variable \\$notices might not be defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/templates/admin-notices.php + + - + message: "#^Variable \\$failed_ipn_log_handle might not be defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/templates/html-ipn-failure-notice.php + + - + message: "#^Variable \\$log_file_url might not be defined\\.$#" + count: 1 + path: includes/core/gateways/paypal/includes/templates/html-ipn-failure-notice.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Legacy\\:\\:\\$product_custom_fields\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Legacy\\:\\:\\$product_type\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Legacy\\:\\:\\$subscription_limit\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Legacy\\:\\:\\$subscription_one_time_shipping\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Legacy\\:\\:\\$subscription_payment_sync_date\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Variation_Legacy\\:\\:\\$parent_product_type\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Variation_Legacy\\:\\:\\$product_type\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Variation_Legacy\\:\\:\\$variation_id\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Variation_Legacy\\:\\:\\$variation_inherited_meta_data\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Subscription_Variation_Legacy\\:\\:\\$variation_level_meta_data\\.$#" + count: 3 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^Method WC_Product_Subscription_Variation\\:\\:__construct\\(\\) invoked with 2 parameters, 0\\-1 required\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$key$#" + count: 1 + path: includes/core/legacy/class-wc-product-subscription-variation-legacy.php + + - + message: "#^Access to an undefined property \\$this\\(WC_Product_Variable_Subscription_Legacy\\)\\:\\:\\$max_variation_price\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property \\$this\\(WC_Product_Variable_Subscription_Legacy\\)\\:\\:\\$min_variation_regular_price\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property \\$this\\(WC_Product_Variable_Subscription_Legacy\\)\\:\\:\\$subscription_length\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property \\$this\\(WC_Product_Variable_Subscription_Legacy\\)\\:\\:\\$subscription_sign_up_fee\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property \\$this\\(WC_Product_Variable_Subscription_Legacy\\)\\:\\:\\$subscription_trial_length\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property \\$this\\(WC_Product_Variable_Subscription_Legacy\\)\\:\\:\\$subscription_trial_period\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$max_variation_price\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$min_variation_price\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$min_variation_regular_price\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$parent_product_type\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$product_custom_fields\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_length\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_limit\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_one_time_shipping\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_payment_sync_date\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_sign_up_fee\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_trial_length\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Product_Variable_Subscription_Legacy\\:\\:\\$subscription_trial_period\\.$#" + count: 2 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Call to an undefined method WooCommerce\\:\\:clear_product_transients\\(\\)\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Method WC_Product_Variable_Subscription_Legacy\\:\\:get_price_hash\\(\\) invoked with 2 parameters, 0\\-1 required\\.$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^PHPDoc tag @param has invalid value \\(WC_Product\\)\\: Unexpected token \"\\\\n\\\\t \\* \", expected variable at offset 318$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$include_taxes$#" + count: 1 + path: includes/core/legacy/class-wc-product-variable-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_address_1\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_address_2\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_city\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_company\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_country\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_email\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_first_name\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_last_name\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_phone\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_postcode\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$billing_state\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$customer_note\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$order_key\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$payment_method\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$payment_method_title\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$post\\.$#" + count: 13 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$post_status\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$prices_include_tax\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_address_1\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_address_2\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_city\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_company\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_country\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_first_name\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_last_name\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_postcode\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Access to an undefined property WC_Subscription_Legacy\\:\\:\\$shipping_state\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Default value of the parameter \\#3 \\$meta_id \\(string\\) of method WC_Subscription_Legacy\\:\\:update_meta_data\\(\\) is incompatible with type int\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^Method WC_Subscription_Legacy\\:\\:set_last_order_date\\(\\) should return WC_DateTime\\|null but return statement is missing\\.$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^PHPDoc tag @param has invalid value \\(array\\|int Either an order item \\(in the array format returned by self\\:\\:get_items\\(\\)\\) or the ID of an order item\\.\\)\\: Unexpected token \"Either\", expected variable at offset 399$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^PHPDoc tag @param has invalid value \\(int\\)\\: Unexpected token \"\\\\n\\\\t \", expected variable at offset 61$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string\\)\\: Unexpected token \"\\\\n\\\\t \\* \", expected variable at offset 555$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string\\)\\: Unexpected token \"\\\\n\\\\t \\* \", expected variable at offset 573$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^PHPDoc tag @param has invalid value \\(string\\|integer\\|object\\)\\: Unexpected token \"\\\\n\\\\t \\* \", expected variable at offset 203$#" + count: 1 + path: includes/core/legacy/class-wc-subscription-legacy.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$product$#" + count: 1 + path: includes/core/legacy/class-wcs-array-property-post-meta-black-magic.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 3 + path: includes/core/privacy/class-wcs-privacy-background-updater.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 3 + path: includes/core/privacy/class-wcs-privacy-background-updater.php + + - + message: "#^Function as_unschedule_action not found\\.$#" + count: 2 + path: includes/core/privacy/class-wcs-privacy-background-updater.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_orders\\(\\)\\.$#" + count: 1 + path: includes/core/privacy/class-wcs-privacy-erasers.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_orders\\(\\)\\.$#" + count: 1 + path: includes/core/privacy/class-wcs-privacy-exporters.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_subscription_customer_ids\\(\\)\\.$#" + count: 1 + path: includes/core/privacy/class-wcs-privacy.php + + - + message: "#^Binary operation \"\\+\" between string and 120 results in an error\\.$#" + count: 1 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^Class WC_Logger referenced with incorrect case\\: WC_logger\\.$#" + count: 2 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^Constant WP_MAX_MEMORY_LIMIT not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^Function remove_action invoked with 4 parameters, 2\\-3 required\\.$#" + count: 1 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$limit$#" + count: 1 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^Variable \\$results might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^Variable \\$upgraded_versions might not be defined\\.$#" + count: 3 + path: includes/core/upgrades/class-wc-subscriptions-upgrader.php + + - + message: "#^Access to constant POST_TYPE on an unknown class ActionScheduler_wpPostStore\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-repair-2-0-2.php + + - + message: "#^Variable \\$matching_line_item_id might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-repair-2-0-2.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-repair-2-0.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$subscription_key$#" + count: 1 + path: includes/core/upgrades/class-wcs-repair-2-0.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_subtotal\\(\\)\\.$#" + count: 2 + path: includes/core/upgrades/class-wcs-repair-subtracted-base-tax-line-item-meta.php + + - + message: "#^Function wc_format_decimalw not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-1-2.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-1-5.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-1-5.php + + - + message: "#^Access to an undefined property object\\:\\:\\$meta_key\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Access to an undefined property object\\:\\:\\$meta_value\\.$#" + count: 2 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Access to an undefined property object\\:\\:\\$order_id\\.$#" + count: 2 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Access to an undefined property object\\:\\:\\$order_item_name\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Access to constant POST_TYPE on an unknown class ActionScheduler_wpPostStore\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 2 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Method WCS_Upgrade_2_0\\:\\:migrate_order_items\\(\\) should return null but return statement is missing\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Method WCS_Upgrade_2_0\\:\\:migrate_order_notes\\(\\) should return null but return statement is missing\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Method WCS_Upgrade_2_0\\:\\:migrate_post_meta\\(\\) should return null but return statement is missing\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Method WCS_Upgrade_2_0\\:\\:migrate_renewal_orders\\(\\) should return null but return statement is missing\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Method WCS_Upgrade_2_0\\:\\:migrate_resubscribe_orders\\(\\) should return null but return statement is missing\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$order$#" + count: 3 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$original_order$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^PHPDoc tag @param references unknown parameter\\: \\$subscription_id$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Variable \\$dates_to_update in empty\\(\\) always exists and is not falsy\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-0.php + + - + message: "#^Binary operation \"\\+\" between string and 180 results in an error\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-2-7.php + + - + message: "#^Callback expects 1 parameter, \\$accepted_args is set to 2\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-2-7.php + + - + message: "#^Function as_next_scheduled_action not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-2-7.php + + - + message: "#^Function as_schedule_single_action not found\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-2-7.php + + - + message: "#^Binary operation \"\\+\" between string and 180 results in an error\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-2-2-9.php + + - + message: "#^Call to an undefined method WC_Logger_Interface\\:\\:clear\\(\\)\\.$#" + count: 1 + path: includes/core/upgrades/class-wcs-upgrade-logger.php + + - + message: "#^Variable \\$features might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/templates/update-welcome-notice.php + + - + message: "#^Variable \\$version might not be defined\\.$#" + count: 2 + path: includes/core/upgrades/templates/update-welcome-notice.php + + - + message: "#^Function esc_html invoked with 2 parameters, 1 required\\.$#" + count: 1 + path: includes/core/upgrades/templates/wcs-about-2-0.php + + - + message: "#^Variable \\$active_version might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/templates/wcs-about-2-0.php + + - + message: "#^Variable \\$active_version might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/templates/wcs-about.php + + - + message: "#^Variable \\$settings_page might not be defined\\.$#" + count: 4 + path: includes/core/upgrades/templates/wcs-about.php + + - + message: "#^Variable \\$about_page_url might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/templates/wcs-upgrade.php + + - + message: "#^Variable \\$estimated_duration might not be defined\\.$#" + count: 2 + path: includes/core/upgrades/templates/wcs-upgrade.php + + - + message: "#^Variable \\$script_data might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/templates/wcs-upgrade.php + + - + message: "#^Variable \\$subscription_count might not be defined\\.$#" + count: 1 + path: includes/core/upgrades/templates/wcs-upgrade.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$display_cart_ex_tax\\.$#" + count: 1 + path: includes/core/wcs-cart-functions.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 2 + path: includes/core/wcs-cart-functions.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$tax_display_cart\\.$#" + count: 2 + path: includes/core/wcs-cart-functions.php + + - + message: "#^Access to an undefined property WC_Shipping_Rate\\:\\:\\$cost\\.$#" + count: 1 + path: includes/core/wcs-cart-functions.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$shipping\\.$#" + count: 2 + path: includes/core/wcs-cart-functions.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 2 + path: includes/core/wcs-functions.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_subscriptions_count_by_status\\(\\)\\.$#" + count: 1 + path: includes/core/wcs-functions.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:search_subscriptions\\(\\)\\.$#" + count: 1 + path: includes/core/wcs-functions.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product\\(\\)\\.$#" + count: 1 + path: includes/core/wcs-functions.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_product_id\\(\\)\\.$#" + count: 3 + path: includes/core/wcs-functions.php + + - + message: "#^Call to an undefined method WC_Order_Item\\:\\:get_variation_id\\(\\)\\.$#" + count: 4 + path: includes/core/wcs-functions.php + + - + message: "#^Binary operation \"/\" between int and 0\\|86400\\|604800\\|31536000 results in an error\\.$#" + count: 2 + path: includes/core/wcs-time-functions.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 1 + path: includes/gateways/class-wc-subscriptions-payment-gateways.php + + - + message: "#^Access to an undefined property WC_Subscription\\:\\:\\$recipient_user\\.$#" + count: 2 + path: includes/gifting/class-wcs-gifting.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 1 + path: includes/gifting/class-wcsg-admin.php + + - + message: "#^Constant WC_PLUGIN_FILE not found\\.$#" + count: 1 + path: includes/gifting/class-wcsg-admin.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_downloads\\(\\)\\.$#" + count: 1 + path: includes/gifting/class-wcsg-download-handler.php + + - + message: "#^Constant WC_PLUGIN_FILE not found\\.$#" + count: 1 + path: includes/gifting/class-wcsg-download-handler.php + + - + message: "#^Function wc_memberships not found\\.$#" + count: 3 + path: includes/gifting/class-wcsg-memberships-integration.php + + - + message: "#^Function wc_memberships_get_membership_plans not found\\.$#" + count: 1 + path: includes/gifting/class-wcsg-memberships-integration.php + + - + message: "#^Parameter \\$membership_plan of method WCSG_Memberships_Integration\\:\\:update_subscription_id\\(\\) has invalid type WC_Memberships_Membership_Plan\\.$#" + count: 1 + path: includes/gifting/class-wcsg-memberships-integration.php + + - + message: "#^Parameter \\$plan of method WCSG_Memberships_Integration\\:\\:get_user_unique_membership_access_granting_product_ids\\(\\) has invalid type WC_Memberships_Membership_Plan\\.$#" + count: 1 + path: includes/gifting/class-wcsg-memberships-integration.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 1 + path: includes/gifting/class-wcsg-recipient-management.php + + - + message: "#^Cannot access property \\$order_date on bool\\|object\\.$#" + count: 1 + path: includes/gifting/emails/class-wcsg-email-completed-renewal-order.php + + - + message: "#^Cannot call method get_billing_first_name\\(\\) on bool\\|object\\.$#" + count: 1 + path: includes/gifting/emails/class-wcsg-email-customer-new-account.php + + - + message: "#^Cannot call method get_billing_last_name\\(\\) on bool\\|object\\.$#" + count: 1 + path: includes/gifting/emails/class-wcsg-email-customer-new-account.php + + - + message: "#^Cannot access property \\$order_date on bool\\|object\\.$#" + count: 1 + path: includes/gifting/emails/class-wcsg-email-processing-renewal-order.php + + - + message: "#^Call to an undefined method WP_Post\\:\\:get_user_id\\(\\)\\.$#" + count: 1 + path: includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php + + - + message: "#^Call to an undefined method WC_Data_Store\\:\\:get_order_type\\(\\)\\.$#" + count: 1 + path: includes/payment-retry/class-wcs-retry-manager.php + + - + message: "#^Call to an undefined method WCS_Retry_Store\\:\\:get_full_table_name\\(\\)\\.$#" + count: 1 + path: includes/payment-retry/class-wcs-retry-migrator.php + + - + message: "#^Call to an undefined method WCS_Retry_Store\\:\\:get_table_name\\(\\)\\.$#" + count: 2 + path: includes/payment-retry/class-wcs-retry-table-maker.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 4 + path: includes/switching/class-wc-subscriptions-switcher.php + + - + message: "#^Access to an undefined property WC_Cart\\:\\:\\$recurring_carts\\.$#" + count: 1 + path: includes/switching/class-wcs-cart-switch.php + + - + message: "#^Call to static method is_true\\(\\) on an unknown class Automattic\\\\Jetpack\\\\Constants\\.$#" + count: 1 + path: src/Internal/Telemetry/Collector.php + + - + message: "#^Access to an undefined property object\\:\\:\\$count\\.$#" + count: 2 + path: src/Internal/Telemetry/Products.php + + - + message: "#^Function as_has_scheduled_action not found\\.$#" + count: 1 + path: src/Internal/Utilities/Scheduled_Actions.php + + - + message: "#^Function as_schedule_recurring_action not found\\.$#" + count: 1 + path: src/Internal/Utilities/Scheduled_Actions.php + + - + message: "#^Call to an undefined method WP_Post\\:\\:get_id\\(\\)\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-price.php + + - + message: "#^Call to an undefined method WP_Post\\:\\:get_meta\\(\\)\\.$#" + count: 5 + path: templates/admin/deprecated/html-variation-price.php + + - + message: "#^Calling self\\:\\:get_trial_period_validation_message\\(\\) outside of class scope\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-price.php + + - + message: "#^Class WP_Post referenced with incorrect case\\: WP_POST\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-price.php + + - + message: "#^Class WP_Post referenced with incorrect case\\: WP_POST\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-synchronisation.php + + - + message: "#^Variable \\$display_annual_select might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-synchronisation.php + + - + message: "#^Variable \\$display_week_month_select might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-synchronisation.php + + - + message: "#^Variable \\$payment_day might not be defined\\.$#" + count: 2 + path: templates/admin/deprecated/html-variation-synchronisation.php + + - + message: "#^Variable \\$payment_month might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/html-variation-synchronisation.php + + - + message: "#^Variable \\$chosen_method might not be defined\\.$#" + count: 4 + path: templates/admin/deprecated/order-shipping-html.php + + - + message: "#^Variable \\$item_id might not be defined\\.$#" + count: 2 + path: templates/admin/deprecated/order-shipping-html.php + + - + message: "#^Variable \\$shipping_cost might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/order-shipping-html.php + + - + message: "#^Variable \\$shipping_methods might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/order-shipping-html.php + + - + message: "#^Variable \\$shipping_title might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/order-shipping-html.php + + - + message: "#^Variable \\$item_id might not be defined\\.$#" + count: 6 + path: templates/admin/deprecated/order-tax-html.php + + - + message: "#^Variable \\$tax_codes might not be defined\\.$#" + count: 1 + path: templates/admin/deprecated/order-tax-html.php + + - + message: "#^Calling self\\:\\:get_trial_period_validation_message\\(\\) outside of class scope\\.$#" + count: 1 + path: templates/admin/html-variation-price.php + + - + message: "#^Class WP_Post referenced with incorrect case\\: WP_POST\\.$#" + count: 1 + path: templates/admin/html-variation-price.php + + - + message: "#^Class WP_Post referenced with incorrect case\\: WP_POST\\.$#" + count: 1 + path: templates/admin/html-variation-synchronisation.php + + - + message: "#^Variable \\$display_annual_select might not be defined\\.$#" + count: 1 + path: templates/admin/html-variation-synchronisation.php + + - + message: "#^Variable \\$display_week_month_select might not be defined\\.$#" + count: 1 + path: templates/admin/html-variation-synchronisation.php + + - + message: "#^Variable \\$payment_day might not be defined\\.$#" + count: 2 + path: templates/admin/html-variation-synchronisation.php + + - + message: "#^Variable \\$payment_month might not be defined\\.$#" + count: 2 + path: templates/admin/html-variation-synchronisation.php + + - + message: "#^Variable \\$section_title might not be defined\\.$#" + count: 2 + path: templates/admin/status.php + + - + message: "#^Variable \\$section_tooltip might not be defined\\.$#" + count: 1 + path: templates/admin/status.php + + - + message: "#^Variable \\$available_methods might not be defined\\.$#" + count: 2 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$chosen_method might not be defined\\.$#" + count: 1 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$index might not be defined\\.$#" + count: 3 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$package_details might not be defined\\.$#" + count: 1 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$package_name might not be defined\\.$#" + count: 2 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$recurring_cart might not be defined\\.$#" + count: 1 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$recurring_cart_key might not be defined\\.$#" + count: 2 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Variable \\$show_package_details might not be defined\\.$#" + count: 1 + path: templates/cart/cart-recurring-shipping.php + + - + message: "#^Access to an undefined property WooCommerce\\:\\:\\$payment_gateways\\.$#" + count: 1 + path: templates/checkout/form-change-payment-method.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 7 + path: templates/checkout/form-change-payment-method.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 1 + path: templates/checkout/recurring-coupon-totals.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 1 + path: templates/checkout/recurring-fee-totals.php + + - + message: "#^Access to an undefined property object\\:\\:\\$formatted_amount\\.$#" + count: 1 + path: templates/checkout/recurring-itemized-tax-totals.php + + - + message: "#^Access to an undefined property object\\:\\:\\$label\\.$#" + count: 2 + path: templates/checkout/recurring-itemized-tax-totals.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 1 + path: templates/checkout/recurring-itemized-tax-totals.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 1 + path: templates/checkout/recurring-subscription-totals.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 1 + path: templates/checkout/recurring-subtotals.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 1 + path: templates/checkout/recurring-tax-totals.php + + - + message: "#^Variable \\$recurring_carts might not be defined\\.$#" + count: 6 + path: templates/checkout/recurring-totals.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 7 + path: templates/checkout/subscription-receipt.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/admin-new-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 5 + path: templates/emails/admin-new-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/admin-new-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/admin-new-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/admin-new-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/admin-new-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 6 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 5 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 2 + path: templates/emails/admin-new-switch-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 5 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 5 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$retry might not be defined\\.$#" + count: 1 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/admin-payment-retry.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/cancelled-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/emails/cancelled-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/cancelled-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/cancelled-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/cancelled-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 11 + path: templates/emails/cancelled-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-completed-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 5 + path: templates/emails/customer-completed-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-completed-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/customer-completed-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/customer-completed-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/customer-completed-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 6 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 1 + path: templates/emails/customer-completed-switch-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 4 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 4 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$can_renew_early might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$url_for_renewal might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 5 + path: templates/emails/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 3 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 1 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$retry might not be defined\\.$#" + count: 1 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 1 + path: templates/emails/customer-payment-retry.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-processing-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 5 + path: templates/emails/customer-processing-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-processing-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 5 + path: templates/emails/customer-processing-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/customer-processing-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/customer-processing-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/customer-renewal-invoice.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/customer-renewal-invoice.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/customer-renewal-invoice.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 6 + path: templates/emails/customer-renewal-invoice.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 1 + path: templates/emails/customer-renewal-invoice.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 1 + path: templates/emails/customer-renewal-invoice.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/email-order-details.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 12 + path: templates/emails/email-order-details.php + + - + message: "#^Variable \\$order_items_table_args might not be defined\\.$#" + count: 1 + path: templates/emails/email-order-details.php + + - + message: "#^Variable \\$order_type might not be defined\\.$#" + count: 3 + path: templates/emails/email-order-details.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/email-order-details.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/email-order-details.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/expired-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/emails/expired-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/expired-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/expired-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/expired-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 8 + path: templates/emails/expired-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/on-hold-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/emails/on-hold-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/on-hold-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/on-hold-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/on-hold-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 7 + path: templates/emails/on-hold-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-new-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/admin-new-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-new-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/plain/admin-new-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/admin-new-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/admin-new-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 2 + path: templates/emails/plain/admin-new-switch-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 5 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$retry might not be defined\\.$#" + count: 1 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/admin-payment-retry.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/cancelled-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/cancelled-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/cancelled-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/cancelled-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/cancelled-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 7 + path: templates/emails/plain/cancelled-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-completed-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-completed-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-completed-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/plain/customer-completed-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-completed-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-completed-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 5 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-completed-switch-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-renewal.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-auto-trial-ending.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-expiring-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$can_renew_early might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$url_for_renewal might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-manual-renewal.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$subscription_event_date might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$subscription_time_til_event might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-notification-manual-trial-ending.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/emails/plain/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-on-hold-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$retry might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-payment-retry.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-processing-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-processing-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-processing-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 5 + path: templates/emails/plain/customer-processing-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-processing-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/customer-processing-renewal-order.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-renewal-invoice.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-renewal-invoice.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-renewal-invoice.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 6 + path: templates/emails/plain/customer-renewal-invoice.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-renewal-invoice.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 1 + path: templates/emails/plain/customer-renewal-invoice.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 2 + path: templates/emails/plain/email-order-details.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 7 + path: templates/emails/plain/email-order-details.php + + - + message: "#^Variable \\$order_items_table_args might not be defined\\.$#" + count: 1 + path: templates/emails/plain/email-order-details.php + + - + message: "#^Variable \\$order_type might not be defined\\.$#" + count: 3 + path: templates/emails/plain/email-order-details.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/emails/plain/email-order-details.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/emails/plain/email-order-details.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/expired-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/expired-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/expired-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/expired-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/expired-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 7 + path: templates/emails/plain/expired-subscription.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/emails/plain/on-hold-subscription.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 3 + path: templates/emails/plain/on-hold-subscription.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/emails/plain/on-hold-subscription.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 3 + path: templates/emails/plain/on-hold-subscription.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 3 + path: templates/emails/plain/on-hold-subscription.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 6 + path: templates/emails/plain/on-hold-subscription.php + + - + message: "#^Variable \\$is_admin_email might not be defined\\.$#" + count: 2 + path: templates/emails/plain/subscription-info.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/plain/subscription-info.php + + - + message: "#^Variable \\$skip_my_account_link might not be defined\\.$#" + count: 1 + path: templates/emails/plain/subscription-info.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 1 + path: templates/emails/plain/subscription-info.php + + - + message: "#^Variable \\$is_admin_email might not be defined\\.$#" + count: 2 + path: templates/emails/subscription-info.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/emails/subscription-info.php + + - + message: "#^Variable \\$skip_my_account_link might not be defined\\.$#" + count: 1 + path: templates/emails/subscription-info.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 1 + path: templates/emails/subscription-info.php + + - + message: "#^Variable \\$section_title might not be defined\\.$#" + count: 2 + path: templates/gifting/admin/status.php + + - + message: "#^Variable \\$section_tooltip might not be defined\\.$#" + count: 1 + path: templates/gifting/admin/status.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$blogname might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$reset_key might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$subscription_purchaser might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$user_id might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$user_login might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/new-recipient-customer.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$blogname might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$reset_key might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$subscription_purchaser might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$user_id might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$user_login might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/new-recipient-customer.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-email-address-table.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-order-details.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-order-details.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-email-order-details.php + + - + message: "#^Variable \\$title might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-order-details.php + + - + message: "#^Variable \\$items might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-order-items.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-email-order-items.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-email-order-items.php + + - + message: "#^Variable \\$show_purchase_note might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-order-items.php + + - + message: "#^Variable \\$show_sku might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-order-items.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-email-subscriptions-table.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$blogname might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$recipient_user might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$subscription_purchaser might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-new-initial-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/plain/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/plain/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 6 + path: templates/gifting/emails/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-completed-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/recipient-email-address-table.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-details.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-details.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/recipient-email-order-details.php + + - + message: "#^Variable \\$title might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-details.php + + - + message: "#^Variable \\$image_size might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$items might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 3 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$show_image might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$show_purchase_note might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$show_sku might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-order-items.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-email-subscriptions-table.php + + - + message: "#^Variable \\$additional_content might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$blogname might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 2 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$subscription_purchaser might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-new-initial-order.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 6 + path: templates/gifting/emails/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$email_heading might not be defined\\.$#" + count: 1 + path: templates/gifting/emails/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$plain_text might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$sent_to_admin might not be defined\\.$#" + count: 4 + path: templates/gifting/emails/recipient-processing-renewal-order.php + + - + message: "#^Variable \\$checkbox_field_args might not be defined\\.$#" + count: 4 + path: templates/gifting/html-add-recipient.php + + - + message: "#^Variable \\$container_css_class might not be defined\\.$#" + count: 1 + path: templates/gifting/html-add-recipient.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 2 + path: templates/gifting/html-add-recipient.php + + - + message: "#^Variable \\$email_field_args might not be defined\\.$#" + count: 3 + path: templates/gifting/html-add-recipient.php + + - + message: "#^Variable \\$id might not be defined\\.$#" + count: 4 + path: templates/gifting/html-add-recipient.php + + - + message: "#^Variable \\$nonce_field might not be defined\\.$#" + count: 1 + path: templates/gifting/html-add-recipient.php + + - + message: "#^Variable \\$email might not be defined\\.$#" + count: 1 + path: templates/gifting/html-flat-gifting-recipient-details.php + + - + message: "#^Variable \\$name might not be defined\\.$#" + count: 1 + path: templates/gifting/html-view-subscription-gifting-information.php + + - + message: "#^Variable \\$user_title might not be defined\\.$#" + count: 2 + path: templates/gifting/html-view-subscription-gifting-information.php + + - + message: "#^Variable \\$order might not be defined\\.$#" + count: 3 + path: templates/gifting/order-details-customer.php + + - + message: "#^Cannot access property \\$order_date on bool\\|WC_Order\\|WC_Order_Refund\\.$#" + count: 1 + path: templates/gifting/related-orders.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 2 + path: templates/gifting/related-orders.php + + - + message: "#^Variable \\$subscription_orders might not be defined\\.$#" + count: 1 + path: templates/gifting/related-orders.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 10 + path: templates/gifting/subscription-totals.php + + - + message: "#^Variable \\$current_page might not be defined\\.$#" + count: 2 + path: templates/myaccount/my-subscriptions.php + + - + message: "#^Variable \\$max_num_pages might not be defined\\.$#" + count: 1 + path: templates/myaccount/my-subscriptions.php + + - + message: "#^Variable \\$order_id might not be defined\\.$#" + count: 1 + path: templates/myaccount/related-subscriptions.php + + - + message: "#^Variable \\$subscriptions might not be defined\\.$#" + count: 1 + path: templates/myaccount/related-subscriptions.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 16 + path: templates/myaccount/subscription-details.php + + - + message: "#^Variable \\$allow_item_removal might not be defined\\.$#" + count: 1 + path: templates/myaccount/subscription-totals-table.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 10 + path: templates/myaccount/subscription-totals-table.php + + - + message: "#^Variable \\$totals might not be defined\\.$#" + count: 1 + path: templates/myaccount/subscription-totals-table.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 3 + path: templates/myaccount/subscription-totals.php + + - + message: "#^Variable \\$current_page might not be defined\\.$#" + count: 1 + path: templates/myaccount/subscriptions.php + + - + message: "#^Variable \\$subscription might not be defined\\.$#" + count: 4 + path: templates/myaccount/view-subscription.php + + - + message: "#^Variable \\$attributes might not be defined\\.$#" + count: 2 + path: templates/single-product/add-to-cart/variable-subscription.php + + - + message: "#^Variable \\$available_variations might not be defined\\.$#" + count: 1 + path: templates/single-product/add-to-cart/variable-subscription.php diff --git a/src/Internal/README.md b/src/Internal/README.md new file mode 100644 index 0000000..c9e7d22 --- /dev/null +++ b/src/Internal/README.md @@ -0,0 +1,6 @@ +# The internal namespace + +- All the code in this directory (and hence in the `Automattic\WooCommerce_Subscriptions\Internal` namespace) is internal WooCommerce Subscriptions infrastructure code. +- Our internal code can change at any time (there are zero guarantees of backwards compatibility), and so the classes and methods you see here should be avoided by extension developers. +- This guidance applies to all the code entities in this namespace, even those not having an `@internal` annotation. + diff --git a/src/Internal/Telemetry/Collector.php b/src/Internal/Telemetry/Collector.php new file mode 100644 index 0000000..cd11952 --- /dev/null +++ b/src/Internal/Telemetry/Collector.php @@ -0,0 +1,99 @@ +collect_telemetry_data(); + $telemetry['telemetry_cache'] = 'miss'; + } else { + $telemetry['telemetry_cache'] = 'hit'; + } + + return $telemetry; + } + + /** + * Captures the results of various telemetry queries, and stores them in the database (via the Options API). + * + * @return array + */ + public function collect_telemetry_data(): array { + $orders = new Orders(); + $products = new Products(); + $subscriptions = new Subscriptions(); + $start_timer = microtime( true ); + + $telemetry = array( + 'order_trends' => array( + 'by_order_type' => $orders->get_aggregated_monthly_order_data( time() - YEAR_IN_SECONDS, time() ), + 'by_payment_gateway' => $orders->get_aggregated_monthly_order_data_by_payment_gateway( time() - YEAR_IN_SECONDS, time() ), + ), + 'products' => array( + 'frequencies' => $products->get_product_frequencies(), + 'giftable' => $products->get_active_giftable_products_count(), + ), + 'subscriptions' => array( + 'gifted' => $subscriptions->get_gifted_subscriptions_count(), + 'payment_methods' => $subscriptions->get_subscriptions_by_payment_method(), + 'renewal_frequencies' => $subscriptions->get_subscriptions_by_frequency(), + 'renewing_automatically' => $subscriptions->get_active_subscriptions_renewing_automatically(), + 'renewing_manually' => $subscriptions->get_active_subscriptions_renewing_manually(), + 'subscriber_count' => $subscriptions->get_subscriber_count(), + ), + ); + + $telemetry['generation_timestamp'] = time(); + $telemetry['total_generation_time'] = ( microtime( true ) - $start_timer ) * 1_000; + set_transient( self::TRANSIENT_KEY, $telemetry, self::TRANSIENT_LIFESPAN ); + + return $telemetry; + } +} diff --git a/src/Internal/Telemetry/Events.php b/src/Internal/Telemetry/Events.php new file mode 100644 index 0000000..3def395 --- /dev/null +++ b/src/Internal/Telemetry/Events.php @@ -0,0 +1,45 @@ +event_recorder = $event_recorder ?? function ( string $event_name, array $event_properties = array() ) { + // Note that the following method ensures nothing is sent home unless tracking is enabled. + WC_Tracks::record_event( $event_name, $event_properties ); + }; + } + + /** + * Adds listeners for events where we want to send a corresponding Tracks event. + * + * @return void + */ + public function setup(): void { + add_action( 'woocommerce_new_subscription', array( $this, 'track_new_subscriptions' ) ); + } + + /** + * Record the creation of a new subscription. + * + * @return void + */ + public function track_new_subscriptions(): void { + call_user_func( $this->event_recorder, 'wcs_new_subscription_created' ); + } +} diff --git a/src/Internal/Telemetry/Orders.php b/src/Internal/Telemetry/Orders.php new file mode 100644 index 0000000..f07f748 --- /dev/null +++ b/src/Internal/Telemetry/Orders.php @@ -0,0 +1,1012 @@ +active_order_statuses_clause = "'wc-completed', 'wc-refunded'"; + + $this->is_hpos = wcs_is_custom_order_tables_usage_enabled(); + $this->wc_orders_table = $wpdb->prefix . 'wc_orders'; + $this->wc_orders_meta_table = $wpdb->prefix . 'wc_orders_meta'; + } + + /** + * Gets order counts and GMV (gross) by payment gateway, segmented by monthly data. + * + * Returns aggregated metrics (count, gross) for all subscription-related orders, + * grouped by payment gateway and segmented by month. + * + * @param int $start_timestamp Start timestamp. Will be normalized to the beginning of the month in UTC. + * @param int $end_timestamp End timestamp. Will be normalized to the end of the month in UTC. + * + * @return array Associative array with structure: + * [ + * 'stripe' => [ + * ['month' => '2024-01', 'count' => 45, 'gross' => 3750.25], + * ['month' => '2024-02', 'count' => 50, 'gross' => 4000.00], + * ], + * 'paypal' => [ + * ['month' => '2024-01', 'count' => 30, 'gross' => 2500.00], + * ], + * ] + */ + public function get_aggregated_monthly_order_data_by_payment_gateway( int $start_timestamp, int $end_timestamp ): array { + // Normalize timestamps to full month boundaries in UTC + [ 'start' => $start, 'end' => $end ] = $this->normalize_timestamp_range_to_month_boundaries( $start_timestamp, $end_timestamp ); + + $results = $this->is_hpos + ? $this->get_hpos_monthly_order_data_by_payment_gateway( $start, $end ) + : $this->get_cpt_monthly_order_data_by_payment_gateway( $start, $end ); + + return $this->format_monthly_order_data_by_payment_gateway( $results ); + } + + /** + * Get monthly order metrics segmented by order type within a date range. + * + * Returns aggregated metrics (count, gross, non_zero_count, quantity) for all subscription-related orders, + * segmented by order type (initial/renewal/switch/resubscribe) and month. + * + * @param int $start_timestamp Start timestamp for date filtering. + * @param int $end_timestamp End timestamp for date filtering. + * + * @return array Associative array with structure: + * [ + * 'store_gross' => [ + * ['month' => '2025-01', 'gross' => 1250.50], + * ['month' => '2025-02', 'gross' => 1500.75], + * ], + * 'initial' => [ + * ['month' => '2025-01', 'count' => 15, 'gross' => 750.00, 'non_zero_count' => 12, 'quantity' => 20, 'non_zero_quantity' => 18], + * ['month' => '2025-02', 'count' => 18, 'gross' => 900.00, 'non_zero_count' => 15, 'quantity' => 24, 'non_zero_quantity' => 22], + * ], + * 'renewal' => [ + * ['month' => '2025-01', 'count' => 10, 'gross' => 500.00, 'non_zero_count' => 8], + * ['month' => '2025-02', 'count' => 12, 'gross' => 600.00, 'non_zero_count' => 10], + * ], + * 'switch' => [ + * ['month' => '2025-01', 'count' => 5, 'gross' => 250.00, 'non_zero_count' => 4], + * ], + * 'resubscribe' => [ + * ['month' => '2025-01', 'count' => 2, 'gross' => 100.00, 'non_zero_count' => 2], + * ], + * ] + */ + public function get_aggregated_monthly_order_data( int $start_timestamp, int $end_timestamp ): array { + // Normalize timestamps to full month boundaries in UTC + [ 'start' => $start, 'end' => $end ] = $this->normalize_timestamp_range_to_month_boundaries( $start_timestamp, $end_timestamp ); + + // Get renewal, switch, and resubscribe order data. + $related_orders_data = $this->aggregate_monthly_order_data_by_type( $start, $end ); + + $orders_data = array( + 'store_gross' => $this->aggregate_monthly_store_gmv( $start, $end ), + 'initial' => $this->aggregate_monthly_parent_order_data( $start, $end ), + 'renewal' => $related_orders_data['renewal'], + 'switch' => $related_orders_data['switch'], + 'resubscribe' => $related_orders_data['resubscribe'], + ); + + return $orders_data; + } + + /** + * HPOS implementation of get_aggregated_monthly_order_data_by_payment_gateway(). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array Array of database result objects with payment_method, month, count, and gross columns. + */ + private function get_hpos_monthly_order_data_by_payment_gateway( string $start_date, string $end_date ): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + -- Group by payment method (null becomes empty string) + COALESCE(orders.payment_method, '') as payment_method, + + -- Group by month (first day of each month) + DATE_FORMAT(orders.date_created_gmt, '%%Y-%%m') as month, + + -- Overall totals + COUNT(*) as count, + SUM(orders.total_amount) as gross + + FROM %i AS orders + WHERE orders.type = 'shop_order' + + -- Only include successful order statuses (excludes on-hold, pending, failed, etc.) + AND orders.status IN ( $this->active_order_statuses_clause ) + + -- Date range filter (last 12 months) + AND orders.date_created_gmt >= %s + AND orders.date_created_gmt < %s + + -- Only include orders related to subscriptions + AND ( + -- Parent orders (orders that created subscriptions) + orders.id IN ( + SELECT DISTINCT parent_order_id + FROM %i AS subscriptions + WHERE subscriptions.type = 'shop_subscription' + AND subscriptions.parent_order_id IS NOT NULL + AND subscriptions.parent_order_id <> 0 + ) + -- Renewal orders (recurring subscription payments) + OR EXISTS ( + SELECT 1 FROM %i AS renewal_meta + WHERE renewal_meta.order_id = orders.id + AND renewal_meta.meta_key = '_subscription_renewal' + ) + -- Switch orders (subscription plan/product changes) + OR EXISTS ( + SELECT 1 FROM %i AS switch_meta + WHERE switch_meta.order_id = orders.id + AND switch_meta.meta_key = '_subscription_switch' + ) + -- Resubscribe orders (reactivated cancelled subscriptions) + OR EXISTS ( + SELECT 1 FROM %i AS resubscribe_meta + WHERE resubscribe_meta.order_id = orders.id + AND resubscribe_meta.meta_key = '_subscription_resubscribe' + ) + ) + + -- Group by payment method and month + GROUP BY COALESCE(orders.payment_method, ''), YEAR(orders.date_created_gmt), MONTH(orders.date_created_gmt) + + -- Sort by payment method, then by month + ORDER BY payment_method ASC, month ASC + ", + $this->wc_orders_table, // main FROM table + $start_date, + $end_date, + $this->wc_orders_table, // WHERE parent orders subquery + $this->wc_orders_meta_table, // WHERE renewal orders subquery + $this->wc_orders_meta_table, // WHERE switch orders subquery + $this->wc_orders_meta_table // WHERE resubscribe orders subquery + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * CPT implementation of get_aggregated_monthly_order_data_by_payment_gateway(). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array Array of database result objects with payment_method, month, count, and gross columns. + */ + private function get_cpt_monthly_order_data_by_payment_gateway( string $start_date, string $end_date ): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + -- Group by payment method (null becomes empty string) + COALESCE(payment_meta.meta_value, '') as payment_method, + + -- Group by month (first day of each month) + DATE_FORMAT(orders.post_date_gmt, '%%Y-%%m') as month, + + -- Overall totals + COUNT(*) as count, + SUM(total_meta.meta_value) as gross + + FROM %i AS orders + -- Join payment method from order meta + LEFT JOIN %i AS payment_meta ON ( + orders.ID = payment_meta.post_id + AND payment_meta.meta_key = '_payment_method' + ) + + -- Join order total from order meta + LEFT JOIN %i AS total_meta ON ( + orders.ID = total_meta.post_id + AND total_meta.meta_key = '_order_total' + ) + WHERE orders.post_type = 'shop_order' + + -- Only include successful order statuses (excludes on-hold, pending, failed, etc.) + AND orders.post_status IN ( $this->active_order_statuses_clause ) + + -- Date range filter (last 12 months) + AND orders.post_date_gmt >= %s + AND orders.post_date_gmt < %s + + -- Only include orders related to subscriptions + AND ( + -- Parent orders (orders that created subscriptions) + orders.ID IN ( + SELECT DISTINCT post_parent + FROM %i AS subscriptions + WHERE subscriptions.post_type = 'shop_subscription' + AND subscriptions.post_parent IS NOT NULL + AND subscriptions.post_parent <> 0 + ) + -- Renewal orders (recurring subscription payments) + OR EXISTS ( + SELECT 1 FROM %i AS renewal_meta + WHERE renewal_meta.post_id = orders.ID + AND renewal_meta.meta_key = '_subscription_renewal' + ) + -- Switch orders (subscription plan/product changes) + OR EXISTS ( + SELECT 1 FROM %i AS switch_meta + WHERE switch_meta.post_id = orders.ID + AND switch_meta.meta_key = '_subscription_switch' + ) + -- Resubscribe orders (reactivated cancelled subscriptions) + OR EXISTS ( + SELECT 1 FROM %i AS resubscribe_meta + WHERE resubscribe_meta.post_id = orders.ID + AND resubscribe_meta.meta_key = '_subscription_resubscribe' + ) + ) + + -- Group by payment method and month + GROUP BY COALESCE(payment_meta.meta_value, ''), YEAR(orders.post_date_gmt), MONTH(orders.post_date_gmt) + + -- Sort by payment method, then by month + ORDER BY payment_method ASC, month ASC + ", + $wpdb->posts, // main FROM table + $wpdb->postmeta, // LEFT JOIN payment_meta + $wpdb->postmeta, // LEFT JOIN total_meta + $start_date, + $end_date, + $wpdb->posts, // WHERE parent orders subquery + $wpdb->postmeta, // WHERE renewal orders subquery + $wpdb->postmeta, // WHERE switch orders subquery + $wpdb->postmeta // WHERE resubscribe orders subquery + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Aggregates order data for all related order types (renewal, switch, resubscribe), segmented by month. + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array Nested array grouped by order type, with monthly data as flat arrays. Structure: + * [ + * 'renewal' => [ + * ['month' => '2025-01', 'count' => 10, 'gross' => 500.00, 'non_zero_count' => 8], + * ['month' => '2025-02', 'count' => 12, 'gross' => 600.00, 'non_zero_count' => 10], + * ], + * 'switch' => [ + * ['month' => '2025-01', 'count' => 5, 'gross' => 250.00, 'non_zero_count' => 4], + * ], + * 'resubscribe' => [ + * ['month' => '2025-01', 'count' => 2, 'gross' => 100.00, 'non_zero_count' => 2], + * ], + * ] + */ + private function aggregate_monthly_order_data_by_type( string $start_date, string $end_date ): array { + $results = $this->is_hpos + ? $this->get_hpos_aggregate_monthly_order_data_by_type( $start_date, $end_date ) + : $this->get_cpt_aggregate_monthly_order_data_by_type( $start_date, $end_date ); + + return $this->format_monthly_order_data_by_type( $results ); + } + + /** + * Formats database results into the structure (payment_gateway => [month, metrics]). + * + * Transforms raw SQL results into a nested array structure where the first level + * is grouped by payment gateway, and each payment gateway contains a flat array of monthly data. + * + * @param array $results Database result objects from get_hpos_monthly_order_data_by_payment_gateway() or get_cpt_monthly_order_data_by_payment_gateway(). + * + * @return array Formatted array with structure: + * [ + * 'stripe' => [ + * ['month' => '2024-01', 'count' => 45, 'gross' => 3750.25], + * ['month' => '2024-02', 'count' => 50, 'gross' => 4000.00], + * ], + * 'paypal' => [ + * ['month' => '2024-01', 'count' => 30, 'gross' => 2500.00], + * ], + * ] + */ + private function format_monthly_order_data_by_payment_gateway( array $results ): array { + $data = array(); + + // Handle empty or null results - return empty array + if ( empty( $results ) ) { + return $data; + } + + foreach ( $results as $result ) { + $payment_method = $result->payment_method ?? ''; + + // Initialize array for this payment method if it doesn't exist + if ( ! isset( $data[ $payment_method ] ) ) { + $data[ $payment_method ] = array(); + } + + // Add monthly data to this payment method's array + $data[ $payment_method ][] = array( + 'month' => $result->month, + 'count' => (int) $result->count, + 'gross' => round( (float) $result->gross, 2 ), + ); + } + + return $data; + } + + /** + * Formats database results into the structure (order_type => [month, metrics]). + * + * Transforms raw SQL results into a nested array structure where the first level + * is grouped by order type, and each order type contains a flat array of monthly data. + * + * @param array $results Database result objects from get_hpos_aggregate_monthly_order_data_by_type() or get_cpt_aggregate_monthly_order_data_by_type(). + * + * @return array Formatted array with structure: + * [ + * 'renewal' => [ + * ['month' => '2025-01', 'count' => 10, 'gross' => 500.00, 'non_zero_count' => 8], + * ['month' => '2025-02', 'count' => 12, 'gross' => 600.00, 'non_zero_count' => 10], + * ], + * 'switch' => [ + * ['month' => '2025-01', 'count' => 5, 'gross' => 250.00, 'non_zero_count' => 4], + * ], + * 'resubscribe' => [ + * ['month' => '2025-01', 'count' => 2, 'gross' => 100.00, 'non_zero_count' => 2], + * ], + * ] + */ + private function format_monthly_order_data_by_type( array $results ): array { + // Initialize with empty arrays for each order type to ensure consistent structure + $data = array( + 'renewal' => array(), + 'switch' => array(), + 'resubscribe' => array(), + ); + + // Handle empty or null results - return structure with empty arrays + if ( empty( $results ) ) { + return $data; + } + + // Map the order type name with its meta key + $order_type_meta_key_map = array( + '_subscription_renewal' => 'renewal', + '_subscription_switch' => 'switch', + '_subscription_resubscribe' => 'resubscribe', + ); + + foreach ( $results as $result ) { + // Map meta key to friendly order type name + $order_type_name = $order_type_meta_key_map[ $result->meta_key ] ?? null; + + if ( ! $order_type_name ) { + continue; + } + + // Add monthly data to this order type's array + $data[ $order_type_name ][] = $this->format_monthly_order_metrics( $result ); + } + + return $data; + } + + /** + * Format a monthly order data entry with consistent type casting and rounding. + * + * Applies standard formatting to database results: + * - Casts count and non_zero_count to integers + * - Rounds gross to 2 decimal places + * - Optionally merges additional fields (e.g., quantity data) + * + * @param object $row Database row with month, count, gross, non_zero_count properties. + * @return array Formatted monthly entry. + */ + private function format_monthly_order_metrics( object $row ): array { + return array( + 'month' => $row->month, + 'count' => (int) $row->count, + 'gross' => round( (float) $row->gross, 2 ), + 'non_zero_count' => (int) $row->non_zero_count, + ); + } + + /** + * Formats store GMV data into monthly array structure. + * + * Transforms raw SQL results into a flat array of monthly GMV entries. + * + * @param array $results Database result objects from get_hpos_store_gmv() or get_cpt_store_gmv(). + * + * @return array Flat array of monthly entries with structure: + * [ + * ['month' => '2025-01', 'gross' => 1250.50], + * ['month' => '2025-02', 'gross' => 1500.75], + * ] + */ + private function format_aggregate_monthly_store_gmv( array $results ): array { + $formatted = array(); + + // Handle empty or null results + if ( empty( $results ) ) { + return $formatted; + } + + foreach ( $results as $result ) { + $formatted[] = array( + 'month' => $result->month, + 'gross' => round( (float) $result->gross, 2 ), + ); + } + + return $formatted; + } + + /** + * HPOS implementation of aggregate_monthly_order_data_by_type(). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array|null Array of database result objects with order data, or null. + */ + private function get_hpos_aggregate_monthly_order_data_by_type( string $start_date, string $end_date ): ?array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + order_type_meta.meta_key, + DATE_FORMAT(orders.date_created_gmt, '%%Y-%%m') as month, + COUNT(*) as count, + SUM(orders.total_amount) as gross, + SUM(CASE WHEN orders.total_amount > 0 THEN 1 ELSE 0 END) as non_zero_count + FROM %i AS orders + + -- Join order type meta + INNER JOIN %i AS order_type_meta ON ( + order_type_meta.order_id = orders.id + AND order_type_meta.meta_key IN ('_subscription_renewal', '_subscription_switch', '_subscription_resubscribe') + ) + + WHERE orders.type = 'shop_order' + + -- Only include successful order statuses + AND orders.status IN ( $this->active_order_statuses_clause ) + + -- Date range filter + AND orders.date_created_gmt >= %s + AND orders.date_created_gmt < %s + + GROUP BY order_type_meta.meta_key, YEAR(orders.date_created_gmt), MONTH(orders.date_created_gmt) + ORDER BY order_type_meta.meta_key ASC, month ASC + ", + $this->wc_orders_table, // FROM %i AS orders + $this->wc_orders_meta_table, // INNER JOIN %i AS order_type_meta + $start_date, // AND orders.date_created_gmt >= %s + $end_date // AND orders.date_created_gmt < %s + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * CPT implementation of aggregate_monthly_order_data_by_type(). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array|null Array of database result objects with order data, or null if no results. + */ + private function get_cpt_aggregate_monthly_order_data_by_type( string $start_date, string $end_date ): ?array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + order_type_meta.meta_key, + DATE_FORMAT(orders.post_date_gmt, '%%Y-%%m') as month, + COUNT(*) as count, + SUM(total_meta.meta_value) as gross, + SUM(CASE WHEN total_meta.meta_value > 0 THEN 1 ELSE 0 END) as non_zero_count + FROM %i AS orders + + -- Join order type meta + INNER JOIN %i AS order_type_meta ON ( + order_type_meta.post_id = orders.ID + AND order_type_meta.meta_key IN ('_subscription_renewal', '_subscription_switch', '_subscription_resubscribe') + ) + + -- Join order total from order meta + LEFT JOIN %i AS total_meta ON ( + orders.ID = total_meta.post_id + AND total_meta.meta_key = '_order_total' + ) + + WHERE orders.post_type = 'shop_order' + + -- Only include successful order statuses + AND orders.post_status IN ( $this->active_order_statuses_clause ) + + -- Date range filter + AND orders.post_date_gmt >= %s + AND orders.post_date_gmt < %s + + GROUP BY order_type_meta.meta_key, YEAR(orders.post_date_gmt), MONTH(orders.post_date_gmt) + ORDER BY order_type_meta.meta_key ASC, month ASC + ", + $wpdb->posts, // FROM %i AS orders + $wpdb->postmeta, // INNER JOIN %i AS order_type_meta + $wpdb->postmeta, // LEFT JOIN %i AS total_meta + $start_date, // AND orders.post_date_gmt >= %s + $end_date // AND orders.post_date_gmt < %s + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Aggregates parent order data (orders that created subscriptions). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array Associative array with order data. + */ + private function aggregate_monthly_parent_order_data( string $start_date, string $end_date ): array { + $results = $this->is_hpos + ? $this->get_hpos_aggregate_monthly_parent_order_data( $start_date, $end_date ) + : $this->get_cpt_aggregate_monthly_parent_order_data( $start_date, $end_date ); + + return $this->format_parent_order_data( $results['order_data'], $results['quantity_data'] ); + } + + /** + * Formats parent order data into monthly array structure. + * + * Merges order data (count, gross, non_zero_count) with quantity data + * (total_quantity, non_zero_quantity) by month and applies formatting. + * + * @param array $order_data Monthly order results from SQL with month, count, gross, non_zero_count. + * @param array $quantity_data Monthly quantity results from SQL with month, total_quantity, non_zero_quantity. + * + * @return array Flat array of monthly entries with structure: + * [ + * ['month' => '2025-01', 'count' => 10, 'gross' => 500.00, 'non_zero_count' => 8, 'quantity' => 15, 'non_zero_quantity' => 12], + * ['month' => '2025-02', 'count' => 12, 'gross' => 600.00, 'non_zero_count' => 10, 'quantity' => 18, 'non_zero_quantity' => 15], + * ] + */ + private function format_parent_order_data( array $order_data, array $quantity_data ): array { + $formatted = array(); + + // Build quantity lookup by month. + $quantity_by_month = array(); + foreach ( $quantity_data as $qty_row ) { + $quantity_by_month[ $qty_row->month ] = array( + 'quantity' => (int) $qty_row->total_quantity, + 'non_zero_quantity' => (int) $qty_row->non_zero_quantity, + ); + } + + // Build final monthly array + foreach ( $order_data as $order_row ) { + $month = $order_row->month; + + // Get quantity data for this month (default to 0 if not found) + $qty_info = $quantity_by_month[ $month ] ?? array( + 'quantity' => 0, + 'non_zero_quantity' => 0, + ); + + // Format base monthly entry and add quantity fields + $entry = $this->format_monthly_order_metrics( $order_row ); + $entry['quantity'] = $qty_info['quantity']; + $entry['non_zero_quantity'] = $qty_info['non_zero_quantity']; + $formatted[] = $entry; + } + + return $formatted; + } + + /** + * HPOS implementation of aggregate_monthly_parent_order_data(). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array Associative array with order data. + */ + private function get_hpos_aggregate_monthly_parent_order_data( string $start_date, string $end_date ): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + // Get order's count, gross, and non-zero count grouped by month + $order_data = $wpdb->get_results( + $wpdb->prepare( + " + SELECT + DATE_FORMAT(orders.date_created_gmt, '%%Y-%%m') as month, + COUNT(*) as count, + SUM(orders.total_amount) as gross, + SUM(CASE WHEN orders.total_amount > 0 THEN 1 ELSE 0 END) as non_zero_count + FROM %i AS orders + WHERE orders.type = 'shop_order' + + -- Only include successful order statuses + AND orders.status IN ( $this->active_order_statuses_clause ) + + -- Date range filter + AND orders.date_created_gmt >= %s + AND orders.date_created_gmt < %s + + -- Parent orders (orders that created subscriptions) + AND orders.id IN ( + SELECT DISTINCT parent_order_id + FROM %i AS subscriptions + WHERE subscriptions.type = 'shop_subscription' + AND subscriptions.parent_order_id IS NOT NULL + AND subscriptions.parent_order_id <> 0 + ) + + GROUP BY YEAR(orders.date_created_gmt), MONTH(orders.date_created_gmt) + ORDER BY month ASC + ", + $this->wc_orders_table, // FROM %i AS orders + $start_date, // AND orders.date_created_gmt >= %s + $end_date, // AND orders.date_created_gmt < %s + $this->wc_orders_table // SELECT DISTINCT parent_order_id FROM %i AS subscriptions + ) + ); + + // Get item quantity counts grouped by month + $quantity_data = $wpdb->get_results( + $wpdb->prepare( + " + SELECT + DATE_FORMAT(orders.date_created_gmt, '%%Y-%%m') as month, + SUM(CAST(wcoimeta.meta_value AS DECIMAL(10,2))) as total_quantity, + SUM( IF( orders.total_amount > 0, CAST( wcoimeta.meta_value AS DECIMAL( 10,2 ) ), 0 ) ) as non_zero_quantity + FROM %i AS orders + + -- Join to subscriptions: Only include orders that created subscriptions (parent orders) + INNER JOIN %i AS subscriptions ON ( + subscriptions.parent_order_id = orders.id + AND subscriptions.type = 'shop_subscription' + ) + + -- Join to order items: Get all line items for each parent order + INNER JOIN %i AS wcoitems ON ( + orders.id = wcoitems.order_id + AND wcoitems.order_item_type = 'line_item' + ) + + -- Join to item metadata: Get quantity values for each line item + INNER JOIN %i AS wcoimeta ON ( + wcoitems.order_item_id = wcoimeta.order_item_id + AND wcoimeta.meta_key = '_qty' + ) + WHERE orders.type = 'shop_order' + + -- Only completed transactions + AND orders.status IN ( $this->active_order_statuses_clause ) + + -- Date range filter + AND orders.date_created_gmt >= %s + AND orders.date_created_gmt < %s + + GROUP BY YEAR(orders.date_created_gmt), MONTH(orders.date_created_gmt) + ORDER BY month ASC + ", + $this->wc_orders_table, // FROM %i AS orders + $this->wc_orders_table, // INNER JOIN %i AS subscriptions + $wpdb->prefix . 'woocommerce_order_items', // INNER JOIN %i AS wcoitems + $wpdb->prefix . 'woocommerce_order_itemmeta', // INNER JOIN %i AS wcoimeta + $start_date, // AND orders.date_created_gmt >= %s + $end_date // AND orders.date_created_gmt < %s + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + + // Return both datasets for formatting + return array( + 'order_data' => $order_data, + 'quantity_data' => $quantity_data, + ); + } + + /** + * CPT implementation of aggregate_monthly_parent_order_data(). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array Associative array with order data. + */ + private function get_cpt_aggregate_monthly_parent_order_data( string $start_date, string $end_date ): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + // Get order's count, gross, and non-zero count grouped by month + $order_data = $wpdb->get_results( + $wpdb->prepare( + " + SELECT + DATE_FORMAT(orders.post_date_gmt, '%%Y-%%m') as month, + COUNT(*) as count, + SUM(total_meta.meta_value) as gross, + SUM(CASE WHEN total_meta.meta_value > 0 THEN 1 ELSE 0 END) as non_zero_count + FROM %i AS orders + + -- Join order total from order meta + LEFT JOIN %i AS total_meta ON ( + orders.ID = total_meta.post_id + AND total_meta.meta_key = '_order_total' + ) + WHERE orders.post_type = 'shop_order' + + -- Only include successful order statuses + AND orders.post_status IN ( $this->active_order_statuses_clause ) + + -- Date range filter + AND orders.post_date_gmt >= %s + AND orders.post_date_gmt < %s + + -- Parent orders (orders that created subscriptions) + AND orders.ID IN ( + SELECT DISTINCT post_parent + FROM %i AS subscriptions + WHERE subscriptions.post_type = 'shop_subscription' + AND subscriptions.post_parent IS NOT NULL + AND subscriptions.post_parent <> 0 + ) + + GROUP BY YEAR(orders.post_date_gmt), MONTH(orders.post_date_gmt) + ORDER BY month ASC + ", + $wpdb->posts, // FROM %i AS orders + $wpdb->postmeta, // LEFT JOIN %i AS total_meta + $start_date, // AND orders.post_date_gmt >= %s + $end_date, // AND orders.post_date_gmt < %s + $wpdb->posts // SELECT DISTINCT post_parent FROM %i AS subscriptions + ) + ); + + // Get item quantity counts grouped by month + $quantity_data = $wpdb->get_results( + $wpdb->prepare( + " + SELECT + DATE_FORMAT(orders.post_date_gmt, '%%Y-%%m') as month, + SUM(CAST(wcoimeta.meta_value AS DECIMAL(10,2))) as total_quantity, + SUM( IF( total_meta.meta_value > 0, CAST( wcoimeta.meta_value AS DECIMAL( 10,2 ) ), 0 ) ) as non_zero_quantity + FROM %i AS orders + + -- Join to subscriptions: Only include orders that created subscriptions (parent orders) + INNER JOIN %i AS subscriptions ON ( + subscriptions.post_parent = orders.ID + AND subscriptions.post_type = 'shop_subscription' + ) + + -- Join order total from order meta + LEFT JOIN %i AS total_meta ON ( + orders.ID = total_meta.post_id + AND total_meta.meta_key = '_order_total' + ) + + -- Join to order items: Get all line items for each parent order + INNER JOIN %i AS wcoitems ON ( + orders.ID = wcoitems.order_id + AND wcoitems.order_item_type = 'line_item' + ) + + -- Join to item metadata: Get quantity values for each line item + INNER JOIN %i AS wcoimeta ON ( + wcoitems.order_item_id = wcoimeta.order_item_id + AND wcoimeta.meta_key = '_qty' + ) + WHERE orders.post_type = 'shop_order' + + -- Only completed transactions + AND orders.post_status IN ( $this->active_order_statuses_clause ) + + -- Date range filter + AND orders.post_date_gmt >= %s + AND orders.post_date_gmt < %s + + GROUP BY YEAR(orders.post_date_gmt), MONTH(orders.post_date_gmt) + ORDER BY month ASC + ", + $wpdb->posts, // FROM %i AS orders + $wpdb->posts, // INNER JOIN %i AS subscriptions + $wpdb->postmeta, // LEFT JOIN %i AS total_meta + $wpdb->prefix . 'woocommerce_order_items', // INNER JOIN %i AS wcoitems + $wpdb->prefix . 'woocommerce_order_itemmeta', // INNER JOIN %i AS wcoimeta + $start_date, // AND orders.post_date_gmt >= %s + $end_date // AND orders.post_date_gmt < %s + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + + // Return both datasets for formatting + return array( + 'order_data' => $order_data, + 'quantity_data' => $quantity_data, + ); + } + + /** + * Gets the store's GMV for the specified timeframe. + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array + */ + private function aggregate_monthly_store_gmv( string $start_date, string $end_date ): array { + $results = $this->is_hpos + ? $this->get_hpos_aggregate_monthly_store_gmv( $start_date, $end_date ) + : $this->get_cpt_aggregate_monthly_store_gmv( $start_date, $end_date ); + + return $this->format_aggregate_monthly_store_gmv( $results ); + } + + /** + * Gets the store's GMV for the specified timeframe (HPOS implementation). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array + */ + private function get_hpos_aggregate_monthly_store_gmv( string $start_date, string $end_date ): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + DATE_FORMAT(orders.date_created_gmt, '%%Y-%%m') as month, + SUM(orders.total_amount) as gross + FROM %i AS orders + WHERE orders.type = 'shop_order' + AND orders.status IN ( $this->active_order_statuses_clause ) + AND orders.date_created_gmt >= %s + AND orders.date_created_gmt < %s + GROUP BY YEAR(orders.date_created_gmt), MONTH(orders.date_created_gmt) + ORDER BY month ASC + ", + $this->wc_orders_table, + $start_date, + $end_date + ) + ); + // phpcs:enable phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Gets the store's GMV for the specified timeframe (CPT implementation). + * + * @param string $start_date Start date in 'Y-m-d H:i:s' format. + * @param string $end_date End date in 'Y-m-d H:i:s' format. + * + * @return array + */ + private function get_cpt_aggregate_monthly_store_gmv( string $start_date, string $end_date ): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_order_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + DATE_FORMAT(orders.post_date_gmt, '%%Y-%%m') as month, + SUM(order_meta.meta_value) as gross + FROM %i AS orders + LEFT JOIN %i AS order_meta ON order_meta.post_id = orders.ID + WHERE order_meta.meta_key = '_order_total' + AND orders.post_status IN ( $this->active_order_statuses_clause ) + AND orders.post_date_gmt >= %s + AND orders.post_date_gmt < %s + GROUP BY YEAR(orders.post_date_gmt), MONTH(orders.post_date_gmt) + ORDER BY month ASC + ", + $wpdb->posts, + $wpdb->postmeta, + $start_date, + $end_date + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Normalizes a timestamp range to full month boundaries in UTC. + * + * Ensures the start timestamp is normalized to the first day of its month + * and the end timestamp is normalized to the last day of its month. + * This prevents partial month data that could be misleading in monthly reports. + * + * @param int $start_timestamp Start timestamp. + * @param int $end_timestamp End timestamp. + * + * @return array { + * 'start': string, + * 'end': string, + * } + */ + private function normalize_timestamp_range_to_month_boundaries( int $start_timestamp, int $end_timestamp ): array { + // Convert timestamps to DateTime objects in UTC (@ prefix sets UTC automatically) + $start = new DateTime( '@' . $start_timestamp ); + $end = new DateTime( '@' . $end_timestamp ); + + // Set start date to the first day of its month at 00:00:00 UTC + $normalized_start = $start->modify( 'first day of this month 00:00:00' )->format( 'Y-m-d H:i:s' ); + + // Set end date to the last day of its month at 23:59:59 UTC + $normalized_end = $end->modify( 'last day of this month 23:59:59' )->format( 'Y-m-d H:i:s' ); + + return array( + 'start' => $normalized_start, + 'end' => $normalized_end, + ); + } +} diff --git a/src/Internal/Telemetry/Products.php b/src/Internal/Telemetry/Products.php new file mode 100644 index 0000000..a91db95 --- /dev/null +++ b/src/Internal/Telemetry/Products.php @@ -0,0 +1,241 @@ +get_subscription_product_type_term_ids(); + + // Under unusual conditions, we may be missing one or both product type term IDs. + if ( false === $subscription_product_term_ids ) { + return 0; + } + + $atomic_gifting_condition = WCSG_Admin::is_gifting_enabled_for_all_products() + ? "( gifting_setting.meta_value <> 'disabled' OR gifting_setting.meta_key IS NULL )" + : "gifting_setting.meta_value = 'enabled'"; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + return (int) $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT(*) + FROM %i AS product + -- Reduce the result set to products of the `subscription` and `variable_subscription` product types. + INNER JOIN ( + SELECT product_post.ID, + product_type.term_taxonomy_id, + product_post.post_status + FROM %i AS product_post + INNER JOIN %i AS product_type ON ( + product_type.object_id = product_post.ID + AND product_type.term_taxonomy_id IN ( %d, %d ) + ) + ) p ON ( + -- For variable subscription products, the relevant taxonomy term is applied to the parent post. + ( product.ID = p.ID AND p.term_taxonomy_id = %d ) + OR ( product.post_parent = p.ID AND p.term_taxonomy_id = %d ) + ) + -- Get the gifting mode (explicitly enabled, disabled, or following the global default). + LEFT JOIN %i AS gifting_setting ON ( + gifting_setting.post_id = product.ID + AND gifting_setting.meta_key = '_subscription_gifting' + ) + WHERE product.post_type IN ( 'product', 'product_variation' ) + AND product.post_status = 'publish' + AND p.post_status = 'publish' + AND $atomic_gifting_condition + ", + $wpdb->posts, + $wpdb->posts, + $wpdb->term_relationships, + $subscription_product_term_ids['subscription'], + $subscription_product_term_ids['variable_subscription'], + $subscription_product_term_ids['subscription'], + $subscription_product_term_ids['variable_subscription'], + $wpdb->postmeta + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Supplies meta query arguments, for use inside a larger set of WP_Query args, that limits results to products + * where gifting is individually enabled or disabled, depending on the value of $enabled. + * + * @param bool $enabled If we are interested in products where gifting is enabled, or excluding those that are disabled. + * + * @return array[] + */ + private function build_gifting_meta_query( bool $enabled ): array { + $meta_query = array( + array( + 'key' => '_subscription_gifting', + 'value' => $enabled ? 'enabled' : 'disabled', + 'compare' => $enabled ? '=' : '!=', + ), + ); + + if ( ! $enabled ) { + $meta_query['relation'] = 'OR'; + $meta_query[] = array( + 'key' => '_subscription_gifting', + 'compare' => 'NOT EXISTS', + ); + } + + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query + return array( 'meta_query' => $meta_query ); + } + + /** + * Returns an array of objects detailing the number of published subscription products by frequency. + * + * The return value is an array of objects, with each object containing the properties period, interval and product count: + * + * [ + * { + * period: string, + * interval: int, + * count: int + * }, + * ... + * ] + * + * @return object[] + */ + public function get_product_frequencies(): array { + global $wpdb; + + $subscription_product_term_ids = $this->get_subscription_product_type_term_ids(); + + // Under unusual conditions, we may be missing one or both product type term IDs. + if ( false === $subscription_product_term_ids ) { + return array(); + } + + $results = $wpdb->get_results( + $wpdb->prepare( + " + -- Count the number of subscription products by billing period and billing interval. + SELECT billing_period.meta_value AS period, + billing_interval.meta_value AS `interval`, + COUNT(*) AS count + FROM %i AS product + -- Reduce the result set to products of the `subscription` and `variable_subscription` product types. + INNER JOIN ( + SELECT product_post.ID, + product_type.term_taxonomy_id, + product_post.post_status + FROM %i AS product_post + INNER JOIN %i AS product_type ON ( + product_type.object_id = product_post.ID + AND product_type.term_taxonomy_id IN ( %d, %d ) + ) + ) subscription_product ON ( + -- For variable subscription products, the relevant taxonomy term is applied to the parent post. + ( product.ID = subscription_product.ID AND subscription_product.term_taxonomy_id = %d ) + OR ( product.post_parent = subscription_product.ID AND subscription_product.term_taxonomy_id = %d ) + ) + -- Obtain the billing period interval (usually an integer, or string representation of an integer). + LEFT JOIN %i AS billing_interval ON ( + billing_interval.post_id = product.ID + AND billing_interval.meta_key = '_subscription_period_interval' + ) + -- Obtain the billing period (usually one of 'day', 'week', 'month', 'year'). + LEFT JOIN %i AS billing_period ON ( + billing_period.post_id = product.ID + AND billing_period.meta_key = '_subscription_period' + ) + -- We are only interested in active (published) products and product variations. + WHERE product.post_type IN ( 'product', 'product_variation' ) + AND product.post_status = 'publish' + AND subscription_product.post_status = 'publish' + GROUP BY billing_period.meta_value, + billing_interval.meta_value + ORDER BY count DESC, + billing_period.meta_value ASC, + billing_interval.meta_value DESC + ", + $wpdb->posts, + $wpdb->posts, + $wpdb->term_relationships, + $subscription_product_term_ids['subscription'], + $subscription_product_term_ids['variable_subscription'], + $subscription_product_term_ids['subscription'], + $subscription_product_term_ids['variable_subscription'], + $wpdb->postmeta, + $wpdb->postmeta, + ) + ); + + foreach ( $results as $index => &$result_set ) { + if ( empty( $result_set->period ) || empty( $result_set->interval ) ) { + unset( $results[ $index ] ); + continue; + } + + $result_set->period = (string) $result_set->period; + $result_set->interval = (int) $result_set->interval; + $result_set->count = (int) $result_set->count; + } + + return array_values( $results ); + } + + /** + * Returns the term IDs for the subscription and variable subscription product types. + * + * This will be presented as a keyed array of integers, as follows (unless one or both terms are missing, in which + * case bool false will be returned): + * + * [ + * 'subscription' => int, + * 'variable_subscription' => int + * ] + * + * @return int[]|false The term IDs for the subscription and variable subscription product types, else false. + */ + private function get_subscription_product_type_term_ids() { + $subscription_product_term_ids = array(); + + $subscription_term = get_term_by( 'slug', 'subscription', 'product_type' ); + $variable_subscription_term = get_term_by( 'slug', 'variable-subscription', 'product_type' ); + + if ( ! is_a( $subscription_term, WP_Term::class ) || ! is_a( $variable_subscription_term, WP_Term::class ) ) { + return false; + } + + return array( + 'subscription' => (int) $subscription_term->term_id, + 'variable_subscription' => (int) $variable_subscription_term->term_id, + ); + } +} diff --git a/src/Internal/Telemetry/Subscriptions.php b/src/Internal/Telemetry/Subscriptions.php new file mode 100644 index 0000000..37e83d4 --- /dev/null +++ b/src/Internal/Telemetry/Subscriptions.php @@ -0,0 +1,556 @@ +active_subscription_statuses_clause = "'wc-active', 'wc-pending-cancel'"; + $this->is_hpos = wcs_is_custom_order_tables_usage_enabled(); + $this->wc_orders_table = $wpdb->prefix . 'wc_orders'; + $this->wc_orders_meta_table = $wpdb->prefix . 'wc_orders_meta'; + } + + /** + * Supplies the number of active subscribers. That is, the number of unique users who have at least one active + * subscription. + * + * @param bool $active Whether to return a count of active subscribers (true) or inactive subscribers (false). Default true. + * + * @return int + */ + public function get_subscriber_count( bool $active = true ): int { + return $this->is_hpos + ? $this->get_hpos_subscriber_count( $active ) + : $this->get_cpt_subscriber_count( $active ); + } + + /** + * HPOS implementation of get_active_subscriber_count(). + * + * @param bool $active Whether to return a count of active subscribers (true) or inactive subscribers (false). Default true. + * + * @return int + */ + private function get_hpos_subscriber_count( bool $active = true ): int { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + $base_query = $wpdb->prepare( + " + FROM %i + WHERE type = 'shop_subscription' + AND customer_id IS NOT NULL + AND status IN ( $this->active_subscription_statuses_clause ) + ", + $this->wc_orders_table + ); + + if ( $active ) { + $query = " + SELECT COUNT( DISTINCT customer_id ) + $base_query + "; + } else { + $query = $wpdb->prepare( + " + SELECT COUNT( DISTINCT customer_id ) + FROM %i + WHERE type = 'shop_subscription' + AND customer_id IS NOT NULL + AND customer_id NOT IN ( + SELECT DISTINCT customer_id + $base_query + ) + ", + $this->wc_orders_table + ); + } + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + return (int) $wpdb->get_var( $query ); + } + + /** + * CPT implementation of get_active_subscriber_count(). + * + * @param bool $active Whether to return a count of active subscribers (true) or inactive subscribers (false). Default true. + * + * @return int + */ + private function get_cpt_subscriber_count( bool $active = true ): int { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + $base_query = $wpdb->prepare( + " + FROM %i AS orders + JOIN %i AS customer ON ( + orders.ID = customer.post_id + AND customer.meta_key = '_customer_user' + ) + WHERE orders.post_type = 'shop_subscription' + AND orders.post_status IN ( $this->active_subscription_statuses_clause ) + ", + $wpdb->posts, + $wpdb->postmeta + ); + + if ( $active ) { + $query = " + SELECT COUNT( DISTINCT customer.meta_value ) AS customer_id + $base_query + "; + } else { + $query = $wpdb->prepare( + " + SELECT COUNT( DISTINCT customer.meta_value ) AS customer_id + FROM %i AS orders + JOIN %i AS customer ON ( + orders.ID = customer.post_id + AND customer.meta_key = '_customer_user' + ) + WHERE orders.post_type = 'shop_subscription' + AND customer.meta_value NOT IN ( + SELECT DISTINCT customer.meta_value + $base_query + ) + ", + $wpdb->posts, + $wpdb->postmeta + ); + } + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + return (int) $wpdb->get_var( $query ); + } + + /** + * Supplies the number of active subscriptions that are set to renew automatically. + * + * @return int + */ + public function get_active_subscriptions_renewing_automatically(): int { + return $this->is_hpos + ? $this->get_hpos_subscriptions_count() + : $this->get_cpt_subscriptions_count(); + } + + /** + * Supplies the number of active subscriptions that are set to renew manually. + * + * @return int + */ + public function get_active_subscriptions_renewing_manually(): int { + return $this->is_hpos + ? $this->get_hpos_subscriptions_count( false ) + : $this->get_cpt_subscriptions_count( false ); + } + + /** + * HPOS implementation for get_active_subscriptions_renewing_(). + * + * @param bool $automatic_renewal If we are interested specifically in subscriptions renewing automatically (true) or manually (false). Default true. + * + * @return int + */ + private function get_hpos_subscriptions_count( bool $automatic_renewal = true ): int { + global $wpdb; + $renewal_condition = $automatic_renewal ? '<>' : '='; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + return (int) $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT( 1 ) AS order_count + FROM %i AS orders + LEFT JOIN %i AS order_meta ON ( + orders.id = order_meta.order_id + AND order_meta.meta_key = '_requires_manual_renewal' + ) + WHERE orders.type = 'shop_subscription' + AND orders.status IN ( $this->active_subscription_statuses_clause ) + AND order_meta.meta_value $renewal_condition 'true' + ", + $this->wc_orders_table, + $this->wc_orders_meta_table + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * CPT implementation for get_active_subscriptions_renewing_(). + * + * @param bool $automatic_renewal If we are interested specifically in subscriptions renewing automatically (true) or manually (false). Default true. + * + * @return int + */ + private function get_cpt_subscriptions_count( bool $automatic_renewal = true ): int { + global $wpdb; + $renewal_condition = $automatic_renewal ? '<>' : '='; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + return (int) $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT( 1 ) AS order_count + FROM %i AS orders + LEFT JOIN %i AS order_meta ON ( + orders.ID = order_meta.post_id + AND order_meta.meta_key = '_requires_manual_renewal' + + ) + WHERE orders.post_type = 'shop_subscription' + AND orders.post_status IN ( $this->active_subscription_statuses_clause ) + AND order_meta.meta_value $renewal_condition 'true' + ", + $wpdb->posts, + $wpdb->postmeta + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Returns an array of objects detailing the number of (active) subscriptions by frequency. + * + * The return value is an array of objects, with each object containing the properties period, interval and count: + * + * [ + * { + * period: string, + * interval: int, + * count: int + * }, + * ... + * ] + * + * @return object[] + */ + public function get_subscriptions_by_frequency(): array { + $results = (array) ( + $this->is_hpos + ? $this->get_hpos_subscriptions_by_frequency() + : $this->get_cpt_subscriptions_by_frequency() + ); + + foreach ( $results as &$result_set ) { + $result_set->period = (string) $result_set->period; + $result_set->interval = (int) $result_set->interval; + $result_set->count = (int) $result_set->count; + } + + return $results; + } + + /** + * HPOS implementation of get_subscriptions_by_frequency(). + */ + private function get_hpos_subscriptions_by_frequency(): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT billing_period.meta_value AS period, + billing_interval.meta_value AS `interval`, + COUNT(*) AS count + FROM %i AS orders + LEFT JOIN %i AS billing_period ON ( + orders.id = billing_period.order_id + AND billing_period.meta_key = '_billing_period' + ) + LEFT JOIN %i AS billing_interval ON ( + orders.id = billing_interval.order_id + AND billing_interval.meta_key = '_billing_interval' + ) + WHERE orders.type = 'shop_subscription' + AND orders.status IN ( $this->active_subscription_statuses_clause ) + GROUP BY billing_period.meta_value, + billing_interval.meta_value + ORDER BY count DESC, + billing_period.meta_value ASC, + billing_interval.meta_value DESC + ", + $this->wc_orders_table, + $this->wc_orders_meta_table, + $this->wc_orders_meta_table + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * CPT implementation of get_subscriptions_by_frequency(). + */ + private function get_cpt_subscriptions_by_frequency(): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT billing_period.meta_value AS period, + billing_interval.meta_value AS `interval`, + COUNT(*) AS count + FROM %i AS orders + LEFT JOIN %i AS billing_period ON ( + orders.ID = billing_period.post_id + AND billing_period.meta_key = '_billing_period' + ) + LEFT JOIN %i AS billing_interval ON ( + orders.ID = billing_interval.post_id + AND billing_interval.meta_key = '_billing_interval' + ) + WHERE orders.post_type = 'shop_subscription' + AND orders.post_status IN ( $this->active_subscription_statuses_clause ) + GROUP BY billing_period.meta_value, + billing_interval.meta_value + ORDER BY count DESC, + billing_period.meta_value ASC, + billing_interval.meta_value DESC + ", + $wpdb->posts, + $wpdb->postmeta, + $wpdb->postmeta + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Gets a count of subscriptions grouped by payment method. + * + * The return value is an array of objects, with each object containing the properties payment_method and order_count: + * + * [ + * { + * payment_method: string, + * active_subscription_count: int, + * inactive_subscription_count: int, + * method_renews_off_site: string, # 'yes'|'no'|'unknown' + * manual_renewal_only: string, # 'yes'|'no'|'unknown' + * }, + * ... + * ] + * + * Note that the method_renews_off_site property is set if the gateway reports that it supports off-site renewal + * payment ('gateway_scheduled_payments'). See also payment_method_renews_off_site() for caveats on this. + * + * @return object[] Array of objects containing payment_method and order_count. + */ + public function get_subscriptions_by_payment_method(): array { + $results = $this->is_hpos + ? $this->get_hpos_subscriptions_by_payment_method() + : $this->get_cpt_subscriptions_by_payment_method(); + + foreach ( $results as &$result_set ) { + $gateway_properties = $this->payment_method_properties( $result_set->payment_method ); + $result_set->payment_method = (string) $result_set->payment_method; + $result_set->active_subscription_count = (int) $result_set->active_subscription_count; + $result_set->inactive_subscription_count = (int) $result_set->inactive_subscription_count; + $result_set->method_renews_off_site = $gateway_properties['gateway_scheduled_payments']; + $result_set->manual_renewal_only = $gateway_properties['manual_renewal_only']; + } + + return $results; + } + + /** + * HPOS implementation of get_subscriptions_by_payment_method(). + */ + private function get_hpos_subscriptions_by_payment_method(): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + IFNULL( payment_method, '' ) as payment_method, + SUM( CASE WHEN status IN ( $this->active_subscription_statuses_clause ) THEN 1 ELSE 0 END ) AS active_subscription_count, + SUM( CASE WHEN status NOT IN ( $this->active_subscription_statuses_clause ) THEN 1 ELSE 0 END ) AS inactive_subscription_count + FROM %i + WHERE type = 'shop_subscription' + GROUP BY IFNULL(payment_method, '') + ORDER BY active_subscription_count DESC, + inactive_subscription_count DESC; + ", + $this->wc_orders_table + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * CPT implementation of get_subscriptions_by_payment_method(). + */ + private function get_cpt_subscriptions_by_payment_method(): array { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- property $this->active_subscription_statuses_clause is sanitized. + return $wpdb->get_results( + $wpdb->prepare( + " + SELECT + IFNULL(order_meta.meta_value, '') AS payment_method, + SUM( CASE WHEN orders.post_status IN ( $this->active_subscription_statuses_clause ) THEN 1 ELSE 0 END ) AS active_subscription_count, + SUM( CASE WHEN orders.post_status NOT IN ( $this->active_subscription_statuses_clause ) THEN 1 ELSE 0 END ) AS inactive_subscription_count + FROM %i AS orders + LEFT JOIN %i AS order_meta ON orders.ID = order_meta.post_id + AND order_meta.meta_key = '_payment_method' + WHERE orders.post_type = 'shop_subscription' + GROUP BY IFNULL(order_meta.meta_value, '') + ORDER BY active_subscription_count DESC, + inactive_subscription_count DESC; + ", + $wpdb->posts, + $wpdb->postmeta + ) + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Indicates if the specified payment method supports off-site renewal payment (ie, gateway scheduled payments), and + * if it supports subscriptions. + * + * Note that, just because a gateways supports 'gateway_scheduled_payments', does not mean it is supported for a + * specific subscription. + * + * @param string $payment_method + * + * @return array { + * gateway_scheduled_payments: string + * manual_renewal_only: string + * } + */ + private function payment_method_properties( string $payment_method ): array { + // If a particular gateway is disabled/inactive, then we cannot determine what it does or does not support. + $properties = array( + 'gateway_scheduled_payments' => 'unknown', + 'manual_renewal_only' => 'unknown', + ); + + foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { + if ( $payment_method === $gateway->id ) { + $properties['gateway_scheduled_payments'] = $gateway->supports( 'gateway_scheduled_payments' ) ? 'yes' : 'no'; + $properties['manual_renewal_only'] = $gateway->supports( 'subscriptions' ) ? 'no' : 'yes'; + break; + } + } + + return $properties; + } + + /** + * Supplies the total count of gifted subscriptions. + * + * @return int + */ + public function get_gifted_subscriptions_count(): int { + return $this->is_hpos + ? $this->get_hpos_gifted_subscriptions_count() + : $this->get_cpt_gifted_subscriptions_count(); + } + + /** + * HPOS implementation of get_gifted_subscriptions_count(). + * + * @return int + */ + private function get_hpos_gifted_subscriptions_count(): int { + global $wpdb; + + $count = $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT(DISTINCT orders.id) + FROM %i AS orders + INNER JOIN %i AS orders_meta ON (orders.id = orders_meta.order_id) + WHERE orders.type = 'shop_subscription' + AND orders.status NOT IN ( 'auto-draft', 'trash' ) + AND orders_meta.meta_key = '_recipient_user' + ", + $this->wc_orders_table, + $this->wc_orders_meta_table + ) + ); + + return absint( $count ); + } + + /** + * CPT implementation of get_gifted_subscriptions_count(). + * + * @return int + */ + private function get_cpt_gifted_subscriptions_count(): int { + global $wpdb; + + $count = $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT(DISTINCT posts.ID) + FROM %i AS posts + INNER JOIN %i AS posts_meta ON (posts.ID = posts_meta.post_id) + WHERE posts.post_type = 'shop_subscription' + AND posts.post_status NOT IN ( 'auto-draft', 'trash' ) + AND posts_meta.meta_key = '_recipient_user' + ", + $wpdb->posts, + $wpdb->postmeta, + ) + ); + + return absint( $count ); + } +} diff --git a/src/Internal/Utilities/Scheduled_Actions.php b/src/Internal/Utilities/Scheduled_Actions.php new file mode 100644 index 0000000..d3fc779 --- /dev/null +++ b/src/Internal/Utilities/Scheduled_Actions.php @@ -0,0 +1,69 @@ + self::schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args, $group, $unique, $priority ) ); + return; + } + + $register_action = static function () use ( $timestamp, $interval_in_seconds, $hook, $args, $group, $unique, $priority ) { + // Older versions of Action Scheduler don't support 'uniqueness', or don't support it evenly (across data + // stores), so we add an additional safeguard. + if ( $unique && as_has_scheduled_action( $hook, $args, $group ) ) { + return 0; + } + + as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args, $group, $unique, $priority ); + }; + + // Since Action Scheduler 3.9.3 it is generally preferable to register recurring actions during the action + // that the library provides for this purpose. + $registration_hook = function_exists( 'as_supports' ) && as_supports( 'ensure_recurring_actions_hook' ) + ? 'action_scheduler_ensure_recurring_actions' + : 'admin_init'; + + // @phpstan-ignore return.void + add_action( $registration_hook, $register_action ); + } +} diff --git a/templates/checkout/recurring-itemized-tax-totals.php b/templates/checkout/recurring-itemized-tax-totals.php index d252073..9ffbce0 100644 --- a/templates/checkout/recurring-itemized-tax-totals.php +++ b/templates/checkout/recurring-itemized-tax-totals.php @@ -21,7 +21,7 @@ foreach ( WC()->cart->get_taxes() as $tax_id => $tax_total ) { * Allow third-parties to filter the tax displayed. * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.1.0 - * @param string The recurring cart's tax total price string for this tax code. + * @param string $tax_amount The recurring cart's tax total price string for this tax code. * @param WC_Cart $recurring_cart The recurring cart. * @param string $recurring_code The tax code. * @param object $recurring_tax The recurring tax data generated by @see WC_Cart::get_tax_totals() diff --git a/templates/checkout/recurring-tax-totals.php b/templates/checkout/recurring-tax-totals.php index a24f67e..ce64a27 100644 --- a/templates/checkout/recurring-tax-totals.php +++ b/templates/checkout/recurring-tax-totals.php @@ -15,7 +15,7 @@ foreach ( $recurring_carts as $recurring_cart_key => $recurring_cart ) { * Allow third-parties to filter the tax displayed. * * @since 1.0.0 - Migrated from WooCommerce Subscriptions v3.1.0 - * @param string The recurring cart's total tax price string. + * @param string $tax_amount The recurring cart's total tax price string. * @param WC_Cart $recurring_cart The recurring cart. */ $tax_amount = wp_kses_post( apply_filters( 'wcs_recurring_cart_tax_totals_html', wcs_cart_price_string( $recurring_cart->get_taxes_total(), $recurring_cart ), $recurring_cart ) ); diff --git a/templates/gifting/emails/recipient-email-order-details.php b/templates/gifting/emails/recipient-email-order-details.php index be9e489..e3890a5 100644 --- a/templates/gifting/emails/recipient-email-order-details.php +++ b/templates/gifting/emails/recipient-email-order-details.php @@ -19,16 +19,14 @@ if ( ! defined( 'ABSPATH' ) ) { $sent_to_admin, - 'show_image' => '', - 'image_size' => '', - 'plain_text' => $plain_text, - 'sent_to_admin' => $sent_to_admin, - ) + WCSG_Email::recipient_email_order_items_table( + $order, + array( + 'show_sku' => $sent_to_admin, + 'show_image' => '', + 'image_size' => '', + 'plain_text' => $plain_text, + 'sent_to_admin' => $sent_to_admin, ) ); ?> diff --git a/templates/gifting/emails/recipient-new-initial-order.php b/templates/gifting/emails/recipient-new-initial-order.php index 83a5779..b75fcc6 100644 --- a/templates/gifting/emails/recipient-new-initial-order.php +++ b/templates/gifting/emails/recipient-new-initial-order.php @@ -25,7 +25,8 @@ printf( esc_html__( ' Details of the %s are shown below.', 'woocommerce-subscrip

ID, 'wcsg_update_account', true ); +// Handle the email preview. +$new_recipient = empty( $recipient_user ) ? 'true' : get_user_meta( $recipient_user->ID, 'wcsg_update_account', true ); if ( 'true' == $new_recipient ) : // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison ?> @@ -49,8 +50,10 @@ if ( 'true' == $new_recipient ) : // phpcs:ignore WordPress.PHP.StrictComparison is_in_stock() ) : ?> is_purchasable() && 0 !== $user_id && 'no' !== wcs_get_product_limitation( $product ) && wcs_is_product_limited_for_user( $product, $user_id ) ) : ?> - get_id() ); ?> - get_id(), wcs_get_product_limitation( $product ) ) && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'active' ) && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'on-hold' ) ) : // customer has an inactive subscription, maybe offer the renewal button. ?> - + get_id() ) + && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'active' ) + && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'on-hold' ) + ) : + ?> + get_id() ); + ?> + + + + +

diff --git a/templates/single-product/add-to-cart/variable-subscription.php b/templates/single-product/add-to-cart/variable-subscription.php index 95d8ec3..70d4adf 100644 --- a/templates/single-product/add-to-cart/variable-subscription.php +++ b/templates/single-product/add-to-cart/variable-subscription.php @@ -23,9 +23,22 @@ do_action( 'woocommerce_before_add_to_cart_form' ); ?>

is_purchasable() && 0 !== $user_id && 'no' !== wcs_get_product_limitation( $product ) && wcs_is_product_limited_for_user( $product, $user_id ) ) : ?> - get_id() ); ?> - get_id(), wcs_get_product_limitation( $product ) ) && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'active' ) && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'on-hold' ) ) : // customer has an inactive subscription, maybe offer the renewal button. ?> - + get_id() ) + && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'active' ) + && ! wcs_user_has_subscription( $user_id, $product->get_id(), 'on-hold' ) + ) : + ?> + get_id() ); + ?> + + + + +

diff --git a/vendor/autoload.php b/vendor/autoload.php index 733cbb6..44ff1dc 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -14,9 +14,12 @@ if (PHP_VERSION_ID < 50600) { echo $err; } } - throw new RuntimeException($err); + trigger_error( + $err, + E_USER_ERROR + ); } require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit32625eaf0064549a4f20b6231a37a93c::getLoader(); +return ComposerAutoloaderInitcb45de1ca955f89ec737c442c7cf101c::getLoader(); diff --git a/vendor/autoload_packages.php b/vendor/autoload_packages.php deleted file mode 100644 index 0b714ef..0000000 --- a/vendor/autoload_packages.php +++ /dev/null @@ -1,13 +0,0 @@ -= 7.0. [#34192] - -## [2.12.0] - 2023-09-28 -### Added -- Add an `AutoloadGenerator::VERSION` constant, and use that for the autoloader's version in preference to whatever Composer has. [#33156] - -## [2.11.23] - 2023-09-19 - -- Minor internal updates. - -## [2.11.22] - 2023-08-23 -### Changed -- Updated package dependencies. [#32605] - -## [2.11.21] - 2023-05-22 -### Added -- Set keywords in `composer.json`. [#30756] - -## [2.11.20] - 2023-05-11 - -- Updated package dependencies - -## [2.11.19] - 2023-04-25 -### Fixed -- Fix example in README [#30225] - -## [2.11.18] - 2023-03-28 -### Changed -- Minor internal updates. - -## [2.11.17] - 2023-03-27 -### Fixed -- Don't error when processing packages specifying missing PSR paths. [#29669] - -## [2.11.16] - 2023-02-20 -### Changed -- Minor internal updates. - -## [2.11.15] - 2023-01-11 -### Changed -- Updated package dependencies. - -## [2.11.14] - 2022-12-19 -### Changed -- Use `Composer\ClassMapGenerator\ClassMapGenerator` when available (i.e. with composer 2.4). [#27812] - -### Fixed -- Declare fields for PHP 8.2 compatibility. [#27949] - -## [2.11.13] - 2022-12-02 -### Changed -- Updated package dependencies. [#27688] - -## [2.11.12] - 2022-11-22 -### Changed -- Updated package dependencies. [#27043] - -## [2.11.11] - 2022-10-25 -### Changed -- Sort data in generated `vendor/composer/jetpack_autoload_classmap.php` to avoid spurious diffs. [#26929] - -## [2.11.10] - 2022-10-05 - -- Tests: Clear `COMPOSER_AUTH` environment variable when running Composer for tests. [#26404] - -## [2.11.9] - 2022-09-27 -### Fixed -- Tests: Clear `COMPOSER_AUTH` environment variable when running Composer for tests. [#26404] - -## [2.11.8] - 2022-09-20 -### Fixed -- Tests: skip test if it requires a version of Composer not compatible with the running version of PHP. [#26143] - -## [2.11.7] - 2022-07-26 -### Changed -- Updated package dependencies. [#25158] - -## [2.11.6] - 2022-06-21 -### Changed -- Renaming `master` to `trunk`. - -## [2.11.5] - 2022-05-18 -### Fixed -- Fix new PHPCS sniffs. [#24366] - -## [2.11.4] - 2022-04-26 -### Changed -- Updated package dependencies. - -## [2.11.3] - 2022-04-19 -### Changed -- PHPCS: Fix `WordPress.Security.ValidatedSanitizedInput` - -## [2.11.2] - 2022-03-29 -### Changed -- Microperformance: Use === null instead of is_null - -## [2.11.1] - 2022-03-08 -### Removed -- Removed the Upgrade Handler. - -## [2.11.0] - 2022-03-08 -### Added -- On plugin update, pre-load all (non-PSR-4) classes from the plugin to avoid mid-upgrade fatals. - -## [2.10.13] - 2022-03-01 -### Fixed -- Fix tests for upstream phpunit change. - -## [2.10.12] - 2022-01-25 -### Changed -- Updated package dependencies. - -## [2.10.11] - 2022-01-04 -### Changed -- Switch to pcov for code coverage. -- Updated package dependencies - -## [2.10.10] - 2021-11-16 -### Added -- Soft return if autoloader chain is not available. - -## [2.10.9] - 2021-11-02 -### Changed -- Set `convertDeprecationsToExceptions` true in PHPUnit config. - -## [2.10.8] - 2021-10-13 -### Changed -- Updated package dependencies. - -## [2.10.7] - 2021-10-07 -### Changed -- Updated package dependencies - -## [2.10.6] - 2021-09-28 -### Changed -- Updated package dependencies. - -## [2.10.5] - 2021-08-31 -### Changed -- Run composer update on test-php command instead of phpunit -- Tests: update PHPUnit polyfills dependency (yoast/phpunit-polyfills). - -## [2.10.4] - 2021-08-10 -### Changed -- Updated package dependencies. - -## [2.10.3] - 2021-05-25 -### Changed -- Updated package dependencies. - -## [2.10.2] - 2021-04-27 -### Changed -- Updated package dependencies. - -## [2.10.1] - 2021-03-30 -### Added -- Composer alias for dev-master, to improve dependencies -- Tests: Added code coverage transformation - -### Changed -- Update package dependencies. - -### Fixed -- Fix coverage test -- Fix uninstallation fatal -- Update tests for changed composer 2.0.9 hash. -- Use `composer update` rather than `install` in scripts, as composer.lock isn't checked in. - -## [2.10.0] - 2021-02-09 - -- Autoloader: test suite refactor - -## [2.9.1] - 2021-02-05 - -- CI: Make tests more generic -- Autoloader: stricter type-checking on WP functions -- Autoloader: prevent transitive plugin execution - -## [2.9.0] - 2021-01-25 - -- Autoloader: revised latest autoloader inclusion semantics -- Add mirror-repo information to all current composer packages -- Monorepo: Reorganize all projects -- Autoloader: Don't cache deactivating plugins - -## [2.8.0] - 2020-12-18 - -## [2.7.1] - 2020-12-18 - -- Autoloader: Added realpath resolution to plugin paths - -## [2.7.0] - 2020-12-08 - -- Autoloader: Preemptively load unknown plugins from cache -- Removed unwanted dot -- Pin dependencies -- Packages: Update for PHP 8 testing - -## [2.6.0] - 2020-11-19 - -- Autoloader: AutoloadGenerator no longer extends Composer's AutoloadGenerator class -- Autoloader: Reuse an existing autoloader suffix if available -- Updated PHPCS: Packages and Debugger - -## [2.5.0] - 2020-10-08 - -- Autoloader: remove the defined('JETPACK_AUTOLOAD_DEV') checks from the tests - -## [2.4.0] - 2020-09-28 - -- Autoloader: remove the plugins_loaded bullet point from the README -- Packages: avoid PHPCS warnings -- Autoloader: add PSR-0 support -- Autoloader: Detect filtering of active_plugins -- Autoloader: Support unoptimized PSR-4 - -## [2.3.0] - 2020-08-21 - -- Autoloader: remove the plugin update hook - -## [2.2.0] - 2020-08-14 - -- Autoloader: don't reset the autoloader version during plugin update -- CI: Try collect js coverage - -## [2.1.0] - 2020-07-27 - -- Autoloader: convert '\' directory separators to '/' in plugin paths -- Autoloader: Avoid a PHP warning when an empty string is passed to `is_directory_plugin()`. -- Autoloader: Tests: Use a string with define - -## [2.0.2] - 2020-07-09 - -- Autoloader: Avoid a PHP warning when an empty string is passed to `is_directory_plugin()`. - -## [2.0.1] - 2020-07-02 - -- Autoloader: Tests: Use a string with define - -## [2.0.0] - 2020-06-29 - -## [2.0.0-beta] - 2020-06-29 - -- Autoloader: Support Composer v2.0 -- Autoloader: use paths to identify plugins instead of the directories -- Autoloader: fix the fatal that occurs during plugin update -- Autoloader: add fallback check for plugin path in mu-plugins -- Autoloader: use JETPACK__PLUGIN_DIR when looking for the jetpack plugin directory. -- Feature Branch: Update the Autoloader -- PHPCS: Clean up the packages -- PHPCS Updates after WPCS 2.3 - -## [1.7.0] - 2020-04-23 - -- Jetpack: Move comment notification override back to the constructor - -## [1.6.0] - 2020-03-26 - -- Autoloader: Remove file check to improve performance. - -## [1.5.0] - 2020-02-25 - -- Jetpack: instantiate manager object if it's null - -## [1.4.1] - 2020-02-14 - -- Autoloader: Load only latest version of autoload files to avoid conflicts. - -## [1.4.0] - 2020-01-23 - -- Autoloader: Remove the ignored classes - -## [1.3.8] - 2020-01-14 - -- Trying to add deterministic initialization. -- Autoloader: Remove Manager_Interface and Plugin\Tracking from ignored list -- Autoloader: Remove Jetpack_IXR_Client from ignore list - -## [1.3.7] - 2019-12-10 - -## [1.3.6] - 2019-12-09 - -- Autoloader: Use long-form sytax for array - -## [1.3.5] - 2019-11-26 - -- Fix/php notice status - -## [1.3.4] - 2019-11-08 - -- Deprecate Jetpack::is_development_mode() in favor of the packaged Status()->is_development_mode() - -## [1.3.3] - 2019-10-28 - -- Packages: Add gitattributes files to all packages that need th… - -## [1.3.2] - 2019-09-24 - -- Autoloader: Cover scenarios where composer/autoload_files.php… - -## [1.3.1] - 2019-09-20 - -- Docs: Unify usage of @package phpdoc tags - -## [1.3.0] - 2019-09-14 - -- Fix for empty namespaces. #13459 -- Connection: Move the Jetpack IXR client to the package -- Adds full connection cycle capability to the Connection package. -- Jetpack 7.5: Back compatibility package - -## [1.2.0] - 2019-06-24 - -- Jetpack DNA: Add full classmap support to Autoloader -- Move Jetpack_Sync_Main from legacy to PSR-4 - -## [1.1.0] - 2019-06-19 - -- Packages: Move autoloader tests to the package -- DNA: Move Jetpack Usage tracking to its own file -- Jetpack DNA: More isolation of Tracks Package -- Autoloader: Ignore XMLRPC_Connector if called too early -- Autoloader: Ignore Jetpack_Signature if called too early - -## 1.0.0 - 2019-06-11 - -- Add Custom Autoloader - -[5.0.10]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.9...v5.0.10 -[5.0.9]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.8...v5.0.9 -[5.0.8]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.7...v5.0.8 -[5.0.7]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.6...v5.0.7 -[5.0.6]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.5...v5.0.6 -[5.0.5]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.4...v5.0.5 -[5.0.4]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.3...v5.0.4 -[5.0.3]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.2...v5.0.3 -[5.0.2]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.1...v5.0.2 -[5.0.1]: https://github.com/Automattic/jetpack-autoloader/compare/v5.0.0...v5.0.1 -[5.0.0]: https://github.com/Automattic/jetpack-autoloader/compare/v4.0.0...v5.0.0 -[4.0.0]: https://github.com/Automattic/jetpack-autoloader/compare/v3.1.3...v4.0.0 -[3.1.3]: https://github.com/Automattic/jetpack-autoloader/compare/v3.1.2...v3.1.3 -[3.1.2]: https://github.com/Automattic/jetpack-autoloader/compare/v3.1.1...v3.1.2 -[3.1.1]: https://github.com/Automattic/jetpack-autoloader/compare/v3.1.0...v3.1.1 -[3.1.0]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.10...v3.1.0 -[3.0.10]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.9...v3.0.10 -[3.0.9]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.8...v3.0.9 -[3.0.8]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.7...v3.0.8 -[3.0.7]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.6...v3.0.7 -[3.0.6]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.5...v3.0.6 -[3.0.5]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.4...v3.0.5 -[3.0.4]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.3...v3.0.4 -[3.0.3]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.2...v3.0.3 -[3.0.2]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.1...v3.0.2 -[3.0.1]: https://github.com/Automattic/jetpack-autoloader/compare/v3.0.0...v3.0.1 -[3.0.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.12.0...v3.0.0 -[2.12.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.23...v2.12.0 -[2.11.23]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.22...v2.11.23 -[2.11.22]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.21...v2.11.22 -[2.11.21]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.20...v2.11.21 -[2.11.20]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.19...v2.11.20 -[2.11.19]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.18...v2.11.19 -[2.11.18]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.17...v2.11.18 -[2.11.17]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.16...v2.11.17 -[2.11.16]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.15...v2.11.16 -[2.11.15]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.14...v2.11.15 -[2.11.14]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.13...v2.11.14 -[2.11.13]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.12...v2.11.13 -[2.11.12]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.11...v2.11.12 -[2.11.11]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.10...v2.11.11 -[2.11.10]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.9...v2.11.10 -[2.11.9]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.8...v2.11.9 -[2.11.8]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.7...v2.11.8 -[2.11.7]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.6...v2.11.7 -[2.11.6]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.5...v2.11.6 -[2.11.5]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.4...v2.11.5 -[2.11.4]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.3...v2.11.4 -[2.11.3]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.2...v2.11.3 -[2.11.2]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.1...v2.11.2 -[2.11.1]: https://github.com/Automattic/jetpack-autoloader/compare/v2.11.0...v2.11.1 -[2.11.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.13...v2.11.0 -[2.10.13]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.12...v2.10.13 -[2.10.12]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.11...v2.10.12 -[2.10.11]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.10...v2.10.11 -[2.10.10]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.9...v2.10.10 -[2.10.9]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.8...v2.10.9 -[2.10.8]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.7...v2.10.8 -[2.10.7]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.6...v2.10.7 -[2.10.6]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.5...v2.10.6 -[2.10.5]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.4...v2.10.5 -[2.10.4]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.3...v2.10.4 -[2.10.3]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.2...v2.10.3 -[2.10.2]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.1...v2.10.2 -[2.10.1]: https://github.com/Automattic/jetpack-autoloader/compare/v2.10.0...v2.10.1 -[2.10.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.9.1...v2.10.0 -[2.9.1]: https://github.com/Automattic/jetpack-autoloader/compare/v2.9.0...v2.9.1 -[2.9.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.8.0...v2.9.0 -[2.8.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.7.1...v2.8.0 -[2.7.1]: https://github.com/Automattic/jetpack-autoloader/compare/v2.7.0...v2.7.1 -[2.7.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.6.0...v2.7.0 -[2.6.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.5.0...v2.6.0 -[2.5.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.4.0...v2.5.0 -[2.4.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.3.0...v2.4.0 -[2.3.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.2.0...v2.3.0 -[2.2.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.1.0...v2.2.0 -[2.1.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.0.2...v2.1.0 -[2.0.2]: https://github.com/Automattic/jetpack-autoloader/compare/v2.0.1...v2.0.2 -[2.0.1]: https://github.com/Automattic/jetpack-autoloader/compare/v2.0.0...v2.0.1 -[2.0.0]: https://github.com/Automattic/jetpack-autoloader/compare/v2.0.0-beta...v2.0.0 -[2.0.0-beta]: https://github.com/Automattic/jetpack-autoloader/compare/v1.7.0...v2.0.0-beta -[1.7.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.6.0...v1.7.0 -[1.6.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.5.0...v1.6.0 -[1.5.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.4.1...v1.5.0 -[1.4.1]: https://github.com/Automattic/jetpack-autoloader/compare/v1.4.0...v1.4.1 -[1.4.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.8...v1.4.0 -[1.3.8]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.7...v1.3.8 -[1.3.7]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.6...v1.3.7 -[1.3.6]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.5...v1.3.6 -[1.3.5]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.4...v1.3.5 -[1.3.4]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.3...v1.3.4 -[1.3.3]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.2...v1.3.3 -[1.3.2]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.1...v1.3.2 -[1.3.1]: https://github.com/Automattic/jetpack-autoloader/compare/v1.3.0...v1.3.1 -[1.3.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.2.0...v1.3.0 -[1.2.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.1.0...v1.2.0 -[1.1.0]: https://github.com/Automattic/jetpack-autoloader/compare/v1.0.0...v1.1.0 diff --git a/vendor/automattic/jetpack-autoloader/README.md b/vendor/automattic/jetpack-autoloader/README.md deleted file mode 100644 index 4d53925..0000000 --- a/vendor/automattic/jetpack-autoloader/README.md +++ /dev/null @@ -1,92 +0,0 @@ -A custom autoloader for Composer -===================================== - -This is a custom autoloader generator that uses a classmap to always load the latest version of a class. - -The problem this autoloader is trying to solve is conflicts that arise when two or more plugins use the same package, but one of the plugins uses an older version of said package. - -This is solved by keeping an in memory map of all the different classes that can be loaded, and updating the map with the path to the latest version of the package for the autoloader to find when we instantiate the class. - -It diverges from the default Composer autoloader setup in the following ways: - -* It creates `jetpack_autoload_classmap.php` and `jetpack_autoload_filemap.php` files in the `vendor/composer` directory. -* This file includes the version numbers from each package that is used. -* The autoloader will only load the latest version of the package no matter what plugin loads the package. This behavior is guaranteed only when every plugin that uses the package uses this autoloader. If any plugin that requires the package uses a different autoloader, this autoloader may not be able to control which version of the package is loaded. - -Usage ------ - -In your project's `composer.json`, add the following lines: - -```json -{ - "require": { - "automattic/jetpack-autoloader": "^2" - } -} -``` - -Your project must use the default composer vendor directory, `vendor`. - -After the next update/install, you will have a `vendor/autoload_packages.php` file. -Load the file in your plugin via main plugin file. - -In the main plugin you will also need to include the files like this. -```php -require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload_packages.php'; -``` - -Working with Development Versions of Packages ------ - -The autoloader will attempt to use the package with the latest semantic version. - -During development, you can force the autoloader to use development package versions by setting the `JETPACK_AUTOLOAD_DEV` constant to true. When `JETPACK_AUTOLOAD_DEV` is true, the autoloader will prefer the following versions over semantic versions: - - `9999999-dev` - - Versions with a `dev-` prefix. - - -Autoloader Limitations and Caveats ------ - -### Plugin Updates - -When moving a package class file, renaming a package class file, or changing a package class namespace, make sure that the class will not be loaded after a plugin update. - -The autoloader builds the in memory classmap as soon as the autoloader is loaded. The package class file paths in the map are not updated after a plugin update. If a plugins's package class files are moved during a plugin update and a moved file is autoloaded after the update, an error will occur. - -### Moving classes to a different package - -Jetpack Autoloader determines the hierarchy of class versions by package version numbers. It can cause problems if a class is moved to a newer package with a lower version number, it will get overshadowed by the old package. - -For instance, if your newer version of a class comes from a new package versioned 0.1.0, and the older version comes from a different package with a greater version number 2.0.1, the newer class will not get loaded. - -### Jetpack Autoloader uses transient cache - -This is a caveat to be aware of when dealing with issues. The JP Autoloader uses transients to cache a list of available plugins to speed up the lookup process. This can sometimes mask problems that arise when loading code too early. See the [Debugging](#debugging) section for more information on how to detect situations like this. - -Debugging ------ - -A common cause of confusing errors is when a plugin autoloads classes during the plugin load, before the 'plugins_loaded' hook. If that plugin has an older version of the class, that older version may be loaded before a plugin providing the newer version of the class has a chance to register. Even more confusingly, this will likely be intermittent, only showing up when the autoloader's plugin cache is invalidated. To debug this situation, you can set the `JETPACK_AUTOLOAD_DEBUG_EARLY_LOADS` constant to true. - -Another common cause of confusing errors is when a plugin registers its own autoloader at a higher priority than the Jetpack Autoloader, and that autoloader would load packages that should be handled by the Jetpack Autoloader. Setting the `JETPACK_AUTOLOAD_DEBUG_CONFLICTING_LOADERS` constant to true will check for standard Composer autoloaders with such a conflict. - - -Autoloading Standards ----- - -All new Jetpack package development should use classmap autoloading, which allows the class and file names to comply with the WordPress Coding Standards. - -### Optimized Autoloader - -An optimized autoloader is generated when: - * `composer install` or `composer update` is called with `-o` or `--optimize-autoloader` - * `composer dump-autoload` is called with `-o` or `--optimize` - -PSR-4 and PSR-0 namespaces are converted to classmaps. - -### Unoptimized Autoloader - -Supports PSR-4 autoloading. PSR-0 namespaces are converted to classmaps. - diff --git a/vendor/automattic/jetpack-autoloader/src/AutoloadFileWriter.php b/vendor/automattic/jetpack-autoloader/src/AutoloadFileWriter.php deleted file mode 100644 index 7e5122c..0000000 --- a/vendor/automattic/jetpack-autoloader/src/AutoloadFileWriter.php +++ /dev/null @@ -1,101 +0,0 @@ - '../autoload_packages.php', - ); - $ignoreList = array( - 'AutoloadGenerator.php', - 'AutoloadProcessor.php', - 'CustomAutoloaderPlugin.php', - 'ManifestGenerator.php', - 'AutoloadFileWriter.php', - ); - - // Copy all of the autoloader files. - $files = scandir( __DIR__ ); - foreach ( $files as $file ) { - // Only PHP files will be copied. - if ( substr( $file, -4 ) !== '.php' ) { - continue; - } - - if ( in_array( $file, $ignoreList, true ) ) { - continue; - } - - $newFile = $renameList[ $file ] ?? $file; - $content = self::prepareAutoloaderFile( $file, $suffix ); - - $written = file_put_contents( $outDir . '/' . $newFile, $content ); - if ( $io ) { - if ( $written ) { - $io->writeError( " Generated: $newFile" ); - } else { - $io->writeError( " Error: $newFile" ); - } - } - } - } - - /** - * Prepares an autoloader file to be written to the destination. - * - * @param String $filename a file to prepare. - * @param String $suffix Unique suffix used in the namespace. - * - * @return string - */ - private static function prepareAutoloaderFile( $filename, $suffix ) { - $header = self::COMMENT; - $header .= PHP_EOL; - if ( $suffix === 'Current' ) { - // Unit testing. - $header .= 'namespace Automattic\Jetpack\Autoloader\jpCurrent;'; - } else { - $header .= 'namespace Automattic\Jetpack\Autoloader\jp' . $suffix . '\al' . preg_replace( '/[^0-9a-zA-Z]/', '_', AutoloadGenerator::VERSION ) . ';'; - } - $header .= PHP_EOL . PHP_EOL; - - $sourceLoader = fopen( __DIR__ . '/' . $filename, 'r' ); - $file_contents = stream_get_contents( $sourceLoader ); - return str_replace( - '/* HEADER */', - $header, - $file_contents - ); - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/AutoloadGenerator.php b/vendor/automattic/jetpack-autoloader/src/AutoloadGenerator.php deleted file mode 100644 index a0e5bfb..0000000 --- a/vendor/automattic/jetpack-autoloader/src/AutoloadGenerator.php +++ /dev/null @@ -1,403 +0,0 @@ -io = $io; - $this->filesystem = new Filesystem(); - } - - /** - * Dump the Jetpack autoloader files. - * - * @param Composer $composer The Composer object. - * @param Config $config Config object. - * @param InstalledRepositoryInterface $localRepo Installed Repository object. - * @param PackageInterface $mainPackage Main Package object. - * @param InstallationManager $installationManager Manager for installing packages. - * @param string $targetDir Path to the current target directory. - * @param bool $scanPsrPackages Whether or not PSR packages should be converted to a classmap. - * @param string $suffix The autoloader suffix. - */ - public function dump( - Composer $composer, - Config $config, - InstalledRepositoryInterface $localRepo, - PackageInterface $mainPackage, - InstallationManager $installationManager, - $targetDir, - $scanPsrPackages = false, - $suffix = null - ) { - $this->filesystem->ensureDirectoryExists( $config->get( 'vendor-dir' ) ); - - $packageMap = $composer->getAutoloadGenerator()->buildPackageMap( $installationManager, $mainPackage, $localRepo->getCanonicalPackages() ); - $autoloads = $this->parseAutoloads( $packageMap, $mainPackage ); - - // Convert the autoloads into a format that the manifest generator can consume more easily. - $basePath = $this->filesystem->normalizePath( realpath( getcwd() ) ); - $vendorPath = $this->filesystem->normalizePath( realpath( $config->get( 'vendor-dir' ) ) ); - $processedAutoloads = $this->processAutoloads( $autoloads, $scanPsrPackages, $vendorPath, $basePath ); - unset( $packageMap, $autoloads ); - - // Make sure none of the legacy files remain that can lead to problems with the autoloader. - $this->removeLegacyFiles( $vendorPath ); - - // Write all of the files now that we're done. - $this->writeAutoloaderFiles( $vendorPath . '/jetpack-autoloader/', $suffix ); - $this->writeManifests( $vendorPath . '/' . $targetDir, $processedAutoloads ); - - if ( ! $scanPsrPackages ) { - $this->io->writeError( 'You are generating an unoptimized autoloader. If this is a production build, consider using the -o option.' ); - } - } - - /** - * Compiles an ordered list of namespace => path mappings - * - * @param array $packageMap Array of array(package, installDir-relative-to-composer.json). - * @param PackageInterface $mainPackage Main package instance. - * - * @return array The list of path mappings. - */ - public function parseAutoloads( array $packageMap, PackageInterface $mainPackage ) { - $rootPackageMap = array_shift( $packageMap ); - - $sortedPackageMap = $this->sortPackageMap( $packageMap ); - $sortedPackageMap[] = $rootPackageMap; - array_unshift( $packageMap, $rootPackageMap ); - - $psr0 = $this->parseAutoloadsType( $packageMap, 'psr-0', $mainPackage ); - $psr4 = $this->parseAutoloadsType( $packageMap, 'psr-4', $mainPackage ); - $classmap = $this->parseAutoloadsType( array_reverse( $sortedPackageMap ), 'classmap', $mainPackage ); - $files = $this->parseAutoloadsType( $sortedPackageMap, 'files', $mainPackage ); - - krsort( $psr0 ); - krsort( $psr4 ); - - return array( - 'psr-0' => $psr0, - 'psr-4' => $psr4, - 'classmap' => $classmap, - 'files' => $files, - ); - } - - /** - * Sorts packages by dependency weight - * - * Packages of equal weight retain the original order - * - * @param array $packageMap The package map. - * - * @return array - */ - protected function sortPackageMap( array $packageMap ) { - $packages = array(); - $paths = array(); - - foreach ( $packageMap as $item ) { - list( $package, $path ) = $item; - $name = $package->getName(); - $packages[ $name ] = $package; - $paths[ $name ] = $path; - } - - $sortedPackages = PackageSorter::sortPackages( $packages ); - - $sortedPackageMap = array(); - - foreach ( $sortedPackages as $package ) { - $name = $package->getName(); - $sortedPackageMap[] = array( $packages[ $name ], $paths[ $name ] ); - } - - return $sortedPackageMap; - } - - /** - * Returns the file identifier. - * - * @param PackageInterface $package The package instance. - * @param string $path The path. - */ - protected function getFileIdentifier( PackageInterface $package, $path ) { - return md5( $package->getName() . ':' . $path ); - } - - /** - * Returns the path code for the given path. - * - * @param Filesystem $filesystem The filesystem instance. - * @param string $basePath The base path. - * @param string $vendorPath The vendor path. - * @param string $path The path. - * - * @return string The path code. - */ - protected function getPathCode( Filesystem $filesystem, $basePath, $vendorPath, $path ) { - if ( ! $filesystem->isAbsolutePath( $path ) ) { - $path = $basePath . '/' . $path; - } - $path = $filesystem->normalizePath( $path ); - - $baseDir = ''; - if ( 0 === strpos( $path . '/', $vendorPath . '/' ) ) { - $path = substr( $path, strlen( $vendorPath ) ); - $baseDir = '$vendorDir'; - - if ( false !== $path ) { - $baseDir .= ' . '; - } - } else { - $path = $filesystem->normalizePath( $filesystem->findShortestPath( $basePath, $path, true ) ); - if ( ! $filesystem->isAbsolutePath( $path ) ) { - $baseDir = '$baseDir . '; - $path = '/' . $path; - } - } - - if ( strpos( $path, '.phar' ) !== false ) { - $baseDir = "'phar://' . " . $baseDir; - } - - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export - return $baseDir . ( ( false !== $path ) ? var_export( $path, true ) : '' ); - } - - /** - * This function differs from the composer parseAutoloadsType in that beside returning the path. - * It also return the path and the version of a package. - * - * Supports PSR-4, PSR-0, and classmap parsing. - * - * @param array $packageMap Map of all the packages. - * @param string $type Type of autoloader to use. - * @param PackageInterface $mainPackage Instance of the Package Object. - * - * @return array - */ - protected function parseAutoloadsType( array $packageMap, $type, PackageInterface $mainPackage ) { - $autoloads = array(); - - foreach ( $packageMap as $item ) { - list($package, $installPath) = $item; - $autoload = $package->getAutoload(); - $version = $package->getVersion(); // Version of the class comes from the package - should we try to parse it? - - // Store our own actual package version, not "dev-trunk" or whatever. - if ( $package->getName() === 'automattic/jetpack-autoloader' ) { - $version = self::VERSION; - } - - if ( $package === $mainPackage ) { - $autoload = array_merge_recursive( $autoload, $package->getDevAutoload() ); - } - - if ( null !== $package->getTargetDir() && $package !== $mainPackage ) { - $installPath = substr( $installPath, 0, -strlen( '/' . $package->getTargetDir() ) ); - } - - if ( in_array( $type, array( 'psr-4', 'psr-0' ), true ) && isset( $autoload[ $type ] ) && is_array( $autoload[ $type ] ) ) { - foreach ( $autoload[ $type ] as $namespace => $paths ) { - $paths = is_array( $paths ) ? $paths : array( $paths ); - foreach ( $paths as $path ) { - $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; - $autoloads[ $namespace ][] = array( - 'path' => $relativePath, - 'version' => $version, - ); - } - } - } - - if ( 'classmap' === $type && isset( $autoload['classmap'] ) && is_array( $autoload['classmap'] ) ) { - foreach ( $autoload['classmap'] as $paths ) { - $paths = is_array( $paths ) ? $paths : array( $paths ); - foreach ( $paths as $path ) { - $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; - $autoloads[] = array( - 'path' => $relativePath, - 'version' => $version, - ); - } - } - } - if ( 'files' === $type && isset( $autoload['files'] ) && is_array( $autoload['files'] ) ) { - foreach ( $autoload['files'] as $paths ) { - $paths = is_array( $paths ) ? $paths : array( $paths ); - foreach ( $paths as $path ) { - $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path; - $autoloads[ $this->getFileIdentifier( $package, $path ) ] = array( - 'path' => $relativePath, - 'version' => $version, - ); - } - } - } - } - - return $autoloads; - } - - /** - * Given Composer's autoloads this will convert them to a version that we can use to generate the manifests. - * - * When the $scanPsrPackages argument is true, PSR-4 namespaces are converted to classmaps. When $scanPsrPackages - * is false, PSR-4 namespaces are not converted to classmaps. - * - * PSR-0 namespaces are always converted to classmaps. - * - * @param array $autoloads The autoloads we want to process. - * @param bool $scanPsrPackages Whether or not PSR-4 packages should be converted to a classmap. - * @param string $vendorPath The path to the vendor directory. - * @param string $basePath The path to the current directory. - * - * @return array $processedAutoloads - */ - private function processAutoloads( $autoloads, $scanPsrPackages, $vendorPath, $basePath ) { - $processor = new AutoloadProcessor( - function ( $path, $excludedClasses, $namespace ) use ( $basePath ) { - $dir = $this->filesystem->normalizePath( - $this->filesystem->isAbsolutePath( $path ) ? $path : $basePath . '/' . $path - ); - - // Composer 2.4 changed the name of the class. - if ( class_exists( \Composer\ClassMapGenerator\ClassMapGenerator::class ) ) { - if ( ! is_dir( $dir ) && ! is_file( $dir ) ) { - return array(); - } - $generator = new \Composer\ClassMapGenerator\ClassMapGenerator(); - $generator->scanPaths( $dir, $excludedClasses, 'classmap', empty( $namespace ) ? null : $namespace ); - return $generator->getClassMap()->getMap(); - } - - return \Composer\Autoload\ClassMapGenerator::createMap( - $dir, - $excludedClasses, - null, // Don't pass the IOInterface since the normal autoload generation will have reported already. - empty( $namespace ) ? null : $namespace - ); - }, - function ( $path ) use ( $basePath, $vendorPath ) { - return $this->getPathCode( $this->filesystem, $basePath, $vendorPath, $path ); - } - ); - - return array( - 'psr-4' => $processor->processPsr4Packages( $autoloads, $scanPsrPackages ), - 'classmap' => $processor->processClassmap( $autoloads, $scanPsrPackages ), - 'files' => $processor->processFiles( $autoloads ), - ); - } - - /** - * Removes all of the legacy autoloader files so they don't cause any problems. - * - * @param string $outDir The directory legacy files are written to. - */ - private function removeLegacyFiles( $outDir ) { - $files = array( - 'autoload_functions.php', - 'class-autoloader-handler.php', - 'class-classes-handler.php', - 'class-files-handler.php', - 'class-plugins-handler.php', - 'class-version-selector.php', - ); - foreach ( $files as $file ) { - $this->filesystem->remove( $outDir . '/' . $file ); - } - } - - /** - * Writes all of the autoloader files to disk. - * - * @param string $outDir The directory to write to. - * @param string $suffix The unique autoloader suffix. - */ - private function writeAutoloaderFiles( $outDir, $suffix ) { - $this->io->writeError( "Generating jetpack autoloader ($outDir)" ); - - // We will remove all autoloader files to generate this again. - $this->filesystem->emptyDirectory( $outDir ); - - // Write the autoloader files. - AutoloadFileWriter::copyAutoloaderFiles( $this->io, $outDir, $suffix ); - } - - /** - * Writes all of the manifest files to disk. - * - * @param string $outDir The directory to write to. - * @param array $processedAutoloads The processed autoloads. - */ - private function writeManifests( $outDir, $processedAutoloads ) { - $this->io->writeError( "Generating jetpack autoloader manifests ($outDir)" ); - - $manifestFiles = array( - 'classmap' => 'jetpack_autoload_classmap.php', - 'psr-4' => 'jetpack_autoload_psr4.php', - 'files' => 'jetpack_autoload_filemap.php', - ); - - foreach ( $manifestFiles as $key => $file ) { - // Make sure the file doesn't exist so it isn't there if we don't write it. - $this->filesystem->remove( $outDir . '/' . $file ); - if ( empty( $processedAutoloads[ $key ] ) ) { - continue; - } - - $content = ManifestGenerator::buildManifest( $key, $file, $processedAutoloads[ $key ] ); - if ( empty( $content ) ) { - continue; - } - - if ( file_put_contents( $outDir . '/' . $file, $content ) ) { - $this->io->writeError( " Generated: $file" ); - } else { - $this->io->writeError( " Error: $file" ); - } - } - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php b/vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php deleted file mode 100644 index ca5ccd9..0000000 --- a/vendor/automattic/jetpack-autoloader/src/AutoloadProcessor.php +++ /dev/null @@ -1,176 +0,0 @@ -classmapScanner = $classmapScanner; - $this->pathCodeTransformer = $pathCodeTransformer; - } - - /** - * Processes the classmap autoloads into a relative path format including the version for each file. - * - * @param array $autoloads The autoloads we are processing. - * @param bool $scanPsrPackages Whether or not PSR packages should be converted to a classmap. - * - * @return array|null $processed - * @phan-param array{classmap:?array{path:string,version:string}[],psr-4:?array,psr-0:?array} $autoloads - */ - public function processClassmap( $autoloads, $scanPsrPackages ) { - // We can't scan PSR packages if we don't actually have any. - if ( empty( $autoloads['psr-4'] ) ) { - $scanPsrPackages = false; - } - - if ( empty( $autoloads['classmap'] ) && ! $scanPsrPackages ) { - return null; - } - - $excludedClasses = null; - if ( ! empty( $autoloads['exclude-from-classmap'] ) ) { - $excludedClasses = '{(' . implode( '|', $autoloads['exclude-from-classmap'] ) . ')}'; - } - - $processed = array(); - - if ( $scanPsrPackages ) { - foreach ( $autoloads['psr-4'] as $namespace => $sources ) { - $namespace = empty( $namespace ) ? null : $namespace; - - foreach ( $sources as $source ) { - $classmap = call_user_func( $this->classmapScanner, $source['path'], $excludedClasses, $namespace ); - - foreach ( $classmap as $class => $path ) { - $processed[ $class ] = array( - 'version' => $source['version'], - 'path' => call_user_func( $this->pathCodeTransformer, $path ), - ); - } - } - } - } - - /* - * PSR-0 namespaces are converted to classmaps for both optimized and unoptimized autoloaders because any new - * development should use classmap or PSR-4 autoloading. - */ - if ( ! empty( $autoloads['psr-0'] ) ) { - foreach ( $autoloads['psr-0'] as $namespace => $sources ) { - $namespace = empty( $namespace ) ? null : $namespace; - - foreach ( $sources as $source ) { - $classmap = call_user_func( $this->classmapScanner, $source['path'], $excludedClasses, $namespace ); - foreach ( $classmap as $class => $path ) { - $processed[ $class ] = array( - 'version' => $source['version'], - 'path' => call_user_func( $this->pathCodeTransformer, $path ), - ); - } - } - } - } - - if ( ! empty( $autoloads['classmap'] ) ) { - foreach ( $autoloads['classmap'] as $package ) { - $classmap = call_user_func( $this->classmapScanner, $package['path'], $excludedClasses, null ); - - foreach ( $classmap as $class => $path ) { - $processed[ $class ] = array( - 'version' => $package['version'], - 'path' => call_user_func( $this->pathCodeTransformer, $path ), - ); - } - } - } - - ksort( $processed ); - - return $processed; - } - - /** - * Processes the PSR-4 autoloads into a relative path format including the version for each file. - * - * @param array $autoloads The autoloads we are processing. - * @param bool $scanPsrPackages Whether or not PSR packages should be converted to a classmap. - * - * @return array|null $processed - */ - public function processPsr4Packages( $autoloads, $scanPsrPackages ) { - if ( $scanPsrPackages || empty( $autoloads['psr-4'] ) ) { - return null; - } - - $processed = array(); - - foreach ( $autoloads['psr-4'] as $namespace => $packages ) { - $namespace = empty( $namespace ) ? null : $namespace; - $paths = array(); - - foreach ( $packages as $package ) { - $paths[] = call_user_func( $this->pathCodeTransformer, $package['path'] ); - } - - $processed[ $namespace ] = array( - 'version' => $package['version'], - 'path' => $paths, - ); - } - - return $processed; - } - - /** - * Processes the file autoloads into a relative format including the version for each file. - * - * @param array $autoloads The autoloads we are processing. - * - * @return array|null $processed - */ - public function processFiles( $autoloads ) { - if ( empty( $autoloads['files'] ) ) { - return null; - } - - $processed = array(); - - foreach ( $autoloads['files'] as $file_id => $package ) { - $processed[ $file_id ] = array( - 'version' => $package['version'], - 'path' => call_user_func( $this->pathCodeTransformer, $package['path'] ), - ); - } - - return $processed; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php b/vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php deleted file mode 100644 index 6e29a09..0000000 --- a/vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php +++ /dev/null @@ -1,188 +0,0 @@ -composer = $composer; - $this->io = $io; - } - - /** - * Do nothing. - * phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - * - * @param Composer $composer Composer object. - * @param IOInterface $io IO object. - */ - public function deactivate( Composer $composer, IOInterface $io ) { - /* - * Intentionally left empty. This is a PluginInterface method. - * phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - */ - } - - /** - * Do nothing. - * phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - * - * @param Composer $composer Composer object. - * @param IOInterface $io IO object. - */ - public function uninstall( Composer $composer, IOInterface $io ) { - /* - * Intentionally left empty. This is a PluginInterface method. - * phpcs:enable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - */ - } - - /** - * Tell composer to listen for events and do something with them. - * - * @return array List of subscribed events. - */ - public static function getSubscribedEvents() { - return array( - ScriptEvents::POST_AUTOLOAD_DUMP => 'postAutoloadDump', - ); - } - - /** - * Generate the custom autolaoder. - * - * @param Event $event Script event object. - */ - public function postAutoloadDump( Event $event ) { - // When the autoloader is not required by the root package we don't want to execute it. - // This prevents unwanted transitive execution that generates unused autoloaders or - // at worst throws fatal executions. - if ( ! $this->isRequiredByRoot() ) { - return; - } - - $config = $this->composer->getConfig(); - - if ( 'vendor' !== $config->raw()['config']['vendor-dir'] ) { - $this->io->writeError( "\nAn error occurred while generating the autoloader files:", true ); - $this->io->writeError( 'The project\'s composer.json or composer environment set a non-default vendor directory.', true ); - $this->io->writeError( 'The default composer vendor directory must be used.', true ); - exit( 0 ); - } - - $installationManager = $this->composer->getInstallationManager(); - $repoManager = $this->composer->getRepositoryManager(); - $localRepo = $repoManager->getLocalRepository(); - $package = $this->composer->getPackage(); - $optimize = $event->getFlags()['optimize']; - $suffix = $this->determineSuffix(); - - $generator = new AutoloadGenerator( $this->io ); - $generator->dump( $this->composer, $config, $localRepo, $package, $installationManager, 'composer', $optimize, $suffix ); - } - - /** - * Determine the suffix for the autoloader class. - * - * Reuses an existing suffix from vendor/autoload_packages.php or vendor/autoload.php if possible. - * - * @return string Suffix. - */ - private function determineSuffix() { - $config = $this->composer->getConfig(); - $vendorPath = $config->get( 'vendor-dir' ); - - // Command line. - $suffix = $config->get( 'autoloader-suffix' ); - if ( $suffix ) { - return $suffix; - } - - // Reuse our own suffix, if any. - if ( is_readable( $vendorPath . '/autoload_packages.php' ) ) { - $content = file_get_contents( $vendorPath . '/autoload_packages.php' ); - if ( preg_match( '/^namespace Automattic\\\\Jetpack\\\\Autoloader\\\\jp([^;\s]+?)(?:\\\\al[^;\s]+)?;/m', $content, $match ) ) { - return $match[1]; - } - } - - // Reuse Composer's suffix, if any. - if ( is_readable( $vendorPath . '/autoload.php' ) ) { - $content = file_get_contents( $vendorPath . '/autoload.php' ); - if ( preg_match( '{ComposerAutoloaderInit([^:\s]+)::}', $content, $match ) ) { - return $match[1]; - } - } - - // Generate a random suffix. - return md5( uniqid( '', true ) ); - } - - /** - * Checks to see whether or not the root package is the one that required the autoloader. - * - * @return bool - */ - private function isRequiredByRoot() { - $package = $this->composer->getPackage(); - $requires = $package->getRequires(); - if ( ! is_array( $requires ) ) { // @phan-suppress-current-line PhanRedundantCondition -- Earlier Composer versions may not have guaranteed this. - $requires = array(); - } - $devRequires = $package->getDevRequires(); - if ( ! is_array( $devRequires ) ) { // @phan-suppress-current-line PhanRedundantCondition -- Earlier Composer versions may not have guaranteed this. - $devRequires = array(); - } - $requires = array_merge( $requires, $devRequires ); - - if ( empty( $requires ) ) { - $this->io->writeError( "\nThe package is not required and this should never happen?", true ); - exit( 0 ); - } - - foreach ( $requires as $require ) { - if ( 'automattic/jetpack-autoloader' === $require->getTarget() ) { - return true; - } - } - - return false; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php b/vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php deleted file mode 100644 index 254d46a..0000000 --- a/vendor/automattic/jetpack-autoloader/src/ManifestGenerator.php +++ /dev/null @@ -1,115 +0,0 @@ - $data ) { - $key = var_export( $key, true ); - $versionCode = var_export( $data['version'], true ); - $fileContent .= << array( - 'version' => $versionCode, - 'path' => {$data['path']} - ), -MANIFEST_CODE; - $fileContent .= PHP_EOL; - } - - return self::buildFile( $fileName, $fileContent ); - } - - /** - * Builds the contents for the PSR-4 manifest file. - * - * @param string $fileName The filename we are building. - * @param array $namespaces The formatted PSR-4 data for the manifest. - * - * @return string|null $manifestFile - */ - private static function buildPsr4Manifest( $fileName, $namespaces ) { - $fileContent = PHP_EOL; - foreach ( $namespaces as $namespace => $data ) { - $namespaceCode = var_export( $namespace, true ); - $versionCode = var_export( $data['version'], true ); - $pathCode = 'array( ' . implode( ', ', $data['path'] ) . ' )'; - $fileContent .= << array( - 'version' => $versionCode, - 'path' => $pathCode - ), -MANIFEST_CODE; - $fileContent .= PHP_EOL; - } - - return self::buildFile( $fileName, $fileContent ); - } - - /** - * Generate the PHP that will be used in the file. - * - * @param string $fileName The filename we are building. - * @param string $content The content to be written into the file. - * - * @return string $fileContent - */ - private static function buildFile( $fileName, $content ) { - return <<php_autoloader = $php_autoloader; - $this->hook_manager = $hook_manager; - $this->manifest_reader = $manifest_reader; - $this->version_selector = $version_selector; - } - - /** - * Checks to see whether or not an autoloader is currently in the process of initializing. - * - * @return bool - */ - public function is_initializing() { - // If no version has been set it means that no autoloader has started initializing yet. - global $jetpack_autoloader_latest_version; - if ( ! isset( $jetpack_autoloader_latest_version ) ) { - return false; - } - - // When the version is set but the classmap is not it ALWAYS means that this is the - // latest autoloader and is being included by an older one. - global $jetpack_packages_classmap; - if ( empty( $jetpack_packages_classmap ) ) { - return true; - } - - // Version 2.4.0 added a new global and altered the reset semantics. We need to check - // the other global as well since it may also point at initialization. - // Note: We don't need to check for the class first because every autoloader that - // will set the latest version global requires this class in the classmap. - $replacing_version = $jetpack_packages_classmap[ AutoloadGenerator::class ]['version']; - if ( $this->version_selector->is_dev_version( $replacing_version ) || version_compare( $replacing_version, '2.4.0.0', '>=' ) ) { - global $jetpack_autoloader_loader; - if ( ! isset( $jetpack_autoloader_loader ) ) { - return true; - } - } - - return false; - } - - /** - * Activates an autoloader using the given plugins and activates it. - * - * @param string[] $plugins The plugins to initialize the autoloader for. - */ - public function activate_autoloader( $plugins ) { - global $jetpack_packages_psr4; - $jetpack_packages_psr4 = array(); - $this->manifest_reader->read_manifests( $plugins, 'vendor/composer/jetpack_autoload_psr4.php', $jetpack_packages_psr4 ); - - global $jetpack_packages_classmap; - $jetpack_packages_classmap = array(); - $this->manifest_reader->read_manifests( $plugins, 'vendor/composer/jetpack_autoload_classmap.php', $jetpack_packages_classmap ); - - global $jetpack_packages_filemap; - $jetpack_packages_filemap = array(); - $this->manifest_reader->read_manifests( $plugins, 'vendor/composer/jetpack_autoload_filemap.php', $jetpack_packages_filemap ); - - $loader = new Version_Loader( - $this->version_selector, - $jetpack_packages_classmap, - $jetpack_packages_psr4, - $jetpack_packages_filemap - ); - - $this->php_autoloader->register_autoloader( $loader ); - - // Now that the autoloader is active we can load the filemap. - $loader->load_filemap(); - } - - /** - * Resets the active autoloader and all related global state. - */ - public function reset_autoloader() { - $this->php_autoloader->unregister_autoloader(); - $this->hook_manager->reset(); - - // Clear all of the autoloader globals so that older autoloaders don't do anything strange. - global $jetpack_autoloader_latest_version; - $jetpack_autoloader_latest_version = null; - - global $jetpack_packages_classmap; - $jetpack_packages_classmap = array(); // Must be array to avoid exceptions in old autoloaders! - - global $jetpack_packages_psr4; - $jetpack_packages_psr4 = array(); // Must be array to avoid exceptions in old autoloaders! - - global $jetpack_packages_filemap; - $jetpack_packages_filemap = array(); // Must be array to avoid exceptions in old autoloaders! - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php b/vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php deleted file mode 100644 index 9082226..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-autoloader-locator.php +++ /dev/null @@ -1,82 +0,0 @@ -version_selector = $version_selector; - } - - /** - * Finds the path to the plugin with the latest autoloader. - * - * @param array $plugin_paths An array of plugin paths. - * @param string $latest_version The latest version reference. @phan-output-reference. - * - * @return string|null - */ - public function find_latest_autoloader( $plugin_paths, &$latest_version ) { - $latest_plugin = null; - - foreach ( $plugin_paths as $plugin_path ) { - $version = $this->get_autoloader_version( $plugin_path ); - if ( ! $version || ! $this->version_selector->is_version_update_required( $latest_version, $version ) ) { - continue; - } - - $latest_version = $version; - $latest_plugin = $plugin_path; - } - - return $latest_plugin; - } - - /** - * Gets the path to the autoloader. - * - * @param string $plugin_path The path to the plugin. - * - * @return string - */ - public function get_autoloader_path( $plugin_path ) { - return trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; - } - - /** - * Gets the version for the autoloader. - * - * @param string $plugin_path The path to the plugin. - * - * @return string|null - */ - public function get_autoloader_version( $plugin_path ) { - $classmap = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; - if ( ! file_exists( $classmap ) ) { - return null; - } - - $classmap = require $classmap; - if ( isset( $classmap[ AutoloadGenerator::class ] ) ) { - return $classmap[ AutoloadGenerator::class ]['version']; - } - - return null; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-autoloader.php b/vendor/automattic/jetpack-autoloader/src/class-autoloader.php deleted file mode 100644 index c9b6608..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-autoloader.php +++ /dev/null @@ -1,85 +0,0 @@ -get( Autoloader_Handler::class ); - - // If the autoloader is already initializing it means that it has included us as the latest. - $was_included_by_autoloader = $autoloader_handler->is_initializing(); - - /** @var Plugin_Locator $plugin_locator */ - $plugin_locator = $container->get( Plugin_Locator::class ); - - /** @var Plugins_Handler $plugins_handler */ - $plugins_handler = $container->get( Plugins_Handler::class ); - - // The current plugin is the one that we are attempting to initialize here. - $current_plugin = $plugin_locator->find_current_plugin(); - - // The active plugins are those that we were able to discover on the site. This list will not - // include mu-plugins, those activated by code, or those who are hidden by filtering. We also - // want to take care to not consider the current plugin unknown if it was included by an - // autoloader. This avoids the case where a plugin will be marked "active" while deactivated - // due to it having the latest autoloader. - $active_plugins = $plugins_handler->get_active_plugins( true, ! $was_included_by_autoloader ); - - // The cached plugins are all of those that were active or discovered by the autoloader during a previous request. - // Note that it's possible this list will include plugins that have since been deactivated, but after a request - // the cache should be updated and the deactivated plugins will be removed. - $cached_plugins = $plugins_handler->get_cached_plugins(); - - // We combine the active list and cached list to preemptively load classes for plugins that are - // presently unknown but will be loaded during the request. While this may result in us considering packages in - // deactivated plugins there shouldn't be any problems as a result and the eventual consistency is sufficient. - $all_plugins = array_merge( $active_plugins, $cached_plugins ); - - // In particular we also include the current plugin to address the case where it is the latest autoloader - // but also unknown (and not cached). We don't want it in the active list because we don't know that it - // is active but we need it in the all plugins list so that it is considered by the autoloader. - $all_plugins[] = $current_plugin; - - // We require uniqueness in the array to avoid processing the same plugin more than once. - $all_plugins = array_values( array_unique( $all_plugins ) ); - - /** @var Latest_Autoloader_Guard $guard */ - $guard = $container->get( Latest_Autoloader_Guard::class ); - if ( $guard->should_stop_init( $current_plugin, $all_plugins, $was_included_by_autoloader ) ) { - return; - } - - // Initialize the autoloader using the handler now that we're ready. - $autoloader_handler->activate_autoloader( $all_plugins ); - - /** @var Hook_Manager $hook_manager */ - $hook_manager = $container->get( Hook_Manager::class ); - - // Register a shutdown handler to clean up the autoloader. - $hook_manager->add_action( 'shutdown', new Shutdown_Handler( $plugins_handler, $cached_plugins, $was_included_by_autoloader ) ); - - // Register a plugins_loaded handler to check for conflicting autoloaders. - $hook_manager->add_action( 'plugins_loaded', array( $guard, 'check_for_conflicting_autoloaders' ), 1 ); - - // phpcs:enable Generic.Commenting.DocComment.MissingShort - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-container.php b/vendor/automattic/jetpack-autoloader/src/class-container.php deleted file mode 100644 index 19ea95c..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-container.php +++ /dev/null @@ -1,142 +0,0 @@ - 'Hook_Manager', - ); - - /** - * A map of all the dependencies we've registered with the container and created. - * - * @var array - */ - protected $dependencies; - - /** - * The constructor. - */ - public function __construct() { - $this->dependencies = array(); - - $this->register_shared_dependencies(); - $this->register_dependencies(); - $this->initialize_globals(); - } - - /** - * Gets a dependency out of the container. - * - * @param string $class The class to fetch. - * - * @return mixed - * @throws \InvalidArgumentException When a class that isn't registered with the container is fetched. - */ - public function get( $class ) { - if ( ! isset( $this->dependencies[ $class ] ) ) { - throw new \InvalidArgumentException( "Class '$class' is not registered with the container." ); - } - - return $this->dependencies[ $class ]; - } - - /** - * Registers all of the dependencies that are shared between all instances of the autoloader. - */ - private function register_shared_dependencies() { - global $jetpack_autoloader_container_shared; - if ( ! isset( $jetpack_autoloader_container_shared ) ) { - $jetpack_autoloader_container_shared = array(); - } - - $key = self::SHARED_DEPENDENCY_KEYS[ Hook_Manager::class ]; - if ( ! isset( $jetpack_autoloader_container_shared[ $key ] ) ) { - require_once __DIR__ . '/class-hook-manager.php'; - $jetpack_autoloader_container_shared[ $key ] = new Hook_Manager(); - } - $this->dependencies[ Hook_Manager::class ] = &$jetpack_autoloader_container_shared[ $key ]; - } - - /** - * Registers all of the dependencies with the container. - */ - private function register_dependencies() { - require_once __DIR__ . '/class-path-processor.php'; - $this->dependencies[ Path_Processor::class ] = new Path_Processor(); - - require_once __DIR__ . '/class-plugin-locator.php'; - $this->dependencies[ Plugin_Locator::class ] = new Plugin_Locator( - $this->get( Path_Processor::class ) - ); - - require_once __DIR__ . '/class-version-selector.php'; - $this->dependencies[ Version_Selector::class ] = new Version_Selector(); - - require_once __DIR__ . '/class-autoloader-locator.php'; - $this->dependencies[ Autoloader_Locator::class ] = new Autoloader_Locator( - $this->get( Version_Selector::class ) - ); - - require_once __DIR__ . '/class-php-autoloader.php'; - $this->dependencies[ PHP_Autoloader::class ] = new PHP_Autoloader(); - - require_once __DIR__ . '/class-manifest-reader.php'; - $this->dependencies[ Manifest_Reader::class ] = new Manifest_Reader( - $this->get( Version_Selector::class ) - ); - - require_once __DIR__ . '/class-plugins-handler.php'; - $this->dependencies[ Plugins_Handler::class ] = new Plugins_Handler( - $this->get( Plugin_Locator::class ), - $this->get( Path_Processor::class ) - ); - - require_once __DIR__ . '/class-autoloader-handler.php'; - $this->dependencies[ Autoloader_Handler::class ] = new Autoloader_Handler( - $this->get( PHP_Autoloader::class ), - $this->get( Hook_Manager::class ), - $this->get( Manifest_Reader::class ), - $this->get( Version_Selector::class ) - ); - - require_once __DIR__ . '/class-latest-autoloader-guard.php'; - $this->dependencies[ Latest_Autoloader_Guard::class ] = new Latest_Autoloader_Guard( - $this->get( Plugins_Handler::class ), - $this->get( Autoloader_Handler::class ), - $this->get( Autoloader_Locator::class ) - ); - - // Register any classes that we will use elsewhere. - require_once __DIR__ . '/class-version-loader.php'; - require_once __DIR__ . '/class-shutdown-handler.php'; - } - - /** - * Initializes any of the globals needed by the autoloader. - */ - private function initialize_globals() { - /* - * This global was retired in version 2.9. The value is set to 'false' to maintain - * compatibility with older versions of the autoloader. - */ - global $jetpack_autoloader_including_latest; - $jetpack_autoloader_including_latest = false; - - // Not all plugins can be found using the locator. In cases where a plugin loads the autoloader - // but was not discoverable, we will record them in this array to track them as "active". - global $jetpack_autoloader_activating_plugins_paths; - if ( ! isset( $jetpack_autoloader_activating_plugins_paths ) ) { - $jetpack_autoloader_activating_plugins_paths = array(); - } - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-hook-manager.php b/vendor/automattic/jetpack-autoloader/src/class-hook-manager.php deleted file mode 100644 index 1d64c75..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-hook-manager.php +++ /dev/null @@ -1,68 +0,0 @@ -registered_hooks = array(); - } - - /** - * Adds an action to WordPress and registers it internally. - * - * @param string $tag The name of the action which is hooked. - * @param callable $callable The function to call. - * @param int $priority Used to specify the priority of the action. - * @param int $accepted_args Used to specify the number of arguments the callable accepts. - */ - public function add_action( $tag, $callable, $priority = 10, $accepted_args = 1 ) { - $this->registered_hooks[ $tag ][] = array( - 'priority' => $priority, - 'callable' => $callable, - ); - - add_action( $tag, $callable, $priority, $accepted_args ); - } - - /** - * Adds a filter to WordPress and registers it internally. - * - * @param string $tag The name of the filter which is hooked. - * @param callable $callable The function to call. - * @param int $priority Used to specify the priority of the filter. - * @param int $accepted_args Used to specify the number of arguments the callable accepts. - */ - public function add_filter( $tag, $callable, $priority = 10, $accepted_args = 1 ) { - $this->registered_hooks[ $tag ][] = array( - 'priority' => $priority, - 'callable' => $callable, - ); - - add_filter( $tag, $callable, $priority, $accepted_args ); - } - - /** - * Removes all of the registered hooks. - */ - public function reset() { - foreach ( $this->registered_hooks as $tag => $hooks ) { - foreach ( $hooks as $hook ) { - remove_filter( $tag, $hook['callable'], $hook['priority'] ); - } - } - $this->registered_hooks = array(); - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-latest-autoloader-guard.php b/vendor/automattic/jetpack-autoloader/src/class-latest-autoloader-guard.php deleted file mode 100644 index 285fe73..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-latest-autoloader-guard.php +++ /dev/null @@ -1,157 +0,0 @@ -plugins_handler = $plugins_handler; - $this->autoloader_handler = $autoloader_handler; - $this->autoloader_locator = $autoloader_locator; - } - - /** - * Indicates whether or not the autoloader should be initialized. Note that this function - * has the side-effect of actually loading the latest autoloader in the event that this - * is not it. - * - * @param string $current_plugin The current plugin we're checking. - * @param string[] $plugins The active plugins to check for autoloaders in. - * @param bool $was_included_by_autoloader Indicates whether or not this autoloader was included by another. - * - * @return bool True if we should stop initialization, otherwise false. - */ - public function should_stop_init( $current_plugin, $plugins, $was_included_by_autoloader ) { - global $jetpack_autoloader_latest_version; - - // We need to reset the autoloader when the plugins change because - // that means the autoloader was generated with a different list. - if ( $this->plugins_handler->have_plugins_changed( $plugins ) ) { - $this->autoloader_handler->reset_autoloader(); - } - - // When the latest autoloader has already been found we don't need to search for it again. - // We should take care however because this will also trigger if the autoloader has been - // included by an older one. - if ( isset( $jetpack_autoloader_latest_version ) && ! $was_included_by_autoloader ) { - return true; - } - - $latest_plugin = $this->autoloader_locator->find_latest_autoloader( $plugins, $jetpack_autoloader_latest_version ); - if ( isset( $latest_plugin ) && $latest_plugin !== $current_plugin ) { - require $this->autoloader_locator->get_autoloader_path( $latest_plugin ); - return true; - } - - return false; - } - - /** - * Check for conflicting autoloaders. - * - * A common source of strange and confusing problems is when another plugin - * registers a Composer autoloader at a higher priority that us. If enabled, - * check for this problem and warn about it. - * - * Called from the plugins_loaded hook. - * - * @since 3.1.0 - * @return void - */ - public function check_for_conflicting_autoloaders() { - if ( ! defined( 'JETPACK_AUTOLOAD_DEBUG_CONFLICTING_LOADERS' ) || ! JETPACK_AUTOLOAD_DEBUG_CONFLICTING_LOADERS ) { - return; - } - - global $jetpack_autoloader_loader; - if ( ! isset( $jetpack_autoloader_loader ) ) { - return; - } - $prefixes = array(); - foreach ( ( $jetpack_autoloader_loader->get_class_map() ?? array() ) as $classname => $data ) { - $parts = explode( '\\', trim( $classname, '\\' ) ); - array_pop( $parts ); - while ( $parts ) { - $prefixes[ implode( '\\', $parts ) . '\\' ] = true; - array_pop( $parts ); - } - } - foreach ( ( $jetpack_autoloader_loader->get_psr4_map() ?? array() ) as $prefix => $data ) { - $parts = explode( '\\', trim( $prefix, '\\' ) ); - while ( $parts ) { - $prefixes[ implode( '\\', $parts ) . '\\' ] = true; - array_pop( $parts ); - } - } - - $autoload_chain = spl_autoload_functions(); - if ( ! $autoload_chain ) { - return; - } - - foreach ( $autoload_chain as $autoloader ) { - // No need to check anything after us. - if ( is_array( $autoloader ) && is_string( $autoloader[0] ) && substr( $autoloader[0], 0, strlen( __NAMESPACE__ ) + 1 ) === __NAMESPACE__ . '\\' ) { - break; - } - - // We can check Composer autoloaders easily enough. - if ( is_array( $autoloader ) && $autoloader[0] instanceof \Composer\Autoload\ClassLoader && is_callable( array( $autoloader[0], 'getPrefixesPsr4' ) ) ) { - $composer_autoloader = $autoloader[0]; - foreach ( $composer_autoloader->getClassMap() as $classname => $path ) { - if ( $jetpack_autoloader_loader->find_class_file( $classname ) ) { - $msg = "A Composer autoloader is registered with a higher priority than the Jetpack Autoloader and would also handle some of the classes we handle (e.g. $classname => $path). This may cause strange and confusing problems."; - wp_trigger_error( '', $msg ); - continue 2; - } - } - foreach ( $composer_autoloader->getPrefixesPsr4() as $prefix => $paths ) { - if ( isset( $prefixes[ $prefix ] ) ) { - $path = array_pop( $paths ); - $msg = "A Composer autoloader is registered with a higher priority than the Jetpack Autoloader and would also handle some of the namespaces we handle (e.g. $prefix => $path). This may cause strange and confusing problems."; - wp_trigger_error( '', $msg ); - continue 2; - } - } - foreach ( $composer_autoloader->getPrefixes() as $prefix => $paths ) { - if ( isset( $prefixes[ $prefix ] ) ) { - $path = array_pop( $paths ); - $msg = "A Composer autoloader is registered with a higher priority than the Jetpack Autoloader and would also handle some of the namespaces we handle (e.g. $prefix => $path). This may cause strange and confusing problems."; - wp_trigger_error( '', $msg ); - continue 2; - } - } - } - } - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-manifest-reader.php b/vendor/automattic/jetpack-autoloader/src/class-manifest-reader.php deleted file mode 100644 index 8eb4825..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-manifest-reader.php +++ /dev/null @@ -1,91 +0,0 @@ -version_selector = $version_selector; - } - - /** - * Reads all of the manifests in the given plugin paths. - * - * @param array $plugin_paths The paths to the plugins we're loading the manifest in. - * @param string $manifest_path The path that we're loading the manifest from in each plugin. - * @param array $path_map The path map to add the contents of the manifests to. - * - * @return array $path_map The path map we've built using the manifests in each plugin. - */ - public function read_manifests( $plugin_paths, $manifest_path, &$path_map ) { - $file_paths = array_map( - function ( $path ) use ( $manifest_path ) { - return trailingslashit( $path ) . $manifest_path; - }, - $plugin_paths - ); - - foreach ( $file_paths as $path ) { - $this->register_manifest( $path, $path_map ); - } - - return $path_map; - } - - /** - * Registers a plugin's manifest file with the path map. - * - * @param string $manifest_path The absolute path to the manifest that we're loading. - * @param array $path_map The path map to add the contents of the manifest to. - */ - protected function register_manifest( $manifest_path, &$path_map ) { - if ( ! is_readable( $manifest_path ) ) { - return; - } - - $manifest = require $manifest_path; - if ( ! is_array( $manifest ) ) { - return; - } - - foreach ( $manifest as $key => $data ) { - $this->register_record( $key, $data, $path_map ); - } - } - - /** - * Registers an entry from the manifest in the path map. - * - * @param string $key The identifier for the entry we're registering. - * @param array $data The data for the entry we're registering. - * @param array $path_map The path map to add the contents of the manifest to. - */ - protected function register_record( $key, $data, &$path_map ) { - if ( isset( $path_map[ $key ]['version'] ) ) { - $selected_version = $path_map[ $key ]['version']; - } else { - $selected_version = null; - } - - if ( $this->version_selector->is_version_update_required( $selected_version, $data['version'] ) ) { - $path_map[ $key ] = array( - 'version' => $data['version'], - 'path' => $data['path'], - ); - } - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-path-processor.php b/vendor/automattic/jetpack-autoloader/src/class-path-processor.php deleted file mode 100644 index 4763274..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-path-processor.php +++ /dev/null @@ -1,186 +0,0 @@ -get_normalized_constants(); - foreach ( $constants as $constant => $constant_path ) { - $len = strlen( $constant_path ); - if ( substr( $path, 0, $len ) !== $constant_path ) { - continue; - } - - return substr_replace( $path, '{{' . $constant . '}}', 0, $len ); - } - - return $path; - } - - /** - * Given a path this will replace any of the path constant tokens with the expanded path. - * - * @param string $tokenized_path The path we want to process. - * - * @return string The expanded path. - */ - public function untokenize_path_constants( $tokenized_path ) { - $tokenized_path = wp_normalize_path( $tokenized_path ); - - $constants = $this->get_normalized_constants(); - foreach ( $constants as $constant => $constant_path ) { - $constant = '{{' . $constant . '}}'; - - $len = strlen( $constant ); - if ( substr( $tokenized_path, 0, $len ) !== $constant ) { - continue; - } - - return $this->get_real_path( substr_replace( $tokenized_path, $constant_path, 0, $len ) ); - } - - return $tokenized_path; - } - - /** - * Given a file and an array of places it might be, this will find the absolute path and return it. - * - * @param string $file The plugin or theme file to resolve. - * @param array $directories_to_check The directories we should check for the file if it isn't an absolute path. - * - * @return string|false Returns the absolute path to the directory, otherwise false. - */ - public function find_directory_with_autoloader( $file, $directories_to_check ) { - $file = wp_normalize_path( $file ); - - if ( ! $this->is_absolute_path( $file ) ) { - $file = $this->find_absolute_plugin_path( $file, $directories_to_check ); - if ( ! isset( $file ) ) { - return false; - } - } - - // We need the real path for consistency with __DIR__ paths. - $file = $this->get_real_path( $file ); - - // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged - $directory = @is_file( $file ) ? dirname( $file ) : $file; - if ( ! @is_file( $directory . '/vendor/composer/jetpack_autoload_classmap.php' ) ) { - return false; - } - // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged - - return $directory; - } - - /** - * Fetches an array of normalized paths keyed by the constant they came from. - * - * @return string[] The normalized paths keyed by the constant. - */ - private function get_normalized_constants() { - $raw_constants = array( - // Order the constants from most-specific to least-specific. - 'WP_PLUGIN_DIR', - 'WPMU_PLUGIN_DIR', - 'WP_CONTENT_DIR', - 'ABSPATH', - ); - - $constants = array(); - foreach ( $raw_constants as $raw ) { - if ( ! defined( $raw ) ) { - continue; - } - - $path = wp_normalize_path( constant( $raw ) ); - if ( isset( $path ) ) { - $constants[ $raw ] = $path; - } - } - - return $constants; - } - - /** - * Indicates whether or not a path is absolute. - * - * @param string $path The path to check. - * - * @return bool True if the path is absolute, otherwise false. - */ - private function is_absolute_path( $path ) { - if ( empty( $path ) || 0 === strlen( $path ) || '.' === $path[0] ) { - return false; - } - - // Absolute paths on Windows may begin with a drive letter. - if ( preg_match( '/^[a-zA-Z]:[\/\\\\]/', $path ) ) { - return true; - } - - // A path starting with / or \ is absolute; anything else is relative. - return ( '/' === $path[0] || '\\' === $path[0] ); - } - - /** - * Given a file and a list of directories to check, this method will try to figure out - * the absolute path to the file in question. - * - * @param string $normalized_path The normalized path to the plugin or theme file to resolve. - * @param array $directories_to_check The directories we should check for the file if it isn't an absolute path. - * - * @return string|null The absolute path to the plugin file, otherwise null. - */ - private function find_absolute_plugin_path( $normalized_path, $directories_to_check ) { - // We're only able to find the absolute path for plugin/theme PHP files. - if ( ! is_string( $normalized_path ) || '.php' !== substr( $normalized_path, -4 ) ) { - return null; - } - - foreach ( $directories_to_check as $directory ) { - $normalized_check = wp_normalize_path( trailingslashit( $directory ) ) . $normalized_path; - // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged - if ( @is_file( $normalized_check ) ) { - return $normalized_check; - } - } - - return null; - } - - /** - * Given a path this will figure out the real path that we should be using. - * - * @param string $path The path to resolve. - * - * @return string The resolved path. - */ - private function get_real_path( $path ) { - // We want to resolve symbolic links for consistency with __DIR__ paths. - // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged - $real_path = @realpath( $path ); - if ( false === $real_path ) { - // Let the autoloader deal with paths that don't exist. - $real_path = $path; - } - - // Using realpath will make it platform-specific so we must normalize it after. - if ( $path !== $real_path ) { - $real_path = wp_normalize_path( $real_path ); - } - - return $real_path; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-php-autoloader.php b/vendor/automattic/jetpack-autoloader/src/class-php-autoloader.php deleted file mode 100644 index f8765a4..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-php-autoloader.php +++ /dev/null @@ -1,97 +0,0 @@ -unregister_autoloader(); - - // Set the global so that it can be used to load classes. - global $jetpack_autoloader_loader; - $jetpack_autoloader_loader = $version_loader; - - // Ensure that the autoloader is first to avoid contention with others. - spl_autoload_register( array( self::class, 'load_class' ), true, true ); - } - - /** - * Unregisters the active autoloader so that it will no longer autoload classes. - */ - public function unregister_autoloader() { - // Remove any v2 autoloader that we've already registered. - $autoload_chain = spl_autoload_functions(); - if ( ! $autoload_chain ) { - return; - } - foreach ( $autoload_chain as $autoloader ) { - // We can identify a v2 autoloader using the namespace. - $namespace_check = null; - - // Functions are recorded as strings. - if ( is_string( $autoloader ) ) { - $namespace_check = $autoloader; - } elseif ( is_array( $autoloader ) && is_string( $autoloader[0] ) ) { - // Static method calls have the class as the first array element. - $namespace_check = $autoloader[0]; - } else { - // Since the autoloader has only ever been a function or a static method we don't currently need to check anything else. - continue; - } - - // Check for the namespace without the generated suffix. - if ( 'Automattic\\Jetpack\\Autoloader\\jp' === substr( $namespace_check, 0, 32 ) ) { - spl_autoload_unregister( $autoloader ); - } - } - - // Clear the global now that the autoloader has been unregistered. - global $jetpack_autoloader_loader; - $jetpack_autoloader_loader = null; - } - - /** - * Loads a class file if one could be found. - * - * Note: This function is static so that the autoloader can be easily unregistered. If - * it was a class method we would have to unwrap the object to check the namespace. - * - * @param string $class_name The name of the class to autoload. - * - * @return bool Indicates whether or not a class file was loaded. - */ - public static function load_class( $class_name ) { - global $jetpack_autoloader_loader; - if ( ! isset( $jetpack_autoloader_loader ) ) { - return false; - } - - $file = $jetpack_autoloader_loader->find_class_file( $class_name ); - if ( ! isset( $file ) ) { - return false; - } - - // A common source of strange and confusing problems is when a vendor - // file is autoloaded before all plugins have had a chance to register - // with the autoloader. Detect that, if a development constant is set. - if ( defined( 'JETPACK_AUTOLOAD_DEBUG_EARLY_LOADS' ) && JETPACK_AUTOLOAD_DEBUG_EARLY_LOADS && - ( strpos( $file, '/vendor/' ) !== false || strpos( $file, '/jetpack_vendor/' ) !== false ) && - is_callable( 'did_action' ) && ! did_action( 'plugins_loaded' ) - ) { - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_wp_debug_backtrace_summary -- This is a debug log message. - $msg = "Jetpack Autoloader: Autoloading `$class_name` before the plugins_loaded hook may cause strange and confusing problems. " . wp_debug_backtrace_summary( '', 1 ); - wp_trigger_error( '', $msg ); - } - - require $file; - return true; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-plugin-locator.php b/vendor/automattic/jetpack-autoloader/src/class-plugin-locator.php deleted file mode 100644 index 8dafeff..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-plugin-locator.php +++ /dev/null @@ -1,145 +0,0 @@ -path_processor = $path_processor; - } - - /** - * Finds the path to the current plugin. - * - * @return string $path The path to the current plugin. - * - * @throws \RuntimeException If the current plugin does not have an autoloader. - */ - public function find_current_plugin() { - // Escape from `vendor/__DIR__` to root plugin directory. - $plugin_directory = dirname( __DIR__, 2 ); - - // Use the path processor to ensure that this is an autoloader we're referencing. - $path = $this->path_processor->find_directory_with_autoloader( $plugin_directory, array() ); - if ( false === $path ) { - throw new \RuntimeException( 'Failed to locate plugin ' . $plugin_directory ); - } - - return $path; - } - - /** - * Checks a given option for plugin paths. - * - * @param string $option_name The option that we want to check for plugin information. - * @param bool $site_option Indicates whether or not we want to check the site option. - * - * @return array $plugin_paths The list of absolute paths we've found. - */ - public function find_using_option( $option_name, $site_option = false ) { - $raw = $site_option ? get_site_option( $option_name ) : get_option( $option_name ); - if ( false === $raw ) { - return array(); - } - - return $this->convert_plugins_to_paths( $raw ); - } - - /** - * Checks for plugins in the `action` request parameter. - * - * @param string[] $allowed_actions The actions that we're allowed to return plugins for. - * - * @return array $plugin_paths The list of absolute paths we've found. - */ - public function find_using_request_action( $allowed_actions ) { - /** - * Note: we're not actually checking the nonce here because it's too early - * in the execution. The pluggable functions are not yet loaded to give - * plugins a chance to plug their versions. Therefore we're doing the bare - * minimum: checking whether the nonce exists and it's in the right place. - * The request will fail later if the nonce doesn't pass the check. - */ - if ( empty( $_REQUEST['_wpnonce'] ) ) { - return array(); - } - - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated just below. - $action = isset( $_REQUEST['action'] ) ? wp_unslash( $_REQUEST['action'] ) : false; - if ( ! in_array( $action, $allowed_actions, true ) ) { - return array(); - } - - $plugin_slugs = array(); - switch ( $action ) { - case 'activate': - case 'deactivate': - if ( empty( $_REQUEST['plugin'] ) ) { - break; - } - - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated by convert_plugins_to_paths. - $plugin_slugs[] = wp_unslash( $_REQUEST['plugin'] ); - break; - - case 'activate-selected': - case 'deactivate-selected': - if ( empty( $_REQUEST['checked'] ) ) { - break; - } - - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated by convert_plugins_to_paths. - $plugin_slugs = wp_unslash( $_REQUEST['checked'] ); - break; - } - - return $this->convert_plugins_to_paths( $plugin_slugs ); - } - - /** - * Given an array of plugin slugs or paths, this will convert them to absolute paths and filter - * out the plugins that are not directory plugins. Note that array keys will also be included - * if they are plugin paths! - * - * @param string[] $plugins Plugin paths or slugs to filter. - * - * @return string[] - */ - private function convert_plugins_to_paths( $plugins ) { - if ( ! is_array( $plugins ) || empty( $plugins ) ) { - return array(); - } - - // We're going to look for plugins in the standard directories. - $path_constants = array( WP_PLUGIN_DIR, WPMU_PLUGIN_DIR ); - - $plugin_paths = array(); - foreach ( $plugins as $key => $value ) { - $path = $this->path_processor->find_directory_with_autoloader( $key, $path_constants ); - if ( $path ) { - $plugin_paths[] = $path; - } - - $path = $this->path_processor->find_directory_with_autoloader( $value, $path_constants ); - if ( $path ) { - $plugin_paths[] = $path; - } - } - - return $plugin_paths; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php b/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php deleted file mode 100644 index dd00ac1..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-plugins-handler.php +++ /dev/null @@ -1,156 +0,0 @@ -plugin_locator = $plugin_locator; - $this->path_processor = $path_processor; - } - - /** - * Gets all of the active plugins we can find. - * - * @param bool $include_deactivating When true, plugins deactivating this request will be considered active. - * @param bool $record_unknown When true, the current plugin will be marked as active and recorded when unknown. - * - * @return string[] - */ - public function get_active_plugins( $include_deactivating, $record_unknown ) { - global $jetpack_autoloader_activating_plugins_paths; - - // We're going to build a unique list of plugins from a few different sources - // to find all of our "active" plugins. While we need to return an integer - // array, we're going to use an associative array internally to reduce - // the amount of time that we're going to spend checking uniqueness - // and merging different arrays together to form the output. - $active_plugins = array(); - - // Make sure that plugins which have activated this request are considered as "active" even though - // they probably won't be present in any option. - if ( is_array( $jetpack_autoloader_activating_plugins_paths ) ) { - foreach ( $jetpack_autoloader_activating_plugins_paths as $path ) { - $active_plugins[ $path ] = $path; - } - } - - // This option contains all of the plugins that have been activated. - $plugins = $this->plugin_locator->find_using_option( 'active_plugins' ); - foreach ( $plugins as $path ) { - $active_plugins[ $path ] = $path; - } - - // This option contains all of the multisite plugins that have been activated. - if ( is_multisite() ) { - $plugins = $this->plugin_locator->find_using_option( 'active_sitewide_plugins', true ); - foreach ( $plugins as $path ) { - $active_plugins[ $path ] = $path; - } - } - - // These actions contain plugins that are being activated/deactivated during this request. - $plugins = $this->plugin_locator->find_using_request_action( array( 'activate', 'activate-selected', 'deactivate', 'deactivate-selected' ) ); - foreach ( $plugins as $path ) { - $active_plugins[ $path ] = $path; - } - - // When the current plugin isn't considered "active" there's a problem. - // Since we're here, the plugin is active and currently being loaded. - // We can support this case (mu-plugins and non-standard activation) - // by adding the current plugin to the active list and marking it - // as an unknown (activating) plugin. This also has the benefit - // of causing a reset because the active plugins list has - // been changed since it was saved in the global. - $current_plugin = $this->plugin_locator->find_current_plugin(); - if ( $record_unknown && ! in_array( $current_plugin, $active_plugins, true ) ) { - $active_plugins[ $current_plugin ] = $current_plugin; - $jetpack_autoloader_activating_plugins_paths[] = $current_plugin; - } - - // When deactivating plugins aren't desired we should entirely remove them from the active list. - if ( ! $include_deactivating ) { - // These actions contain plugins that are being deactivated during this request. - $plugins = $this->plugin_locator->find_using_request_action( array( 'deactivate', 'deactivate-selected' ) ); - foreach ( $plugins as $path ) { - unset( $active_plugins[ $path ] ); - } - } - - // Transform the array so that we don't have to worry about the keys interacting with other array types later. - return array_values( $active_plugins ); - } - - /** - * Gets all of the cached plugins if there are any. - * - * @return string[] - */ - public function get_cached_plugins() { - $cached = get_transient( self::TRANSIENT_KEY ); - if ( ! is_array( $cached ) || empty( $cached ) ) { - return array(); - } - - // We need to expand the tokens to an absolute path for this webserver. - return array_map( array( $this->path_processor, 'untokenize_path_constants' ), $cached ); - } - - /** - * Saves the plugin list to the cache. - * - * @param array $plugins The plugin list to save to the cache. - */ - public function cache_plugins( $plugins ) { - // We store the paths in a tokenized form so that that webservers with different absolute paths don't break. - $plugins = array_map( array( $this->path_processor, 'tokenize_path_constants' ), $plugins ); - - set_transient( self::TRANSIENT_KEY, $plugins ); - } - - /** - * Checks to see whether or not the plugin list given has changed when compared to the - * shared `$jetpack_autoloader_cached_plugin_paths` global. This allows us to deal - * with cases where the active list may change due to filtering.. - * - * @param string[] $plugins The plugins list to check against the global cache. - * - * @return bool True if the plugins have changed, otherwise false. - */ - public function have_plugins_changed( $plugins ) { - global $jetpack_autoloader_cached_plugin_paths; - - if ( $jetpack_autoloader_cached_plugin_paths !== $plugins ) { - $jetpack_autoloader_cached_plugin_paths = $plugins; - return true; - } - - return false; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-shutdown-handler.php b/vendor/automattic/jetpack-autoloader/src/class-shutdown-handler.php deleted file mode 100644 index 198b19c..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-shutdown-handler.php +++ /dev/null @@ -1,84 +0,0 @@ -plugins_handler = $plugins_handler; - $this->cached_plugins = $cached_plugins; - $this->was_included_by_autoloader = $was_included_by_autoloader; - } - - /** - * Handles the shutdown of the autoloader. - */ - public function __invoke() { - // Don't save a broken cache if an error happens during some plugin's initialization. - if ( ! did_action( 'plugins_loaded' ) ) { - // Ensure that the cache is emptied to prevent consecutive failures if the cache is to blame. - if ( ! empty( $this->cached_plugins ) ) { - $this->plugins_handler->cache_plugins( array() ); - } - - return; - } - - // Load the active plugins fresh since the list we pulled earlier might not contain - // plugins that were activated but did not reset the autoloader. This happens - // when a plugin is in the cache but not "active" when the autoloader loads. - // We also want to make sure that plugins which are deactivating are not - // considered "active" so that they will be removed from the cache now. - try { - $active_plugins = $this->plugins_handler->get_active_plugins( false, ! $this->was_included_by_autoloader ); - } catch ( \Exception $ex ) { - // When the package is deleted before shutdown it will throw an exception. - // In the event this happens we should erase the cache. - if ( ! empty( $this->cached_plugins ) ) { - $this->plugins_handler->cache_plugins( array() ); - } - return; - } - - // The paths should be sorted for easy comparisons with those loaded from the cache. - // Note we don't need to sort the cached entries because they're already sorted. - sort( $active_plugins ); - - // We don't want to waste time saving a cache that hasn't changed. - if ( $this->cached_plugins === $active_plugins ) { - return; - } - - $this->plugins_handler->cache_plugins( $active_plugins ); - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-version-loader.php b/vendor/automattic/jetpack-autoloader/src/class-version-loader.php deleted file mode 100644 index cc7dcd6..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-version-loader.php +++ /dev/null @@ -1,176 +0,0 @@ -version_selector = $version_selector; - $this->classmap = $classmap; - $this->psr4_map = $psr4_map; - $this->filemap = $filemap; - } - - /** - * Fetch the classmap. - * - * @since 3.1.0 - * @return array - */ - public function get_class_map() { - return $this->classmap; - } - - /** - * Fetch the psr-4 mappings. - * - * @since 3.1.0 - * @return array - */ - public function get_psr4_map() { - return $this->psr4_map; - } - - /** - * Finds the file path for the given class. - * - * @param string $class_name The class to find. - * - * @return string|null $file_path The path to the file if found, null if no class was found. - */ - public function find_class_file( $class_name ) { - $data = $this->select_newest_file( - $this->classmap[ $class_name ] ?? null, - $this->find_psr4_file( $class_name ) - ); - if ( ! isset( $data ) ) { - return null; - } - - return $data['path']; - } - - /** - * Load all of the files in the filemap. - */ - public function load_filemap() { - if ( empty( $this->filemap ) ) { - return; - } - - foreach ( $this->filemap as $file_identifier => $file_data ) { - if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { - require_once $file_data['path']; - - $GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; - } - } - } - - /** - * Compares different class sources and returns the newest. - * - * @param array|null $classmap_data The classmap class data. - * @param array|null $psr4_data The PSR-4 class data. - * - * @return array|null $data - */ - private function select_newest_file( $classmap_data, $psr4_data ) { - if ( ! isset( $classmap_data ) ) { - return $psr4_data; - } elseif ( ! isset( $psr4_data ) ) { - return $classmap_data; - } - - if ( $this->version_selector->is_version_update_required( $classmap_data['version'], $psr4_data['version'] ) ) { - return $psr4_data; - } - - return $classmap_data; - } - - /** - * Finds the file for a given class in a PSR-4 namespace. - * - * @param string $class_name The class to find. - * - * @return array|null $data The version and path path to the file if found, null otherwise. - */ - private function find_psr4_file( $class_name ) { - if ( empty( $this->psr4_map ) ) { - return null; - } - - // Don't bother with classes that have no namespace. - $class_index = strrpos( $class_name, '\\' ); - if ( ! $class_index ) { - return null; - } - $class_for_path = str_replace( '\\', '/', $class_name ); - - // Search for the namespace by iteratively cutting off the last segment until - // we find a match. This allows us to check the most-specific namespaces - // first as well as minimize the amount of time spent looking. - for ( - $class_namespace = substr( $class_name, 0, $class_index ); - ! empty( $class_namespace ); - $class_namespace = substr( $class_namespace, 0, strrpos( $class_namespace, '\\' ) ) - ) { - $namespace = $class_namespace . '\\'; - if ( ! isset( $this->psr4_map[ $namespace ] ) ) { - continue; - } - $data = $this->psr4_map[ $namespace ]; - - foreach ( $data['path'] as $path ) { - $path .= '/' . substr( $class_for_path, strlen( $namespace ) ) . '.php'; - if ( file_exists( $path ) ) { - return array( - 'version' => $data['version'], - 'path' => $path, - ); - } - } - } - - return null; - } -} diff --git a/vendor/automattic/jetpack-autoloader/src/class-version-selector.php b/vendor/automattic/jetpack-autoloader/src/class-version-selector.php deleted file mode 100644 index 5b201ff..0000000 --- a/vendor/automattic/jetpack-autoloader/src/class-version-selector.php +++ /dev/null @@ -1,61 +0,0 @@ -is_dev_version( $selected_version ) ) { - return false; - } - - if ( $this->is_dev_version( $compare_version ) ) { - if ( $use_dev_versions ) { - return true; - } else { - return false; - } - } - - if ( version_compare( $selected_version, $compare_version, '<' ) ) { - return true; - } - - return false; - } - - /** - * Checks whether the given package version is a development version. - * - * @param String $version The package version. - * - * @return bool True if the version is a dev version, else false. - */ - public function is_dev_version( $version ) { - if ( 'dev-' === substr( $version, 0, 4 ) || '9999999-dev' === $version ) { - return true; - } - - return false; - } -} diff --git a/vendor/automattic/jetpack-constants/CHANGELOG.md b/vendor/automattic/jetpack-constants/CHANGELOG.md new file mode 100644 index 0000000..0bdf65f --- /dev/null +++ b/vendor/automattic/jetpack-constants/CHANGELOG.md @@ -0,0 +1,264 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [3.0.8] - 2025-04-28 +### Changed +- Internal updates. + +## [3.0.7] - 2025-04-14 +### Changed +- Internal updates. + +## [3.0.6] - 2025-03-31 +### Changed +- Internal updates. + +## [3.0.5] - 2025-03-21 +### Changed +- Internal updates. + +## [3.0.4] - 2025-03-12 +### Changed +- Internal updates. + +## [3.0.3] - 2025-03-05 +### Changed +- Internal updates. + +## [3.0.2] - 2025-02-24 +### Changed +- Update dependencies. + +## [3.0.1] - 2024-11-25 +### Changed +- Updated package dependencies. [#40258] + +## [3.0.0] - 2024-11-14 +### Removed +- General: Update minimum PHP version to 7.2. [#40147] + +## [2.0.5] - 2024-11-04 +### Added +- Enable test coverage. [#39961] + +## [2.0.4] - 2024-08-23 +### Changed +- Updated package dependencies. [#39004] + +## [2.0.3] - 2024-05-29 +### Fixed +- Fix phpdoc type on `Constants::set_constant()` value parameter. [#37606] + +## [2.0.2] - 2024-04-30 +### Changed +- Internal updates. + +## [2.0.1] - 2024-03-12 +### Changed +- Internal updates. + +## [2.0.0] - 2023-11-20 +### Changed +- Updated required PHP version to >= 7.0. [#34192] + +## [1.6.23] - 2023-08-23 +### Changed +- Updated package dependencies. [#32605] + +## [1.6.22] - 2023-04-10 +### Added +- Add Jetpack Autoloader package suggestion. [#29988] + +## [1.6.21] - 2023-02-20 +### Changed +- Minor internal updates. + +## [1.6.20] - 2022-12-02 +### Changed +- Updated package dependencies. [#27688] + +## [1.6.19] - 2022-11-22 +### Changed +- Updated package dependencies. [#27043] + +## [1.6.18] - 2022-07-26 +### Changed +- Updated package dependencies. [#25158] + +## [1.6.17] - 2022-06-21 +### Changed +- Renaming master to trunk. + +## [1.6.16] - 2022-04-26 +### Changed +- Updated package dependencies. + +## [1.6.15] - 2022-01-25 +### Changed +- Updated package dependencies. + +## [1.6.14] - 2022-01-04 +### Changed +- Switch to pcov for code coverage. +- Updated package dependencies + +## [1.6.13] - 2021-12-14 +### Changed +- Updated package dependencies. + +## [1.6.12] - 2021-11-22 +### Changed +- Updated package dependencies + +## [1.6.11] - 2021-11-02 +### Changed +- Set `convertDeprecationsToExceptions` true in PHPUnit config. +- Update PHPUnit configs to include just what needs coverage rather than include everything then try to exclude stuff that doesn't. + +## [1.6.10] - 2021-10-26 +### Fixed +- Updated is_true docblock to be more accurate. + +## [1.6.9] - 2021-10-13 +### Changed +- Updated package dependencies. + +## [1.6.8] - 2021-10-06 +### Changed +- Updated package dependencies + +## [1.6.7] - 2021-09-28 +### Changed +- Updated package dependencies. + +## [1.6.6] - 2021-08-30 +### Changed +- Run composer update on test-php command instead of phpunit +- Tests: update PHPUnit polyfills dependency (yoast/phpunit-polyfills). +- Updated versions in annotations + +## [1.6.5] - 2021-05-25 +### Changed +- Updated package dependencies. + +## [1.6.4] - 2021-04-08 +### Changed +- Packaging and build changes, no change to the package itself. + +## [1.6.3] - 2021-03-30 +### Added +- Composer alias for dev-master, to improve dependencies + +### Changed +- Update package dependencies. + +### Fixed +- Use `composer update` rather than `install` in scripts, as composer.lock isn't checked in. + +## [1.6.2] - 2021-02-05 + +- CI: Make tests more generic + +## [1.6.1] - 2021-01-19 + +- Add mirror-repo information to all current composer packages +- Monorepo: Reorganize all projects + +## [1.6.0] - 2020-12-14 + +- Update dependency brain/monkey to v2.6.0 +- Pin dependencies +- Packages: Update for PHP 8 testing + +## [1.5.1] - 2020-10-28 + +- Updated PHPCS: Packages and Debugger + +## [1.5.0] - 2020-08-13 + +- CI: Try collect js coverage +- Docker: Add package testing shortcut + +## [1.4.0] - 2020-07-01 + +- Package Unit tests: update test file names to make sure they runs in Travis + +## [1.3.0] - 2020-06-22 + +- PHPCS: Clean up the packages + +## [1.2.0] - 2020-04-15 + +- Use jp.com redirect in all links +- Connection: add a filter for setting Jetpack api constants + +## [1.1.3] - 2019-11-08 + +- Packages: Use classmap instead of PSR-4 + +## [1.1.2] - 2019-10-28 + +- Packages: Add gitattributes files to all packages that need th… + +## [1.1.1] - 2019-09-20 + +- Docs: Unify usage of @package phpdoc tags + +## [1.1.0] - 2019-09-14 + +## 1.0.0 - 2019-07-09 + +- Packages: Finish the constants package + +[3.0.8]: https://github.com/Automattic/jetpack-constants/compare/v3.0.7...v3.0.8 +[3.0.7]: https://github.com/Automattic/jetpack-constants/compare/v3.0.6...v3.0.7 +[3.0.6]: https://github.com/Automattic/jetpack-constants/compare/v3.0.5...v3.0.6 +[3.0.5]: https://github.com/Automattic/jetpack-constants/compare/v3.0.4...v3.0.5 +[3.0.4]: https://github.com/Automattic/jetpack-constants/compare/v3.0.3...v3.0.4 +[3.0.3]: https://github.com/Automattic/jetpack-constants/compare/v3.0.2...v3.0.3 +[3.0.2]: https://github.com/Automattic/jetpack-constants/compare/v3.0.1...v3.0.2 +[3.0.1]: https://github.com/Automattic/jetpack-constants/compare/v3.0.0...v3.0.1 +[3.0.0]: https://github.com/Automattic/jetpack-constants/compare/v2.0.5...v3.0.0 +[2.0.5]: https://github.com/Automattic/jetpack-constants/compare/v2.0.4...v2.0.5 +[2.0.4]: https://github.com/Automattic/jetpack-constants/compare/v2.0.3...v2.0.4 +[2.0.3]: https://github.com/Automattic/jetpack-constants/compare/v2.0.2...v2.0.3 +[2.0.2]: https://github.com/Automattic/jetpack-constants/compare/v2.0.1...v2.0.2 +[2.0.1]: https://github.com/Automattic/jetpack-constants/compare/v2.0.0...v2.0.1 +[2.0.0]: https://github.com/Automattic/jetpack-constants/compare/v1.6.23...v2.0.0 +[1.6.23]: https://github.com/Automattic/jetpack-constants/compare/v1.6.22...v1.6.23 +[1.6.22]: https://github.com/Automattic/jetpack-constants/compare/v1.6.21...v1.6.22 +[1.6.21]: https://github.com/Automattic/jetpack-constants/compare/v1.6.20...v1.6.21 +[1.6.20]: https://github.com/Automattic/jetpack-constants/compare/v1.6.19...v1.6.20 +[1.6.19]: https://github.com/Automattic/jetpack-constants/compare/v1.6.18...v1.6.19 +[1.6.18]: https://github.com/Automattic/jetpack-constants/compare/v1.6.17...v1.6.18 +[1.6.17]: https://github.com/Automattic/jetpack-constants/compare/v1.6.16...v1.6.17 +[1.6.16]: https://github.com/Automattic/jetpack-constants/compare/v1.6.15...v1.6.16 +[1.6.15]: https://github.com/Automattic/jetpack-constants/compare/v1.6.14...v1.6.15 +[1.6.14]: https://github.com/Automattic/jetpack-constants/compare/v1.6.13...v1.6.14 +[1.6.13]: https://github.com/Automattic/jetpack-constants/compare/v1.6.12...v1.6.13 +[1.6.12]: https://github.com/Automattic/jetpack-constants/compare/v1.6.11...v1.6.12 +[1.6.11]: https://github.com/Automattic/jetpack-constants/compare/v1.6.10...v1.6.11 +[1.6.10]: https://github.com/Automattic/jetpack-constants/compare/v1.6.9...v1.6.10 +[1.6.9]: https://github.com/Automattic/jetpack-constants/compare/v1.6.8...v1.6.9 +[1.6.8]: https://github.com/Automattic/jetpack-constants/compare/v1.6.7...v1.6.8 +[1.6.7]: https://github.com/Automattic/jetpack-constants/compare/v1.6.6...v1.6.7 +[1.6.6]: https://github.com/Automattic/jetpack-constants/compare/v1.6.5...v1.6.6 +[1.6.5]: https://github.com/Automattic/jetpack-constants/compare/v1.6.4...v1.6.5 +[1.6.4]: https://github.com/Automattic/jetpack-constants/compare/v1.6.3...v1.6.4 +[1.6.3]: https://github.com/Automattic/jetpack-constants/compare/v1.6.2...v1.6.3 +[1.6.2]: https://github.com/Automattic/jetpack-constants/compare/v1.6.1...v1.6.2 +[1.6.1]: https://github.com/Automattic/jetpack-constants/compare/v1.6.0...v1.6.1 +[1.6.0]: https://github.com/Automattic/jetpack-constants/compare/v1.5.1...v1.6.0 +[1.5.1]: https://github.com/Automattic/jetpack-constants/compare/v1.5.0...v1.5.1 +[1.5.0]: https://github.com/Automattic/jetpack-constants/compare/v1.4.0...v1.5.0 +[1.4.0]: https://github.com/Automattic/jetpack-constants/compare/v1.3.0...v1.4.0 +[1.3.0]: https://github.com/Automattic/jetpack-constants/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/Automattic/jetpack-constants/compare/v1.1.3...v1.2.0 +[1.1.3]: https://github.com/Automattic/jetpack-constants/compare/v1.1.2...v1.1.3 +[1.1.2]: https://github.com/Automattic/jetpack-constants/compare/v1.1.1...v1.1.2 +[1.1.1]: https://github.com/Automattic/jetpack-constants/compare/v1.1.0...v1.1.1 +[1.1.0]: https://github.com/Automattic/jetpack-constants/compare/v1.0.0...v1.1.0 diff --git a/vendor/automattic/jetpack-autoloader/LICENSE.txt b/vendor/automattic/jetpack-constants/LICENSE.txt similarity index 100% rename from vendor/automattic/jetpack-autoloader/LICENSE.txt rename to vendor/automattic/jetpack-constants/LICENSE.txt diff --git a/vendor/automattic/jetpack-constants/README.md b/vendor/automattic/jetpack-constants/README.md new file mode 100644 index 0000000..ed216f5 --- /dev/null +++ b/vendor/automattic/jetpack-constants/README.md @@ -0,0 +1,67 @@ +# Jetpack Constants + +A simple constant manager for Jetpack. + +Testing constants is hard. Once you define a constant in PHP, it's defined. Constants Manager is an abstraction layer so that unit tests can set constants for tests. + +### Usage + +Retrieve the value of a constant `CONSTANT_NAME` (returns `null` if it's not defined): + +```php +use Automattic\Jetpack\Constants; + +$constant_value = Constants::get_constant( 'CONSTANT_NAME' ); +``` + +Set the value of a constant `CONSTANT_NAME` to a particular value: + +```php +use Automattic\Jetpack\Constants; + +$value = 'some value'; +Constants::set_constant( 'CONSTANT_NAME', $value ); +``` + +Check whether a constant `CONSTANT_NAME` is defined: + +```php +use Automattic\Jetpack\Constants; + +$defined = Constants::is_defined( 'CONSTANT_NAME' ); +``` + +Check whether a constant `CONSTANT_NAME` is truthy: + +```php +use Automattic\Jetpack\Constants; + +$is_truthy = Constants::is_true( 'CONSTANT_NAME' ); +``` + +Delete the `CONSTANT_NAME` constant: + +```php +use Automattic\Jetpack\Constants; + +Constants::clear_single_constant( 'CONSTANT_NAME' ); +``` + +Delete all known constants: + +```php +use Automattic\Jetpack\Constants; + +Constants::clear_constants(); +``` +## Using this package in your WordPress plugin + +If you plan on using this package in your WordPress plugin, we would recommend that you use [Jetpack Autoloader](https://packagist.org/packages/automattic/jetpack-autoloader) as your autoloader. This will allow for maximum interoperability with other plugins that use this package as well. + +## Security + +Need to report a security vulnerability? Go to [https://automattic.com/security/](https://automattic.com/security/) or directly to our security bug bounty site [https://hackerone.com/automattic](https://hackerone.com/automattic). + +## License + +jetpack-constants is licensed under [GNU General Public License v2 (or later)](./LICENSE.txt) diff --git a/vendor/automattic/jetpack-autoloader/SECURITY.md b/vendor/automattic/jetpack-constants/SECURITY.md similarity index 100% rename from vendor/automattic/jetpack-autoloader/SECURITY.md rename to vendor/automattic/jetpack-constants/SECURITY.md diff --git a/vendor/automattic/jetpack-constants/src/class-constants.php b/vendor/automattic/jetpack-constants/src/class-constants.php new file mode 100644 index 0000000..45768a9 --- /dev/null +++ b/vendor/automattic/jetpack-constants/src/class-constants.php @@ -0,0 +1,124 @@ +}|array{}|null */ private static $installed; - /** - * @var bool - */ - private static $installedIsLocalDir; - /** * @var bool|null */ @@ -320,24 +309,6 @@ class InstalledVersions { self::$installed = $data; self::$installedByVendor = array(); - - // when using reload, we disable the duplicate protection to ensure that self::$installed data is - // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, - // so we have to assume it does not, and that may result in duplicate data being returned when listing - // all installed packages for example - self::$installedIsLocalDir = false; - } - - /** - * @return string - */ - private static function getSelfDir() - { - if (self::$selfDir === null) { - self::$selfDir = strtr(__DIR__, '\\', '/'); - } - - return self::$selfDir; } /** @@ -351,27 +322,19 @@ class InstalledVersions } $installed = array(); - $copiedLocalDir = false; if (self::$canGetVendors) { - $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - $vendorDir = strtr($vendorDir, '\\', '/'); if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ $required = require $vendorDir.'/composer/installed.php'; - self::$installedByVendor[$vendorDir] = $required; - $installed[] = $required; - if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { - self::$installed = $required; - self::$installedIsLocalDir = true; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; } } - if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { - $copiedLocalDir = true; - } } } @@ -387,7 +350,7 @@ class InstalledVersions } } - if (self::$installed !== array() && !$copiedLocalDir) { + if (self::$installed !== array()) { $installed[] = self::$installed; } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 013df1f..d4aaf79 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,11 +6,13 @@ $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( - 'Automattic\\Jetpack\\Autoloader\\AutoloadFileWriter' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadFileWriter.php', - 'Automattic\\Jetpack\\Autoloader\\AutoloadGenerator' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php', - 'Automattic\\Jetpack\\Autoloader\\AutoloadProcessor' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadProcessor.php', - 'Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin' => $vendorDir . '/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php', - 'Automattic\\Jetpack\\Autoloader\\ManifestGenerator' => $vendorDir . '/automattic/jetpack-autoloader/src/ManifestGenerator.php', + 'Automattic\\Jetpack\\Constants' => $vendorDir . '/automattic/jetpack-constants/src/class-constants.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Collector' => $baseDir . '/src/Internal/Telemetry/Collector.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Events' => $baseDir . '/src/Internal/Telemetry/Events.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Orders' => $baseDir . '/src/Internal/Telemetry/Orders.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Products' => $baseDir . '/src/Internal/Telemetry/Products.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Subscriptions' => $baseDir . '/src/Internal/Telemetry/Subscriptions.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Utilities\\Scheduled_Actions' => $baseDir . '/src/Internal/Utilities/Scheduled_Actions.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php', 'Composer\\Installers\\AkauntingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AkauntingInstaller.php', diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 3033720..ed4466e 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -8,5 +8,4 @@ $baseDir = dirname($vendorDir); return array( 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), 'Automattic\\WooCommerce_Subscriptions\\' => array($baseDir . '/src'), - 'Automattic\\Jetpack\\Autoloader\\' => array($vendorDir . '/automattic/jetpack-autoloader/src'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 438b0ea..92a2f69 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit32625eaf0064549a4f20b6231a37a93c +class ComposerAutoloaderInitcb45de1ca955f89ec737c442c7cf101c { private static $loader; @@ -24,12 +24,12 @@ class ComposerAutoloaderInit32625eaf0064549a4f20b6231a37a93c require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit32625eaf0064549a4f20b6231a37a93c', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitcb45de1ca955f89ec737c442c7cf101c', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit32625eaf0064549a4f20b6231a37a93c', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitcb45de1ca955f89ec737c442c7cf101c', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit32625eaf0064549a4f20b6231a37a93c::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitcb45de1ca955f89ec737c442c7cf101c::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index e4f4099..bee98d4 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit32625eaf0064549a4f20b6231a37a93c +class ComposerStaticInitcb45de1ca955f89ec737c442c7cf101c { public static $prefixLengthsPsr4 = array ( 'C' => @@ -14,7 +14,6 @@ class ComposerStaticInit32625eaf0064549a4f20b6231a37a93c 'A' => array ( 'Automattic\\WooCommerce_Subscriptions\\' => 37, - 'Automattic\\Jetpack\\Autoloader\\' => 30, ), ); @@ -27,18 +26,16 @@ class ComposerStaticInit32625eaf0064549a4f20b6231a37a93c array ( 0 => __DIR__ . '/../..' . '/src', ), - 'Automattic\\Jetpack\\Autoloader\\' => - array ( - 0 => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src', - ), ); public static $classMap = array ( - 'Automattic\\Jetpack\\Autoloader\\AutoloadFileWriter' => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src/AutoloadFileWriter.php', - 'Automattic\\Jetpack\\Autoloader\\AutoloadGenerator' => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php', - 'Automattic\\Jetpack\\Autoloader\\AutoloadProcessor' => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src/AutoloadProcessor.php', - 'Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin' => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php', - 'Automattic\\Jetpack\\Autoloader\\ManifestGenerator' => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src/ManifestGenerator.php', + 'Automattic\\Jetpack\\Constants' => __DIR__ . '/..' . '/automattic/jetpack-constants/src/class-constants.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Collector' => __DIR__ . '/../..' . '/src/Internal/Telemetry/Collector.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Events' => __DIR__ . '/../..' . '/src/Internal/Telemetry/Events.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Orders' => __DIR__ . '/../..' . '/src/Internal/Telemetry/Orders.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Products' => __DIR__ . '/../..' . '/src/Internal/Telemetry/Products.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Telemetry\\Subscriptions' => __DIR__ . '/../..' . '/src/Internal/Telemetry/Subscriptions.php', + 'Automattic\\WooCommerce_Subscriptions\\Internal\\Utilities\\Scheduled_Actions' => __DIR__ . '/../..' . '/src/Internal/Utilities/Scheduled_Actions.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Composer\\Installers\\AglInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AglInstaller.php', 'Composer\\Installers\\AkauntingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AkauntingInstaller.php', @@ -168,9 +165,9 @@ class ComposerStaticInit32625eaf0064549a4f20b6231a37a93c public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit32625eaf0064549a4f20b6231a37a93c::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit32625eaf0064549a4f20b6231a37a93c::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit32625eaf0064549a4f20b6231a37a93c::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitcb45de1ca955f89ec737c442c7cf101c::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitcb45de1ca955f89ec737c442c7cf101c::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitcb45de1ca955f89ec737c442c7cf101c::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 726058c..219323c 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,72 +1,59 @@ { "packages": [ { - "name": "automattic/jetpack-autoloader", - "version": "v5.0.10", - "version_normalized": "5.0.10.0", + "name": "automattic/jetpack-constants", + "version": "v3.0.8", + "version_normalized": "3.0.8.0", "source": { "type": "git", - "url": "https://github.com/Automattic/jetpack-autoloader.git", - "reference": "f7e2142139b925fac0a167ed0cbc71e2592bd9a0" + "url": "https://github.com/Automattic/jetpack-constants.git", + "reference": "f9bf00ab48956b8326209e7c0baf247a0ed721c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/f7e2142139b925fac0a167ed0cbc71e2592bd9a0", - "reference": "f7e2142139b925fac0a167ed0cbc71e2592bd9a0", + "url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/f9bf00ab48956b8326209e7c0baf247a0ed721c4", + "reference": "f9bf00ab48956b8326209e7c0baf247a0ed721c4", "shasum": "" }, "require": { - "composer-plugin-api": "^2.2", "php": ">=7.2" }, "require-dev": { - "automattic/jetpack-changelogger": "^6.0.7", + "automattic/jetpack-changelogger": "^6.0.5", "automattic/phpunit-select-config": "^1.0.3", - "composer/composer": "^2.2", + "brain/monkey": "^2.6.2", "yoast/phpunit-polyfills": "^4.0.0" }, - "time": "2025-09-15T14:36:53+00:00", - "type": "composer-plugin", + "suggest": { + "automattic/jetpack-autoloader": "Allow for better interoperability with other plugins that use this package." + }, + "time": "2025-04-28T15:12:45+00:00", + "type": "jetpack-library", "extra": { - "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin", "autotagger": true, - "mirror-repo": "Automattic/jetpack-autoloader", + "mirror-repo": "Automattic/jetpack-constants", "branch-alias": { - "dev-trunk": "5.0.x-dev" + "dev-trunk": "3.0.x-dev" }, "changelogger": { - "link-template": "https://github.com/Automattic/jetpack-autoloader/compare/v${old}...v${new}" - }, - "version-constants": { - "::VERSION": "src/AutoloadGenerator.php" + "link-template": "https://github.com/Automattic/jetpack-constants/compare/v${old}...v${new}" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Automattic\\Jetpack\\Autoloader\\": "src" - }, "classmap": [ - "src/AutoloadGenerator.php" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "GPL-2.0-or-later" ], - "description": "Creates a custom autoloader for a plugin or theme.", - "keywords": [ - "autoload", - "autoloader", - "composer", - "jetpack", - "plugin", - "wordpress" - ], + "description": "A wrapper for defining constants in a more testable way.", "support": { - "source": "https://github.com/Automattic/jetpack-autoloader/tree/v5.0.10" + "source": "https://github.com/Automattic/jetpack-constants/tree/v3.0.8" }, - "install-path": "../automattic/jetpack-autoloader" + "install-path": "../automattic/jetpack-constants" }, { "name": "composer/installers", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 05e4292..a2b55b8 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,21 +1,21 @@ array( 'name' => 'woocommerce/woocommerce-subscriptions', - 'pretty_version' => 'dev-release/7.9.0', - 'version' => 'dev-release/7.9.0', - 'reference' => '9114ff6422e5a37b9ccca8c6954172b07ffd9cae', + 'pretty_version' => 'dev-release/8.0.0', + 'version' => 'dev-release/8.0.0', + 'reference' => 'fae6f1f47d4716196c53f3d73845d84afd815c63', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => false, ), 'versions' => array( - 'automattic/jetpack-autoloader' => array( - 'pretty_version' => 'v5.0.10', - 'version' => '5.0.10.0', - 'reference' => 'f7e2142139b925fac0a167ed0cbc71e2592bd9a0', - 'type' => 'composer-plugin', - 'install_path' => __DIR__ . '/../automattic/jetpack-autoloader', + 'automattic/jetpack-constants' => array( + 'pretty_version' => 'v3.0.8', + 'version' => '3.0.8.0', + 'reference' => 'f9bf00ab48956b8326209e7c0baf247a0ed721c4', + 'type' => 'jetpack-library', + 'install_path' => __DIR__ . '/../automattic/jetpack-constants', 'aliases' => array(), 'dev_requirement' => false, ), @@ -29,9 +29,9 @@ 'dev_requirement' => false, ), 'woocommerce/woocommerce-subscriptions' => array( - 'pretty_version' => 'dev-release/7.9.0', - 'version' => 'dev-release/7.9.0', - 'reference' => '9114ff6422e5a37b9ccca8c6954172b07ffd9cae', + 'pretty_version' => 'dev-release/8.0.0', + 'version' => 'dev-release/8.0.0', + 'reference' => 'fae6f1f47d4716196c53f3d73845d84afd815c63', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/composer/jetpack_autoload_classmap.php b/vendor/composer/jetpack_autoload_classmap.php deleted file mode 100644 index 1bf538f..0000000 --- a/vendor/composer/jetpack_autoload_classmap.php +++ /dev/null @@ -1,577 +0,0 @@ - array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-autoloader.php' - ), - 'Autoloader_Handler' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-autoloader-handler.php' - ), - 'Autoloader_Locator' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-autoloader-locator.php' - ), - 'Automattic\\Jetpack\\Autoloader\\AutoloadFileWriter' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadFileWriter.php' - ), - 'Automattic\\Jetpack\\Autoloader\\AutoloadGenerator' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php' - ), - 'Automattic\\Jetpack\\Autoloader\\AutoloadProcessor' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadProcessor.php' - ), - 'Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php' - ), - 'Automattic\\Jetpack\\Autoloader\\ManifestGenerator' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/ManifestGenerator.php' - ), - 'Composer\\Installers\\AglInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php' - ), - 'Composer\\Installers\\AkauntingInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AkauntingInstaller.php' - ), - 'Composer\\Installers\\AnnotateCmsInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php' - ), - 'Composer\\Installers\\AsgardInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php' - ), - 'Composer\\Installers\\AttogramInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php' - ), - 'Composer\\Installers\\BaseInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BaseInstaller.php' - ), - 'Composer\\Installers\\BitrixInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BitrixInstaller.php' - ), - 'Composer\\Installers\\BonefishInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BonefishInstaller.php' - ), - 'Composer\\Installers\\BotbleInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/BotbleInstaller.php' - ), - 'Composer\\Installers\\CakePHPInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php' - ), - 'Composer\\Installers\\ChefInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ChefInstaller.php' - ), - 'Composer\\Installers\\CiviCrmInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CiviCrmInstaller.php' - ), - 'Composer\\Installers\\ClanCatsFrameworkInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php' - ), - 'Composer\\Installers\\CockpitInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php' - ), - 'Composer\\Installers\\CodeIgniterInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php' - ), - 'Composer\\Installers\\Concrete5Installer' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php' - ), - 'Composer\\Installers\\ConcreteCMSInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ConcreteCMSInstaller.php' - ), - 'Composer\\Installers\\CroogoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php' - ), - 'Composer\\Installers\\DecibelInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php' - ), - 'Composer\\Installers\\DframeInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DframeInstaller.php' - ), - 'Composer\\Installers\\DokuWikiInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php' - ), - 'Composer\\Installers\\DolibarrInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php' - ), - 'Composer\\Installers\\DrupalInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/DrupalInstaller.php' - ), - 'Composer\\Installers\\ElggInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ElggInstaller.php' - ), - 'Composer\\Installers\\EliasisInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/EliasisInstaller.php' - ), - 'Composer\\Installers\\ExpressionEngineInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php' - ), - 'Composer\\Installers\\EzPlatformInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php' - ), - 'Composer\\Installers\\ForkCMSInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ForkCMSInstaller.php' - ), - 'Composer\\Installers\\FuelInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php' - ), - 'Composer\\Installers\\FuelphpInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php' - ), - 'Composer\\Installers\\GravInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/GravInstaller.php' - ), - 'Composer\\Installers\\HuradInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php' - ), - 'Composer\\Installers\\ImageCMSInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php' - ), - 'Composer\\Installers\\Installer' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php' - ), - 'Composer\\Installers\\ItopInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php' - ), - 'Composer\\Installers\\KanboardInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php' - ), - 'Composer\\Installers\\KnownInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KnownInstaller.php' - ), - 'Composer\\Installers\\KodiCMSInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php' - ), - 'Composer\\Installers\\KohanaInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php' - ), - 'Composer\\Installers\\LanManagementSystemInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php' - ), - 'Composer\\Installers\\LaravelInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php' - ), - 'Composer\\Installers\\LavaLiteInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php' - ), - 'Composer\\Installers\\LithiumInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php' - ), - 'Composer\\Installers\\MODULEWorkInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php' - ), - 'Composer\\Installers\\MODXEvoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php' - ), - 'Composer\\Installers\\MagentoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php' - ), - 'Composer\\Installers\\MajimaInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php' - ), - 'Composer\\Installers\\MakoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php' - ), - 'Composer\\Installers\\MantisBTInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MantisBTInstaller.php' - ), - 'Composer\\Installers\\MatomoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MatomoInstaller.php' - ), - 'Composer\\Installers\\MauticInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php' - ), - 'Composer\\Installers\\MayaInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php' - ), - 'Composer\\Installers\\MediaWikiInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php' - ), - 'Composer\\Installers\\MiaoxingInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MiaoxingInstaller.php' - ), - 'Composer\\Installers\\MicroweberInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php' - ), - 'Composer\\Installers\\ModxInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ModxInstaller.php' - ), - 'Composer\\Installers\\MoodleInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php' - ), - 'Composer\\Installers\\OctoberInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php' - ), - 'Composer\\Installers\\OntoWikiInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php' - ), - 'Composer\\Installers\\OsclassInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OsclassInstaller.php' - ), - 'Composer\\Installers\\OxidInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php' - ), - 'Composer\\Installers\\PPIInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php' - ), - 'Composer\\Installers\\PantheonInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PantheonInstaller.php' - ), - 'Composer\\Installers\\PhiftyInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php' - ), - 'Composer\\Installers\\PhpBBInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php' - ), - 'Composer\\Installers\\PiwikInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php' - ), - 'Composer\\Installers\\PlentymarketsInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php' - ), - 'Composer\\Installers\\Plugin' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php' - ), - 'Composer\\Installers\\PortoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PortoInstaller.php' - ), - 'Composer\\Installers\\PrestashopInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php' - ), - 'Composer\\Installers\\ProcessWireInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ProcessWireInstaller.php' - ), - 'Composer\\Installers\\PuppetInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php' - ), - 'Composer\\Installers\\PxcmsInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php' - ), - 'Composer\\Installers\\RadPHPInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php' - ), - 'Composer\\Installers\\ReIndexInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php' - ), - 'Composer\\Installers\\Redaxo5Installer' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/Redaxo5Installer.php' - ), - 'Composer\\Installers\\RedaxoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php' - ), - 'Composer\\Installers\\RoundcubeInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php' - ), - 'Composer\\Installers\\SMFInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php' - ), - 'Composer\\Installers\\ShopwareInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php' - ), - 'Composer\\Installers\\SilverStripeInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php' - ), - 'Composer\\Installers\\SiteDirectInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php' - ), - 'Composer\\Installers\\StarbugInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/StarbugInstaller.php' - ), - 'Composer\\Installers\\SyDESInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php' - ), - 'Composer\\Installers\\SyliusInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/SyliusInstaller.php' - ), - 'Composer\\Installers\\TaoInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TaoInstaller.php' - ), - 'Composer\\Installers\\TastyIgniterInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php' - ), - 'Composer\\Installers\\TheliaInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php' - ), - 'Composer\\Installers\\TuskInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php' - ), - 'Composer\\Installers\\UserFrostingInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php' - ), - 'Composer\\Installers\\VanillaInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php' - ), - 'Composer\\Installers\\VgmcpInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php' - ), - 'Composer\\Installers\\WHMCSInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php' - ), - 'Composer\\Installers\\WinterInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WinterInstaller.php' - ), - 'Composer\\Installers\\WolfCMSInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php' - ), - 'Composer\\Installers\\WordPressInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php' - ), - 'Composer\\Installers\\YawikInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php' - ), - 'Composer\\Installers\\ZendInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php' - ), - 'Composer\\Installers\\ZikulaInstaller' => array( - 'version' => '2.3.0.0', - 'path' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php' - ), - 'Container' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-container.php' - ), - 'Hook_Manager' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-hook-manager.php' - ), - 'Latest_Autoloader_Guard' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-latest-autoloader-guard.php' - ), - 'Manifest_Reader' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-manifest-reader.php' - ), - 'PHP_Autoloader' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-php-autoloader.php' - ), - 'Path_Processor' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-path-processor.php' - ), - 'Plugin_Locator' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-plugin-locator.php' - ), - 'Plugins_Handler' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-plugins-handler.php' - ), - 'Shutdown_Handler' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-shutdown-handler.php' - ), - 'Version_Loader' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-version-loader.php' - ), - 'Version_Selector' => array( - 'version' => '5.0.10', - 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/class-version-selector.php' - ), - 'WCSG_Admin' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-admin.php' - ), - 'WCSG_Admin_Order' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/admin/class-wcsg-admin-order.php' - ), - 'WCSG_Admin_System_Status' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-admin-system-status.php' - ), - 'WCSG_Admin_Welcome_Announcement' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-admin-welcome-announcement.php' - ), - 'WCSG_Blocks_Integration' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-blocks-integration.php' - ), - 'WCSG_Cart' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-cart.php' - ), - 'WCSG_Checkout' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-checkout.php' - ), - 'WCSG_Download_Handler' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-download-handler.php' - ), - 'WCSG_Email' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-email.php' - ), - 'WCSG_Email_Completed_Renewal_Order' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/emails/class-wcsg-email-completed-renewal-order.php' - ), - 'WCSG_Email_Customer_New_Account' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/emails/class-wcsg-email-customer-new-account.php' - ), - 'WCSG_Email_Processing_Renewal_Order' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/emails/class-wcsg-email-processing-renewal-order.php' - ), - 'WCSG_Email_Recipient_New_Initial_Order' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/emails/class-wcsg-email-recipient-new-initial-order.php' - ), - 'WCSG_Memberships_Integration' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-memberships-integration.php' - ), - 'WCSG_Privacy' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/privacy/class-wcsg-privacy.php' - ), - 'WCSG_Privacy_Erasers' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/privacy/class-wcsg-privacy-erasers.php' - ), - 'WCSG_Privacy_Exporters' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/privacy/class-wcsg-privacy-exporters.php' - ), - 'WCSG_Product' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-product.php' - ), - 'WCSG_Query' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-query.php' - ), - 'WCSG_Recipient_Addresses' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-recipient-addresses.php' - ), - 'WCSG_Recipient_Details' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-recipient-details.php' - ), - 'WCSG_Recipient_Management' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-recipient-management.php' - ), - 'WCSG_Template_Loader' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcsg-template-loader.php' - ), - 'WCS_Gifting' => array( - 'version' => 'dev-release/7.9.0', - 'path' => $baseDir . '/includes/gifting/class-wcs-gifting.php' - ), -); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 6cd6b53..589e9e7 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -19,7 +19,8 @@ if ($issues) { echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; } } - throw new \RuntimeException( - 'Composer detected issues in your platform: ' . implode(' ', $issues) + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR ); } diff --git a/vendor/jetpack-autoloader/class-autoloader-handler.php b/vendor/jetpack-autoloader/class-autoloader-handler.php deleted file mode 100644 index c6594ec..0000000 --- a/vendor/jetpack-autoloader/class-autoloader-handler.php +++ /dev/null @@ -1,147 +0,0 @@ -php_autoloader = $php_autoloader; - $this->hook_manager = $hook_manager; - $this->manifest_reader = $manifest_reader; - $this->version_selector = $version_selector; - } - - /** - * Checks to see whether or not an autoloader is currently in the process of initializing. - * - * @return bool - */ - public function is_initializing() { - // If no version has been set it means that no autoloader has started initializing yet. - global $jetpack_autoloader_latest_version; - if ( ! isset( $jetpack_autoloader_latest_version ) ) { - return false; - } - - // When the version is set but the classmap is not it ALWAYS means that this is the - // latest autoloader and is being included by an older one. - global $jetpack_packages_classmap; - if ( empty( $jetpack_packages_classmap ) ) { - return true; - } - - // Version 2.4.0 added a new global and altered the reset semantics. We need to check - // the other global as well since it may also point at initialization. - // Note: We don't need to check for the class first because every autoloader that - // will set the latest version global requires this class in the classmap. - $replacing_version = $jetpack_packages_classmap[ AutoloadGenerator::class ]['version']; - if ( $this->version_selector->is_dev_version( $replacing_version ) || version_compare( $replacing_version, '2.4.0.0', '>=' ) ) { - global $jetpack_autoloader_loader; - if ( ! isset( $jetpack_autoloader_loader ) ) { - return true; - } - } - - return false; - } - - /** - * Activates an autoloader using the given plugins and activates it. - * - * @param string[] $plugins The plugins to initialize the autoloader for. - */ - public function activate_autoloader( $plugins ) { - global $jetpack_packages_psr4; - $jetpack_packages_psr4 = array(); - $this->manifest_reader->read_manifests( $plugins, 'vendor/composer/jetpack_autoload_psr4.php', $jetpack_packages_psr4 ); - - global $jetpack_packages_classmap; - $jetpack_packages_classmap = array(); - $this->manifest_reader->read_manifests( $plugins, 'vendor/composer/jetpack_autoload_classmap.php', $jetpack_packages_classmap ); - - global $jetpack_packages_filemap; - $jetpack_packages_filemap = array(); - $this->manifest_reader->read_manifests( $plugins, 'vendor/composer/jetpack_autoload_filemap.php', $jetpack_packages_filemap ); - - $loader = new Version_Loader( - $this->version_selector, - $jetpack_packages_classmap, - $jetpack_packages_psr4, - $jetpack_packages_filemap - ); - - $this->php_autoloader->register_autoloader( $loader ); - - // Now that the autoloader is active we can load the filemap. - $loader->load_filemap(); - } - - /** - * Resets the active autoloader and all related global state. - */ - public function reset_autoloader() { - $this->php_autoloader->unregister_autoloader(); - $this->hook_manager->reset(); - - // Clear all of the autoloader globals so that older autoloaders don't do anything strange. - global $jetpack_autoloader_latest_version; - $jetpack_autoloader_latest_version = null; - - global $jetpack_packages_classmap; - $jetpack_packages_classmap = array(); // Must be array to avoid exceptions in old autoloaders! - - global $jetpack_packages_psr4; - $jetpack_packages_psr4 = array(); // Must be array to avoid exceptions in old autoloaders! - - global $jetpack_packages_filemap; - $jetpack_packages_filemap = array(); // Must be array to avoid exceptions in old autoloaders! - } -} diff --git a/vendor/jetpack-autoloader/class-autoloader-locator.php b/vendor/jetpack-autoloader/class-autoloader-locator.php deleted file mode 100644 index bc85b91..0000000 --- a/vendor/jetpack-autoloader/class-autoloader-locator.php +++ /dev/null @@ -1,90 +0,0 @@ -version_selector = $version_selector; - } - - /** - * Finds the path to the plugin with the latest autoloader. - * - * @param array $plugin_paths An array of plugin paths. - * @param string $latest_version The latest version reference. @phan-output-reference. - * - * @return string|null - */ - public function find_latest_autoloader( $plugin_paths, &$latest_version ) { - $latest_plugin = null; - - foreach ( $plugin_paths as $plugin_path ) { - $version = $this->get_autoloader_version( $plugin_path ); - if ( ! $version || ! $this->version_selector->is_version_update_required( $latest_version, $version ) ) { - continue; - } - - $latest_version = $version; - $latest_plugin = $plugin_path; - } - - return $latest_plugin; - } - - /** - * Gets the path to the autoloader. - * - * @param string $plugin_path The path to the plugin. - * - * @return string - */ - public function get_autoloader_path( $plugin_path ) { - return trailingslashit( $plugin_path ) . 'vendor/autoload_packages.php'; - } - - /** - * Gets the version for the autoloader. - * - * @param string $plugin_path The path to the plugin. - * - * @return string|null - */ - public function get_autoloader_version( $plugin_path ) { - $classmap = trailingslashit( $plugin_path ) . 'vendor/composer/jetpack_autoload_classmap.php'; - if ( ! file_exists( $classmap ) ) { - return null; - } - - $classmap = require $classmap; - if ( isset( $classmap[ AutoloadGenerator::class ] ) ) { - return $classmap[ AutoloadGenerator::class ]['version']; - } - - return null; - } -} diff --git a/vendor/jetpack-autoloader/class-autoloader.php b/vendor/jetpack-autoloader/class-autoloader.php deleted file mode 100644 index 5f9bf5a..0000000 --- a/vendor/jetpack-autoloader/class-autoloader.php +++ /dev/null @@ -1,93 +0,0 @@ -get( Autoloader_Handler::class ); - - // If the autoloader is already initializing it means that it has included us as the latest. - $was_included_by_autoloader = $autoloader_handler->is_initializing(); - - /** @var Plugin_Locator $plugin_locator */ - $plugin_locator = $container->get( Plugin_Locator::class ); - - /** @var Plugins_Handler $plugins_handler */ - $plugins_handler = $container->get( Plugins_Handler::class ); - - // The current plugin is the one that we are attempting to initialize here. - $current_plugin = $plugin_locator->find_current_plugin(); - - // The active plugins are those that we were able to discover on the site. This list will not - // include mu-plugins, those activated by code, or those who are hidden by filtering. We also - // want to take care to not consider the current plugin unknown if it was included by an - // autoloader. This avoids the case where a plugin will be marked "active" while deactivated - // due to it having the latest autoloader. - $active_plugins = $plugins_handler->get_active_plugins( true, ! $was_included_by_autoloader ); - - // The cached plugins are all of those that were active or discovered by the autoloader during a previous request. - // Note that it's possible this list will include plugins that have since been deactivated, but after a request - // the cache should be updated and the deactivated plugins will be removed. - $cached_plugins = $plugins_handler->get_cached_plugins(); - - // We combine the active list and cached list to preemptively load classes for plugins that are - // presently unknown but will be loaded during the request. While this may result in us considering packages in - // deactivated plugins there shouldn't be any problems as a result and the eventual consistency is sufficient. - $all_plugins = array_merge( $active_plugins, $cached_plugins ); - - // In particular we also include the current plugin to address the case where it is the latest autoloader - // but also unknown (and not cached). We don't want it in the active list because we don't know that it - // is active but we need it in the all plugins list so that it is considered by the autoloader. - $all_plugins[] = $current_plugin; - - // We require uniqueness in the array to avoid processing the same plugin more than once. - $all_plugins = array_values( array_unique( $all_plugins ) ); - - /** @var Latest_Autoloader_Guard $guard */ - $guard = $container->get( Latest_Autoloader_Guard::class ); - if ( $guard->should_stop_init( $current_plugin, $all_plugins, $was_included_by_autoloader ) ) { - return; - } - - // Initialize the autoloader using the handler now that we're ready. - $autoloader_handler->activate_autoloader( $all_plugins ); - - /** @var Hook_Manager $hook_manager */ - $hook_manager = $container->get( Hook_Manager::class ); - - // Register a shutdown handler to clean up the autoloader. - $hook_manager->add_action( 'shutdown', new Shutdown_Handler( $plugins_handler, $cached_plugins, $was_included_by_autoloader ) ); - - // Register a plugins_loaded handler to check for conflicting autoloaders. - $hook_manager->add_action( 'plugins_loaded', array( $guard, 'check_for_conflicting_autoloaders' ), 1 ); - - // phpcs:enable Generic.Commenting.DocComment.MissingShort - } -} diff --git a/vendor/jetpack-autoloader/class-container.php b/vendor/jetpack-autoloader/class-container.php deleted file mode 100644 index f547865..0000000 --- a/vendor/jetpack-autoloader/class-container.php +++ /dev/null @@ -1,150 +0,0 @@ - 'Hook_Manager', - ); - - /** - * A map of all the dependencies we've registered with the container and created. - * - * @var array - */ - protected $dependencies; - - /** - * The constructor. - */ - public function __construct() { - $this->dependencies = array(); - - $this->register_shared_dependencies(); - $this->register_dependencies(); - $this->initialize_globals(); - } - - /** - * Gets a dependency out of the container. - * - * @param string $class The class to fetch. - * - * @return mixed - * @throws \InvalidArgumentException When a class that isn't registered with the container is fetched. - */ - public function get( $class ) { - if ( ! isset( $this->dependencies[ $class ] ) ) { - throw new \InvalidArgumentException( "Class '$class' is not registered with the container." ); - } - - return $this->dependencies[ $class ]; - } - - /** - * Registers all of the dependencies that are shared between all instances of the autoloader. - */ - private function register_shared_dependencies() { - global $jetpack_autoloader_container_shared; - if ( ! isset( $jetpack_autoloader_container_shared ) ) { - $jetpack_autoloader_container_shared = array(); - } - - $key = self::SHARED_DEPENDENCY_KEYS[ Hook_Manager::class ]; - if ( ! isset( $jetpack_autoloader_container_shared[ $key ] ) ) { - require_once __DIR__ . '/class-hook-manager.php'; - $jetpack_autoloader_container_shared[ $key ] = new Hook_Manager(); - } - $this->dependencies[ Hook_Manager::class ] = &$jetpack_autoloader_container_shared[ $key ]; - } - - /** - * Registers all of the dependencies with the container. - */ - private function register_dependencies() { - require_once __DIR__ . '/class-path-processor.php'; - $this->dependencies[ Path_Processor::class ] = new Path_Processor(); - - require_once __DIR__ . '/class-plugin-locator.php'; - $this->dependencies[ Plugin_Locator::class ] = new Plugin_Locator( - $this->get( Path_Processor::class ) - ); - - require_once __DIR__ . '/class-version-selector.php'; - $this->dependencies[ Version_Selector::class ] = new Version_Selector(); - - require_once __DIR__ . '/class-autoloader-locator.php'; - $this->dependencies[ Autoloader_Locator::class ] = new Autoloader_Locator( - $this->get( Version_Selector::class ) - ); - - require_once __DIR__ . '/class-php-autoloader.php'; - $this->dependencies[ PHP_Autoloader::class ] = new PHP_Autoloader(); - - require_once __DIR__ . '/class-manifest-reader.php'; - $this->dependencies[ Manifest_Reader::class ] = new Manifest_Reader( - $this->get( Version_Selector::class ) - ); - - require_once __DIR__ . '/class-plugins-handler.php'; - $this->dependencies[ Plugins_Handler::class ] = new Plugins_Handler( - $this->get( Plugin_Locator::class ), - $this->get( Path_Processor::class ) - ); - - require_once __DIR__ . '/class-autoloader-handler.php'; - $this->dependencies[ Autoloader_Handler::class ] = new Autoloader_Handler( - $this->get( PHP_Autoloader::class ), - $this->get( Hook_Manager::class ), - $this->get( Manifest_Reader::class ), - $this->get( Version_Selector::class ) - ); - - require_once __DIR__ . '/class-latest-autoloader-guard.php'; - $this->dependencies[ Latest_Autoloader_Guard::class ] = new Latest_Autoloader_Guard( - $this->get( Plugins_Handler::class ), - $this->get( Autoloader_Handler::class ), - $this->get( Autoloader_Locator::class ) - ); - - // Register any classes that we will use elsewhere. - require_once __DIR__ . '/class-version-loader.php'; - require_once __DIR__ . '/class-shutdown-handler.php'; - } - - /** - * Initializes any of the globals needed by the autoloader. - */ - private function initialize_globals() { - /* - * This global was retired in version 2.9. The value is set to 'false' to maintain - * compatibility with older versions of the autoloader. - */ - global $jetpack_autoloader_including_latest; - $jetpack_autoloader_including_latest = false; - - // Not all plugins can be found using the locator. In cases where a plugin loads the autoloader - // but was not discoverable, we will record them in this array to track them as "active". - global $jetpack_autoloader_activating_plugins_paths; - if ( ! isset( $jetpack_autoloader_activating_plugins_paths ) ) { - $jetpack_autoloader_activating_plugins_paths = array(); - } - } -} diff --git a/vendor/jetpack-autoloader/class-hook-manager.php b/vendor/jetpack-autoloader/class-hook-manager.php deleted file mode 100644 index 31f8345..0000000 --- a/vendor/jetpack-autoloader/class-hook-manager.php +++ /dev/null @@ -1,76 +0,0 @@ -registered_hooks = array(); - } - - /** - * Adds an action to WordPress and registers it internally. - * - * @param string $tag The name of the action which is hooked. - * @param callable $callable The function to call. - * @param int $priority Used to specify the priority of the action. - * @param int $accepted_args Used to specify the number of arguments the callable accepts. - */ - public function add_action( $tag, $callable, $priority = 10, $accepted_args = 1 ) { - $this->registered_hooks[ $tag ][] = array( - 'priority' => $priority, - 'callable' => $callable, - ); - - add_action( $tag, $callable, $priority, $accepted_args ); - } - - /** - * Adds a filter to WordPress and registers it internally. - * - * @param string $tag The name of the filter which is hooked. - * @param callable $callable The function to call. - * @param int $priority Used to specify the priority of the filter. - * @param int $accepted_args Used to specify the number of arguments the callable accepts. - */ - public function add_filter( $tag, $callable, $priority = 10, $accepted_args = 1 ) { - $this->registered_hooks[ $tag ][] = array( - 'priority' => $priority, - 'callable' => $callable, - ); - - add_filter( $tag, $callable, $priority, $accepted_args ); - } - - /** - * Removes all of the registered hooks. - */ - public function reset() { - foreach ( $this->registered_hooks as $tag => $hooks ) { - foreach ( $hooks as $hook ) { - remove_filter( $tag, $hook['callable'], $hook['priority'] ); - } - } - $this->registered_hooks = array(); - } -} diff --git a/vendor/jetpack-autoloader/class-latest-autoloader-guard.php b/vendor/jetpack-autoloader/class-latest-autoloader-guard.php deleted file mode 100644 index dd12d87..0000000 --- a/vendor/jetpack-autoloader/class-latest-autoloader-guard.php +++ /dev/null @@ -1,165 +0,0 @@ -plugins_handler = $plugins_handler; - $this->autoloader_handler = $autoloader_handler; - $this->autoloader_locator = $autoloader_locator; - } - - /** - * Indicates whether or not the autoloader should be initialized. Note that this function - * has the side-effect of actually loading the latest autoloader in the event that this - * is not it. - * - * @param string $current_plugin The current plugin we're checking. - * @param string[] $plugins The active plugins to check for autoloaders in. - * @param bool $was_included_by_autoloader Indicates whether or not this autoloader was included by another. - * - * @return bool True if we should stop initialization, otherwise false. - */ - public function should_stop_init( $current_plugin, $plugins, $was_included_by_autoloader ) { - global $jetpack_autoloader_latest_version; - - // We need to reset the autoloader when the plugins change because - // that means the autoloader was generated with a different list. - if ( $this->plugins_handler->have_plugins_changed( $plugins ) ) { - $this->autoloader_handler->reset_autoloader(); - } - - // When the latest autoloader has already been found we don't need to search for it again. - // We should take care however because this will also trigger if the autoloader has been - // included by an older one. - if ( isset( $jetpack_autoloader_latest_version ) && ! $was_included_by_autoloader ) { - return true; - } - - $latest_plugin = $this->autoloader_locator->find_latest_autoloader( $plugins, $jetpack_autoloader_latest_version ); - if ( isset( $latest_plugin ) && $latest_plugin !== $current_plugin ) { - require $this->autoloader_locator->get_autoloader_path( $latest_plugin ); - return true; - } - - return false; - } - - /** - * Check for conflicting autoloaders. - * - * A common source of strange and confusing problems is when another plugin - * registers a Composer autoloader at a higher priority that us. If enabled, - * check for this problem and warn about it. - * - * Called from the plugins_loaded hook. - * - * @since 3.1.0 - * @return void - */ - public function check_for_conflicting_autoloaders() { - if ( ! defined( 'JETPACK_AUTOLOAD_DEBUG_CONFLICTING_LOADERS' ) || ! JETPACK_AUTOLOAD_DEBUG_CONFLICTING_LOADERS ) { - return; - } - - global $jetpack_autoloader_loader; - if ( ! isset( $jetpack_autoloader_loader ) ) { - return; - } - $prefixes = array(); - foreach ( ( $jetpack_autoloader_loader->get_class_map() ?? array() ) as $classname => $data ) { - $parts = explode( '\\', trim( $classname, '\\' ) ); - array_pop( $parts ); - while ( $parts ) { - $prefixes[ implode( '\\', $parts ) . '\\' ] = true; - array_pop( $parts ); - } - } - foreach ( ( $jetpack_autoloader_loader->get_psr4_map() ?? array() ) as $prefix => $data ) { - $parts = explode( '\\', trim( $prefix, '\\' ) ); - while ( $parts ) { - $prefixes[ implode( '\\', $parts ) . '\\' ] = true; - array_pop( $parts ); - } - } - - $autoload_chain = spl_autoload_functions(); - if ( ! $autoload_chain ) { - return; - } - - foreach ( $autoload_chain as $autoloader ) { - // No need to check anything after us. - if ( is_array( $autoloader ) && is_string( $autoloader[0] ) && substr( $autoloader[0], 0, strlen( __NAMESPACE__ ) + 1 ) === __NAMESPACE__ . '\\' ) { - break; - } - - // We can check Composer autoloaders easily enough. - if ( is_array( $autoloader ) && $autoloader[0] instanceof \Composer\Autoload\ClassLoader && is_callable( array( $autoloader[0], 'getPrefixesPsr4' ) ) ) { - $composer_autoloader = $autoloader[0]; - foreach ( $composer_autoloader->getClassMap() as $classname => $path ) { - if ( $jetpack_autoloader_loader->find_class_file( $classname ) ) { - $msg = "A Composer autoloader is registered with a higher priority than the Jetpack Autoloader and would also handle some of the classes we handle (e.g. $classname => $path). This may cause strange and confusing problems."; - wp_trigger_error( '', $msg ); - continue 2; - } - } - foreach ( $composer_autoloader->getPrefixesPsr4() as $prefix => $paths ) { - if ( isset( $prefixes[ $prefix ] ) ) { - $path = array_pop( $paths ); - $msg = "A Composer autoloader is registered with a higher priority than the Jetpack Autoloader and would also handle some of the namespaces we handle (e.g. $prefix => $path). This may cause strange and confusing problems."; - wp_trigger_error( '', $msg ); - continue 2; - } - } - foreach ( $composer_autoloader->getPrefixes() as $prefix => $paths ) { - if ( isset( $prefixes[ $prefix ] ) ) { - $path = array_pop( $paths ); - $msg = "A Composer autoloader is registered with a higher priority than the Jetpack Autoloader and would also handle some of the namespaces we handle (e.g. $prefix => $path). This may cause strange and confusing problems."; - wp_trigger_error( '', $msg ); - continue 2; - } - } - } - } - } -} diff --git a/vendor/jetpack-autoloader/class-manifest-reader.php b/vendor/jetpack-autoloader/class-manifest-reader.php deleted file mode 100644 index 38b8671..0000000 --- a/vendor/jetpack-autoloader/class-manifest-reader.php +++ /dev/null @@ -1,99 +0,0 @@ -version_selector = $version_selector; - } - - /** - * Reads all of the manifests in the given plugin paths. - * - * @param array $plugin_paths The paths to the plugins we're loading the manifest in. - * @param string $manifest_path The path that we're loading the manifest from in each plugin. - * @param array $path_map The path map to add the contents of the manifests to. - * - * @return array $path_map The path map we've built using the manifests in each plugin. - */ - public function read_manifests( $plugin_paths, $manifest_path, &$path_map ) { - $file_paths = array_map( - function ( $path ) use ( $manifest_path ) { - return trailingslashit( $path ) . $manifest_path; - }, - $plugin_paths - ); - - foreach ( $file_paths as $path ) { - $this->register_manifest( $path, $path_map ); - } - - return $path_map; - } - - /** - * Registers a plugin's manifest file with the path map. - * - * @param string $manifest_path The absolute path to the manifest that we're loading. - * @param array $path_map The path map to add the contents of the manifest to. - */ - protected function register_manifest( $manifest_path, &$path_map ) { - if ( ! is_readable( $manifest_path ) ) { - return; - } - - $manifest = require $manifest_path; - if ( ! is_array( $manifest ) ) { - return; - } - - foreach ( $manifest as $key => $data ) { - $this->register_record( $key, $data, $path_map ); - } - } - - /** - * Registers an entry from the manifest in the path map. - * - * @param string $key The identifier for the entry we're registering. - * @param array $data The data for the entry we're registering. - * @param array $path_map The path map to add the contents of the manifest to. - */ - protected function register_record( $key, $data, &$path_map ) { - if ( isset( $path_map[ $key ]['version'] ) ) { - $selected_version = $path_map[ $key ]['version']; - } else { - $selected_version = null; - } - - if ( $this->version_selector->is_version_update_required( $selected_version, $data['version'] ) ) { - $path_map[ $key ] = array( - 'version' => $data['version'], - 'path' => $data['path'], - ); - } - } -} diff --git a/vendor/jetpack-autoloader/class-path-processor.php b/vendor/jetpack-autoloader/class-path-processor.php deleted file mode 100644 index e70bf26..0000000 --- a/vendor/jetpack-autoloader/class-path-processor.php +++ /dev/null @@ -1,194 +0,0 @@ -get_normalized_constants(); - foreach ( $constants as $constant => $constant_path ) { - $len = strlen( $constant_path ); - if ( substr( $path, 0, $len ) !== $constant_path ) { - continue; - } - - return substr_replace( $path, '{{' . $constant . '}}', 0, $len ); - } - - return $path; - } - - /** - * Given a path this will replace any of the path constant tokens with the expanded path. - * - * @param string $tokenized_path The path we want to process. - * - * @return string The expanded path. - */ - public function untokenize_path_constants( $tokenized_path ) { - $tokenized_path = wp_normalize_path( $tokenized_path ); - - $constants = $this->get_normalized_constants(); - foreach ( $constants as $constant => $constant_path ) { - $constant = '{{' . $constant . '}}'; - - $len = strlen( $constant ); - if ( substr( $tokenized_path, 0, $len ) !== $constant ) { - continue; - } - - return $this->get_real_path( substr_replace( $tokenized_path, $constant_path, 0, $len ) ); - } - - return $tokenized_path; - } - - /** - * Given a file and an array of places it might be, this will find the absolute path and return it. - * - * @param string $file The plugin or theme file to resolve. - * @param array $directories_to_check The directories we should check for the file if it isn't an absolute path. - * - * @return string|false Returns the absolute path to the directory, otherwise false. - */ - public function find_directory_with_autoloader( $file, $directories_to_check ) { - $file = wp_normalize_path( $file ); - - if ( ! $this->is_absolute_path( $file ) ) { - $file = $this->find_absolute_plugin_path( $file, $directories_to_check ); - if ( ! isset( $file ) ) { - return false; - } - } - - // We need the real path for consistency with __DIR__ paths. - $file = $this->get_real_path( $file ); - - // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged - $directory = @is_file( $file ) ? dirname( $file ) : $file; - if ( ! @is_file( $directory . '/vendor/composer/jetpack_autoload_classmap.php' ) ) { - return false; - } - // phpcs:enable WordPress.PHP.NoSilencedErrors.Discouraged - - return $directory; - } - - /** - * Fetches an array of normalized paths keyed by the constant they came from. - * - * @return string[] The normalized paths keyed by the constant. - */ - private function get_normalized_constants() { - $raw_constants = array( - // Order the constants from most-specific to least-specific. - 'WP_PLUGIN_DIR', - 'WPMU_PLUGIN_DIR', - 'WP_CONTENT_DIR', - 'ABSPATH', - ); - - $constants = array(); - foreach ( $raw_constants as $raw ) { - if ( ! defined( $raw ) ) { - continue; - } - - $path = wp_normalize_path( constant( $raw ) ); - if ( isset( $path ) ) { - $constants[ $raw ] = $path; - } - } - - return $constants; - } - - /** - * Indicates whether or not a path is absolute. - * - * @param string $path The path to check. - * - * @return bool True if the path is absolute, otherwise false. - */ - private function is_absolute_path( $path ) { - if ( empty( $path ) || 0 === strlen( $path ) || '.' === $path[0] ) { - return false; - } - - // Absolute paths on Windows may begin with a drive letter. - if ( preg_match( '/^[a-zA-Z]:[\/\\\\]/', $path ) ) { - return true; - } - - // A path starting with / or \ is absolute; anything else is relative. - return ( '/' === $path[0] || '\\' === $path[0] ); - } - - /** - * Given a file and a list of directories to check, this method will try to figure out - * the absolute path to the file in question. - * - * @param string $normalized_path The normalized path to the plugin or theme file to resolve. - * @param array $directories_to_check The directories we should check for the file if it isn't an absolute path. - * - * @return string|null The absolute path to the plugin file, otherwise null. - */ - private function find_absolute_plugin_path( $normalized_path, $directories_to_check ) { - // We're only able to find the absolute path for plugin/theme PHP files. - if ( ! is_string( $normalized_path ) || '.php' !== substr( $normalized_path, -4 ) ) { - return null; - } - - foreach ( $directories_to_check as $directory ) { - $normalized_check = wp_normalize_path( trailingslashit( $directory ) ) . $normalized_path; - // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged - if ( @is_file( $normalized_check ) ) { - return $normalized_check; - } - } - - return null; - } - - /** - * Given a path this will figure out the real path that we should be using. - * - * @param string $path The path to resolve. - * - * @return string The resolved path. - */ - private function get_real_path( $path ) { - // We want to resolve symbolic links for consistency with __DIR__ paths. - // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged - $real_path = @realpath( $path ); - if ( false === $real_path ) { - // Let the autoloader deal with paths that don't exist. - $real_path = $path; - } - - // Using realpath will make it platform-specific so we must normalize it after. - if ( $path !== $real_path ) { - $real_path = wp_normalize_path( $real_path ); - } - - return $real_path; - } -} diff --git a/vendor/jetpack-autoloader/class-php-autoloader.php b/vendor/jetpack-autoloader/class-php-autoloader.php deleted file mode 100644 index 89088cb..0000000 --- a/vendor/jetpack-autoloader/class-php-autoloader.php +++ /dev/null @@ -1,105 +0,0 @@ -unregister_autoloader(); - - // Set the global so that it can be used to load classes. - global $jetpack_autoloader_loader; - $jetpack_autoloader_loader = $version_loader; - - // Ensure that the autoloader is first to avoid contention with others. - spl_autoload_register( array( self::class, 'load_class' ), true, true ); - } - - /** - * Unregisters the active autoloader so that it will no longer autoload classes. - */ - public function unregister_autoloader() { - // Remove any v2 autoloader that we've already registered. - $autoload_chain = spl_autoload_functions(); - if ( ! $autoload_chain ) { - return; - } - foreach ( $autoload_chain as $autoloader ) { - // We can identify a v2 autoloader using the namespace. - $namespace_check = null; - - // Functions are recorded as strings. - if ( is_string( $autoloader ) ) { - $namespace_check = $autoloader; - } elseif ( is_array( $autoloader ) && is_string( $autoloader[0] ) ) { - // Static method calls have the class as the first array element. - $namespace_check = $autoloader[0]; - } else { - // Since the autoloader has only ever been a function or a static method we don't currently need to check anything else. - continue; - } - - // Check for the namespace without the generated suffix. - if ( 'Automattic\\Jetpack\\Autoloader\\jp' === substr( $namespace_check, 0, 32 ) ) { - spl_autoload_unregister( $autoloader ); - } - } - - // Clear the global now that the autoloader has been unregistered. - global $jetpack_autoloader_loader; - $jetpack_autoloader_loader = null; - } - - /** - * Loads a class file if one could be found. - * - * Note: This function is static so that the autoloader can be easily unregistered. If - * it was a class method we would have to unwrap the object to check the namespace. - * - * @param string $class_name The name of the class to autoload. - * - * @return bool Indicates whether or not a class file was loaded. - */ - public static function load_class( $class_name ) { - global $jetpack_autoloader_loader; - if ( ! isset( $jetpack_autoloader_loader ) ) { - return false; - } - - $file = $jetpack_autoloader_loader->find_class_file( $class_name ); - if ( ! isset( $file ) ) { - return false; - } - - // A common source of strange and confusing problems is when a vendor - // file is autoloaded before all plugins have had a chance to register - // with the autoloader. Detect that, if a development constant is set. - if ( defined( 'JETPACK_AUTOLOAD_DEBUG_EARLY_LOADS' ) && JETPACK_AUTOLOAD_DEBUG_EARLY_LOADS && - ( strpos( $file, '/vendor/' ) !== false || strpos( $file, '/jetpack_vendor/' ) !== false ) && - is_callable( 'did_action' ) && ! did_action( 'plugins_loaded' ) - ) { - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_wp_debug_backtrace_summary -- This is a debug log message. - $msg = "Jetpack Autoloader: Autoloading `$class_name` before the plugins_loaded hook may cause strange and confusing problems. " . wp_debug_backtrace_summary( '', 1 ); - wp_trigger_error( '', $msg ); - } - - require $file; - return true; - } -} diff --git a/vendor/jetpack-autoloader/class-plugin-locator.php b/vendor/jetpack-autoloader/class-plugin-locator.php deleted file mode 100644 index 8241cda..0000000 --- a/vendor/jetpack-autoloader/class-plugin-locator.php +++ /dev/null @@ -1,153 +0,0 @@ -path_processor = $path_processor; - } - - /** - * Finds the path to the current plugin. - * - * @return string $path The path to the current plugin. - * - * @throws \RuntimeException If the current plugin does not have an autoloader. - */ - public function find_current_plugin() { - // Escape from `vendor/__DIR__` to root plugin directory. - $plugin_directory = dirname( __DIR__, 2 ); - - // Use the path processor to ensure that this is an autoloader we're referencing. - $path = $this->path_processor->find_directory_with_autoloader( $plugin_directory, array() ); - if ( false === $path ) { - throw new \RuntimeException( 'Failed to locate plugin ' . $plugin_directory ); - } - - return $path; - } - - /** - * Checks a given option for plugin paths. - * - * @param string $option_name The option that we want to check for plugin information. - * @param bool $site_option Indicates whether or not we want to check the site option. - * - * @return array $plugin_paths The list of absolute paths we've found. - */ - public function find_using_option( $option_name, $site_option = false ) { - $raw = $site_option ? get_site_option( $option_name ) : get_option( $option_name ); - if ( false === $raw ) { - return array(); - } - - return $this->convert_plugins_to_paths( $raw ); - } - - /** - * Checks for plugins in the `action` request parameter. - * - * @param string[] $allowed_actions The actions that we're allowed to return plugins for. - * - * @return array $plugin_paths The list of absolute paths we've found. - */ - public function find_using_request_action( $allowed_actions ) { - /** - * Note: we're not actually checking the nonce here because it's too early - * in the execution. The pluggable functions are not yet loaded to give - * plugins a chance to plug their versions. Therefore we're doing the bare - * minimum: checking whether the nonce exists and it's in the right place. - * The request will fail later if the nonce doesn't pass the check. - */ - if ( empty( $_REQUEST['_wpnonce'] ) ) { - return array(); - } - - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated just below. - $action = isset( $_REQUEST['action'] ) ? wp_unslash( $_REQUEST['action'] ) : false; - if ( ! in_array( $action, $allowed_actions, true ) ) { - return array(); - } - - $plugin_slugs = array(); - switch ( $action ) { - case 'activate': - case 'deactivate': - if ( empty( $_REQUEST['plugin'] ) ) { - break; - } - - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated by convert_plugins_to_paths. - $plugin_slugs[] = wp_unslash( $_REQUEST['plugin'] ); - break; - - case 'activate-selected': - case 'deactivate-selected': - if ( empty( $_REQUEST['checked'] ) ) { - break; - } - - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated by convert_plugins_to_paths. - $plugin_slugs = wp_unslash( $_REQUEST['checked'] ); - break; - } - - return $this->convert_plugins_to_paths( $plugin_slugs ); - } - - /** - * Given an array of plugin slugs or paths, this will convert them to absolute paths and filter - * out the plugins that are not directory plugins. Note that array keys will also be included - * if they are plugin paths! - * - * @param string[] $plugins Plugin paths or slugs to filter. - * - * @return string[] - */ - private function convert_plugins_to_paths( $plugins ) { - if ( ! is_array( $plugins ) || empty( $plugins ) ) { - return array(); - } - - // We're going to look for plugins in the standard directories. - $path_constants = array( WP_PLUGIN_DIR, WPMU_PLUGIN_DIR ); - - $plugin_paths = array(); - foreach ( $plugins as $key => $value ) { - $path = $this->path_processor->find_directory_with_autoloader( $key, $path_constants ); - if ( $path ) { - $plugin_paths[] = $path; - } - - $path = $this->path_processor->find_directory_with_autoloader( $value, $path_constants ); - if ( $path ) { - $plugin_paths[] = $path; - } - } - - return $plugin_paths; - } -} diff --git a/vendor/jetpack-autoloader/class-plugins-handler.php b/vendor/jetpack-autoloader/class-plugins-handler.php deleted file mode 100644 index 55bdc6a..0000000 --- a/vendor/jetpack-autoloader/class-plugins-handler.php +++ /dev/null @@ -1,164 +0,0 @@ -plugin_locator = $plugin_locator; - $this->path_processor = $path_processor; - } - - /** - * Gets all of the active plugins we can find. - * - * @param bool $include_deactivating When true, plugins deactivating this request will be considered active. - * @param bool $record_unknown When true, the current plugin will be marked as active and recorded when unknown. - * - * @return string[] - */ - public function get_active_plugins( $include_deactivating, $record_unknown ) { - global $jetpack_autoloader_activating_plugins_paths; - - // We're going to build a unique list of plugins from a few different sources - // to find all of our "active" plugins. While we need to return an integer - // array, we're going to use an associative array internally to reduce - // the amount of time that we're going to spend checking uniqueness - // and merging different arrays together to form the output. - $active_plugins = array(); - - // Make sure that plugins which have activated this request are considered as "active" even though - // they probably won't be present in any option. - if ( is_array( $jetpack_autoloader_activating_plugins_paths ) ) { - foreach ( $jetpack_autoloader_activating_plugins_paths as $path ) { - $active_plugins[ $path ] = $path; - } - } - - // This option contains all of the plugins that have been activated. - $plugins = $this->plugin_locator->find_using_option( 'active_plugins' ); - foreach ( $plugins as $path ) { - $active_plugins[ $path ] = $path; - } - - // This option contains all of the multisite plugins that have been activated. - if ( is_multisite() ) { - $plugins = $this->plugin_locator->find_using_option( 'active_sitewide_plugins', true ); - foreach ( $plugins as $path ) { - $active_plugins[ $path ] = $path; - } - } - - // These actions contain plugins that are being activated/deactivated during this request. - $plugins = $this->plugin_locator->find_using_request_action( array( 'activate', 'activate-selected', 'deactivate', 'deactivate-selected' ) ); - foreach ( $plugins as $path ) { - $active_plugins[ $path ] = $path; - } - - // When the current plugin isn't considered "active" there's a problem. - // Since we're here, the plugin is active and currently being loaded. - // We can support this case (mu-plugins and non-standard activation) - // by adding the current plugin to the active list and marking it - // as an unknown (activating) plugin. This also has the benefit - // of causing a reset because the active plugins list has - // been changed since it was saved in the global. - $current_plugin = $this->plugin_locator->find_current_plugin(); - if ( $record_unknown && ! in_array( $current_plugin, $active_plugins, true ) ) { - $active_plugins[ $current_plugin ] = $current_plugin; - $jetpack_autoloader_activating_plugins_paths[] = $current_plugin; - } - - // When deactivating plugins aren't desired we should entirely remove them from the active list. - if ( ! $include_deactivating ) { - // These actions contain plugins that are being deactivated during this request. - $plugins = $this->plugin_locator->find_using_request_action( array( 'deactivate', 'deactivate-selected' ) ); - foreach ( $plugins as $path ) { - unset( $active_plugins[ $path ] ); - } - } - - // Transform the array so that we don't have to worry about the keys interacting with other array types later. - return array_values( $active_plugins ); - } - - /** - * Gets all of the cached plugins if there are any. - * - * @return string[] - */ - public function get_cached_plugins() { - $cached = get_transient( self::TRANSIENT_KEY ); - if ( ! is_array( $cached ) || empty( $cached ) ) { - return array(); - } - - // We need to expand the tokens to an absolute path for this webserver. - return array_map( array( $this->path_processor, 'untokenize_path_constants' ), $cached ); - } - - /** - * Saves the plugin list to the cache. - * - * @param array $plugins The plugin list to save to the cache. - */ - public function cache_plugins( $plugins ) { - // We store the paths in a tokenized form so that that webservers with different absolute paths don't break. - $plugins = array_map( array( $this->path_processor, 'tokenize_path_constants' ), $plugins ); - - set_transient( self::TRANSIENT_KEY, $plugins ); - } - - /** - * Checks to see whether or not the plugin list given has changed when compared to the - * shared `$jetpack_autoloader_cached_plugin_paths` global. This allows us to deal - * with cases where the active list may change due to filtering.. - * - * @param string[] $plugins The plugins list to check against the global cache. - * - * @return bool True if the plugins have changed, otherwise false. - */ - public function have_plugins_changed( $plugins ) { - global $jetpack_autoloader_cached_plugin_paths; - - if ( $jetpack_autoloader_cached_plugin_paths !== $plugins ) { - $jetpack_autoloader_cached_plugin_paths = $plugins; - return true; - } - - return false; - } -} diff --git a/vendor/jetpack-autoloader/class-shutdown-handler.php b/vendor/jetpack-autoloader/class-shutdown-handler.php deleted file mode 100644 index 6332d58..0000000 --- a/vendor/jetpack-autoloader/class-shutdown-handler.php +++ /dev/null @@ -1,92 +0,0 @@ -plugins_handler = $plugins_handler; - $this->cached_plugins = $cached_plugins; - $this->was_included_by_autoloader = $was_included_by_autoloader; - } - - /** - * Handles the shutdown of the autoloader. - */ - public function __invoke() { - // Don't save a broken cache if an error happens during some plugin's initialization. - if ( ! did_action( 'plugins_loaded' ) ) { - // Ensure that the cache is emptied to prevent consecutive failures if the cache is to blame. - if ( ! empty( $this->cached_plugins ) ) { - $this->plugins_handler->cache_plugins( array() ); - } - - return; - } - - // Load the active plugins fresh since the list we pulled earlier might not contain - // plugins that were activated but did not reset the autoloader. This happens - // when a plugin is in the cache but not "active" when the autoloader loads. - // We also want to make sure that plugins which are deactivating are not - // considered "active" so that they will be removed from the cache now. - try { - $active_plugins = $this->plugins_handler->get_active_plugins( false, ! $this->was_included_by_autoloader ); - } catch ( \Exception $ex ) { - // When the package is deleted before shutdown it will throw an exception. - // In the event this happens we should erase the cache. - if ( ! empty( $this->cached_plugins ) ) { - $this->plugins_handler->cache_plugins( array() ); - } - return; - } - - // The paths should be sorted for easy comparisons with those loaded from the cache. - // Note we don't need to sort the cached entries because they're already sorted. - sort( $active_plugins ); - - // We don't want to waste time saving a cache that hasn't changed. - if ( $this->cached_plugins === $active_plugins ) { - return; - } - - $this->plugins_handler->cache_plugins( $active_plugins ); - } -} diff --git a/vendor/jetpack-autoloader/class-version-loader.php b/vendor/jetpack-autoloader/class-version-loader.php deleted file mode 100644 index 65003c4..0000000 --- a/vendor/jetpack-autoloader/class-version-loader.php +++ /dev/null @@ -1,184 +0,0 @@ -version_selector = $version_selector; - $this->classmap = $classmap; - $this->psr4_map = $psr4_map; - $this->filemap = $filemap; - } - - /** - * Fetch the classmap. - * - * @since 3.1.0 - * @return array - */ - public function get_class_map() { - return $this->classmap; - } - - /** - * Fetch the psr-4 mappings. - * - * @since 3.1.0 - * @return array - */ - public function get_psr4_map() { - return $this->psr4_map; - } - - /** - * Finds the file path for the given class. - * - * @param string $class_name The class to find. - * - * @return string|null $file_path The path to the file if found, null if no class was found. - */ - public function find_class_file( $class_name ) { - $data = $this->select_newest_file( - $this->classmap[ $class_name ] ?? null, - $this->find_psr4_file( $class_name ) - ); - if ( ! isset( $data ) ) { - return null; - } - - return $data['path']; - } - - /** - * Load all of the files in the filemap. - */ - public function load_filemap() { - if ( empty( $this->filemap ) ) { - return; - } - - foreach ( $this->filemap as $file_identifier => $file_data ) { - if ( empty( $GLOBALS['__composer_autoload_files'][ $file_identifier ] ) ) { - require_once $file_data['path']; - - $GLOBALS['__composer_autoload_files'][ $file_identifier ] = true; - } - } - } - - /** - * Compares different class sources and returns the newest. - * - * @param array|null $classmap_data The classmap class data. - * @param array|null $psr4_data The PSR-4 class data. - * - * @return array|null $data - */ - private function select_newest_file( $classmap_data, $psr4_data ) { - if ( ! isset( $classmap_data ) ) { - return $psr4_data; - } elseif ( ! isset( $psr4_data ) ) { - return $classmap_data; - } - - if ( $this->version_selector->is_version_update_required( $classmap_data['version'], $psr4_data['version'] ) ) { - return $psr4_data; - } - - return $classmap_data; - } - - /** - * Finds the file for a given class in a PSR-4 namespace. - * - * @param string $class_name The class to find. - * - * @return array|null $data The version and path path to the file if found, null otherwise. - */ - private function find_psr4_file( $class_name ) { - if ( empty( $this->psr4_map ) ) { - return null; - } - - // Don't bother with classes that have no namespace. - $class_index = strrpos( $class_name, '\\' ); - if ( ! $class_index ) { - return null; - } - $class_for_path = str_replace( '\\', '/', $class_name ); - - // Search for the namespace by iteratively cutting off the last segment until - // we find a match. This allows us to check the most-specific namespaces - // first as well as minimize the amount of time spent looking. - for ( - $class_namespace = substr( $class_name, 0, $class_index ); - ! empty( $class_namespace ); - $class_namespace = substr( $class_namespace, 0, strrpos( $class_namespace, '\\' ) ) - ) { - $namespace = $class_namespace . '\\'; - if ( ! isset( $this->psr4_map[ $namespace ] ) ) { - continue; - } - $data = $this->psr4_map[ $namespace ]; - - foreach ( $data['path'] as $path ) { - $path .= '/' . substr( $class_for_path, strlen( $namespace ) ) . '.php'; - if ( file_exists( $path ) ) { - return array( - 'version' => $data['version'], - 'path' => $path, - ); - } - } - } - - return null; - } -} diff --git a/vendor/jetpack-autoloader/class-version-selector.php b/vendor/jetpack-autoloader/class-version-selector.php deleted file mode 100644 index 1e224a9..0000000 --- a/vendor/jetpack-autoloader/class-version-selector.php +++ /dev/null @@ -1,69 +0,0 @@ -is_dev_version( $selected_version ) ) { - return false; - } - - if ( $this->is_dev_version( $compare_version ) ) { - if ( $use_dev_versions ) { - return true; - } else { - return false; - } - } - - if ( version_compare( $selected_version, $compare_version, '<' ) ) { - return true; - } - - return false; - } - - /** - * Checks whether the given package version is a development version. - * - * @param String $version The package version. - * - * @return bool True if the version is a dev version, else false. - */ - public function is_dev_version( $version ) { - if ( 'dev-' === substr( $version, 0, 4 ) || '9999999-dev' === $version ) { - return true; - } - - return false; - } -} diff --git a/woocommerce-subscriptions.php b/woocommerce-subscriptions.php index 3577225..d826a05 100644 --- a/woocommerce-subscriptions.php +++ b/woocommerce-subscriptions.php @@ -5,11 +5,12 @@ * Description: Sell products and services with recurring payments in your WooCommerce Store. * Author: WooCommerce * Author URI: https://woocommerce.com/ - * Version: 7.9.0 + * Version: 8.0.0 * Requires Plugins: woocommerce * - * WC requires at least: 10.0.0 - * WC tested up to: 10.2.0 + * WC requires at least: 10.1.0 + * WC tested up to: 10.3.0 + * Requires PHP: 7.4 * * License: GNU General Public License v3.0 * License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -22,7 +23,7 @@ * @since 1.0 */ -require_once __DIR__ . '/vendor/autoload_packages.php'; +require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/includes/class-wc-subscriptions-dependency-manager.php'; $dependency_manager = new WC_Subscriptions_Dependency_Manager( WC_Subscriptions::$wc_minimum_supported_version ); @@ -74,7 +75,7 @@ class WC_Subscriptions { public static $plugin_file = __FILE__; /** @var string */ - public static $version = '7.9.0'; // WRCS: DEFINED_VERSION. + public static $version = '8.0.0'; // WRCS: DEFINED_VERSION. /** @var string */ public static $wc_minimum_supported_version = '7.7';