├── .nvmrc ├── assets ├── css │ ├── about.css │ ├── admin-empty-state.css │ ├── admin-order-statuses.css │ ├── admin.css │ ├── checkout.css │ ├── modal.css │ ├── view-subscription.css │ └── wcs-upgrade.css ├── images │ ├── add-edit-subscription-screen.png │ ├── admin-change-payment-method.jpg │ ├── ajax-loader.gif │ ├── ajax-loader@2x.gif │ ├── billing-schedules-meta-box.png │ ├── checkout-recurring-totals.png │ ├── drip-downloadable-content.jpg │ ├── gift-subscription.png │ ├── renewal-retry-settings.png │ ├── subscribe-all-the-things.png │ ├── subscription-reports.png │ ├── subscription-suspended-email.jpg │ ├── subscriptions-empty-state.svg │ ├── subscriptions-importer-exporter.png │ ├── view-subscription.png │ └── woocommerce_subscriptions_logo.png └── js │ ├── admin │ ├── admin-pointers.js │ ├── admin.js │ ├── jstz.js │ ├── jstz.min.js │ ├── meta-boxes-coupon.js │ ├── meta-boxes-subscription.js │ ├── moment.js │ ├── moment.min.js │ ├── payment-method-restrictions.js │ └── wcs-meta-boxes-order.js │ ├── frontend │ ├── payment-methods.js │ ├── single-product.js │ ├── view-subscription.js │ └── wcs-cart.js │ ├── modal.js │ └── wcs-upgrade.js ├── build ├── index.asset.php ├── index.css └── index.js ├── changelog.txt ├── includes ├── abstracts │ ├── abstract-wcs-background-repairer.php │ ├── abstract-wcs-background-updater.php │ ├── abstract-wcs-background-upgrader.php │ ├── abstract-wcs-cache-manager.php │ ├── abstract-wcs-customer-store.php │ ├── abstract-wcs-debug-tool-cache-updater.php │ ├── abstract-wcs-debug-tool.php │ ├── abstract-wcs-deprecated-functions-handler.php │ ├── abstract-wcs-dynamic-hook-deprecator.php │ ├── abstract-wcs-hook-deprecator.php │ ├── abstract-wcs-migrator.php │ ├── abstract-wcs-related-order-store.php │ ├── abstract-wcs-scheduler.php │ └── abstract-wcs-table-maker.php ├── admin │ ├── class-wc-subscriptions-admin.php │ ├── class-wcs-admin-empty-list-content-manager.php │ ├── class-wcs-admin-meta-boxes.php │ ├── class-wcs-admin-notice.php │ ├── class-wcs-admin-post-types.php │ ├── class-wcs-admin-product-import-export-manager.php │ ├── class-wcs-admin-system-status.php │ ├── class-wcs-wc-admin-manager.php │ ├── debug-tools │ │ ├── class-wcs-debug-tool-cache-background-updater.php │ │ ├── class-wcs-debug-tool-cache-eraser.php │ │ ├── class-wcs-debug-tool-cache-generator.php │ │ ├── class-wcs-debug-tool-factory.php │ │ └── class-wcs-notifications-debug-tool-processor.php │ ├── meta-boxes │ │ ├── class-wcs-meta-box-related-orders.php │ │ ├── class-wcs-meta-box-schedule.php │ │ ├── class-wcs-meta-box-subscription-data.php │ │ └── views │ │ │ ├── html-related-orders-row.php │ │ │ ├── html-related-orders-table.php │ │ │ ├── html-subscription-schedule.php │ │ │ └── html-unknown-related-orders-row.php │ └── wcs-admin-functions.php ├── class-wc-product-subscription-variation.php ├── class-wc-product-subscription.php ├── class-wc-product-variable-subscription.php ├── class-wc-subscription-item-coupon-pending-switch.php ├── class-wc-subscription-item-fee-pending-switch.php ├── class-wc-subscription-line-item-removed.php ├── class-wc-subscription-line-item-switched.php ├── class-wc-subscription-query-controller.php ├── class-wc-subscription.php ├── class-wc-subscriptions-addresses.php ├── class-wc-subscriptions-cart-validator.php ├── class-wc-subscriptions-cart.php ├── class-wc-subscriptions-change-payment-gateway.php ├── class-wc-subscriptions-checkout.php ├── class-wc-subscriptions-core-plugin.php ├── class-wc-subscriptions-coupon.php ├── class-wc-subscriptions-data-copier.php ├── class-wc-subscriptions-email-notifications.php ├── class-wc-subscriptions-email.php ├── class-wc-subscriptions-extend-store-endpoint.php ├── class-wc-subscriptions-frontend-scripts.php ├── class-wc-subscriptions-manager.php ├── class-wc-subscriptions-order.php ├── class-wc-subscriptions-product.php ├── class-wc-subscriptions-renewal-order.php ├── class-wc-subscriptions-synchroniser.php ├── class-wc-subscriptions-tracker.php ├── class-wcs-action-scheduler-customer-notifications.php ├── class-wcs-action-scheduler.php ├── class-wcs-batch-processing-controller.php ├── class-wcs-blocks-integration.php ├── class-wcs-cached-data-manager.php ├── class-wcs-cart-initial-payment.php ├── class-wcs-cart-renewal.php ├── class-wcs-cart-resubscribe.php ├── class-wcs-change-payment-method-admin.php ├── class-wcs-core-autoloader.php ├── class-wcs-custom-order-item-manager.php ├── class-wcs-dependent-hook-manager.php ├── class-wcs-download-handler.php ├── class-wcs-failed-scheduled-action-manager.php ├── class-wcs-initial-cart-stock-manager.php ├── class-wcs-limiter.php ├── class-wcs-modal.php ├── class-wcs-my-account-auto-renew-toggle.php ├── class-wcs-my-account-payment-methods.php ├── class-wcs-notifications-batch-processor.php ├── class-wcs-object-data-cache-manager-many-to-one.php ├── class-wcs-object-data-cache-manager.php ├── class-wcs-object-sorter.php ├── class-wcs-payment-tokens.php ├── class-wcs-permalink-manager.php ├── class-wcs-post-meta-cache-manager-many-to-one.php ├── class-wcs-post-meta-cache-manager.php ├── class-wcs-query.php ├── class-wcs-remove-item.php ├── class-wcs-renewal-cart-stock-manager.php ├── class-wcs-select2.php ├── class-wcs-sql-transaction.php ├── class-wcs-staging.php ├── class-wcs-template-loader.php ├── class-wcs-user-change-status-handler.php ├── data-stores │ ├── class-wcs-customer-store-cached-cpt.php │ ├── class-wcs-customer-store-cpt.php │ ├── class-wcs-orders-table-data-store-controller.php │ ├── class-wcs-orders-table-subscription-data-store.php │ ├── class-wcs-product-variable-data-store-cpt.php │ ├── class-wcs-related-order-store-cached-cpt.php │ ├── class-wcs-related-order-store-cpt.php │ └── class-wcs-subscription-data-store-cpt.php ├── deprecated │ ├── class-wcs-action-deprecator.php │ ├── class-wcs-deprecated-filter-hooks.php │ ├── class-wcs-dynamic-action-deprecator.php │ ├── class-wcs-dynamic-filter-deprecator.php │ ├── class-wcs-filter-deprecator.php │ └── deprecation-handlers │ │ └── class-wc-subscriptions-deprecation-handler.php ├── emails │ ├── class-wc-subscriptions-email-preview.php │ ├── class-wcs-email-cancelled-subscription.php │ ├── class-wcs-email-completed-renewal-order.php │ ├── class-wcs-email-completed-switch-order.php │ ├── class-wcs-email-customer-notification-auto-renewal.php │ ├── class-wcs-email-customer-notification-auto-trial-expiration.php │ ├── class-wcs-email-customer-notification-manual-renewal.php │ ├── class-wcs-email-customer-notification-manual-trial-expiration.php │ ├── class-wcs-email-customer-notification-subscription-expiration.php │ ├── class-wcs-email-customer-notification.php │ ├── class-wcs-email-customer-on-hold-renewal-order.php │ ├── class-wcs-email-customer-renewal-invoice.php │ ├── class-wcs-email-expired-subscription.php │ ├── class-wcs-email-new-renewal-order.php │ ├── class-wcs-email-new-switch-order.php │ ├── class-wcs-email-on-hold-subscription.php │ └── class-wcs-email-processing-renewal-order.php ├── gateways │ ├── class-wc-subscriptions-core-payment-gateways.php │ ├── class-wc-subscriptions-gateway-restrictions-manager.php │ └── paypal │ │ ├── class-wcs-paypal.php │ │ └── includes │ │ ├── abstracts │ │ └── abstract-wcs-sv-api-base.php │ │ ├── admin │ │ ├── class-wcs-paypal-admin.php │ │ └── class-wcs-paypal-change-payment-method-admin.php │ │ ├── class-wcs-paypal-reference-transaction-api-request.php │ │ ├── class-wcs-paypal-reference-transaction-api-response-billing-agreement.php │ │ ├── class-wcs-paypal-reference-transaction-api-response-checkout.php │ │ ├── class-wcs-paypal-reference-transaction-api-response-payment.php │ │ ├── class-wcs-paypal-reference-transaction-api-response-recurring-payment.php │ │ ├── class-wcs-paypal-reference-transaction-api-response.php │ │ ├── class-wcs-paypal-reference-transaction-api.php │ │ ├── class-wcs-paypal-reference-transaction-ipn-handler.php │ │ ├── class-wcs-paypal-standard-change-payment-method.php │ │ ├── class-wcs-paypal-standard-ipn-failure-handler.php │ │ ├── class-wcs-paypal-standard-ipn-handler.php │ │ ├── class-wcs-paypal-standard-request.php │ │ ├── class-wcs-paypal-standard-switcher.php │ │ ├── class-wcs-paypal-status-manager.php │ │ ├── class-wcs-paypal-supports.php │ │ ├── deprecated │ │ └── class-wc-paypal-standard-subscriptions.php │ │ ├── templates │ │ ├── admin-notices.php │ │ └── html-ipn-failure-notice.php │ │ └── wcs-paypal-functions.php ├── interfaces │ ├── interface-wcs-batch-processor.php │ └── interface-wcs-cache-updater.php ├── legacy │ ├── class-wc-product-subscription-legacy.php │ ├── class-wc-product-subscription-variation-legacy.php │ ├── class-wc-product-variable-subscription-legacy.php │ ├── class-wc-subscription-legacy.php │ ├── class-wcs-array-property-post-meta-black-magic.php │ └── class-wcs-product-legacy.php ├── privacy │ ├── class-wcs-privacy-background-updater.php │ ├── class-wcs-privacy-erasers.php │ ├── class-wcs-privacy-exporters.php │ └── class-wcs-privacy.php ├── upgrades │ ├── class-wc-subscriptions-upgrader.php │ ├── class-wcs-repair-2-0-2.php │ ├── class-wcs-repair-2-0.php │ ├── class-wcs-repair-line-item-has-trial-meta.php │ ├── class-wcs-repair-start-date-metadata.php │ ├── class-wcs-repair-subscription-address-indexes.php │ ├── class-wcs-repair-subtracted-base-tax-line-item-meta.php │ ├── class-wcs-repair-suspended-paypal-subscriptions.php │ ├── class-wcs-upgrade-1-2.php │ ├── class-wcs-upgrade-1-3.php │ ├── class-wcs-upgrade-1-4.php │ ├── class-wcs-upgrade-1-5.php │ ├── class-wcs-upgrade-2-0.php │ ├── class-wcs-upgrade-2-1.php │ ├── class-wcs-upgrade-2-2-7.php │ ├── class-wcs-upgrade-2-2-9.php │ ├── class-wcs-upgrade-3-1-0.php │ ├── class-wcs-upgrade-logger.php │ ├── class-wcs-upgrade-subscription-post-author.php │ └── templates │ │ ├── update-welcome-notice.php │ │ ├── wcs-about-2-0.php │ │ ├── wcs-about.php │ │ ├── wcs-upgrade-in-progress.php │ │ └── wcs-upgrade.php ├── wcs-cart-functions.php ├── wcs-compatibility-functions.php ├── wcs-conditional-functions.php ├── wcs-deprecated-functions.php ├── wcs-formatting-functions.php ├── wcs-helper-functions.php ├── wcs-limit-functions.php ├── wcs-order-functions.php ├── wcs-product-functions.php ├── wcs-renewal-functions.php ├── wcs-resubscribe-functions.php ├── wcs-switch-functions.php ├── wcs-time-functions.php └── wcs-user-functions.php ├── languages ├── woocommerce-subscriptions-fr.mo ├── woocommerce-subscriptions-fr.po └── woocommerce-subscriptions.pot ├── license.txt ├── templates ├── admin │ ├── deprecated │ │ ├── html-variation-price.php │ │ ├── html-variation-synchronisation.php │ │ ├── order-shipping-html.php │ │ └── order-tax-html.php │ ├── html-admin-empty-list-table.php │ ├── html-admin-notice.php │ ├── html-failed-scheduled-action-notice.php │ ├── html-variation-price.php │ ├── html-variation-synchronisation.php │ └── status.php ├── cart │ └── cart-recurring-shipping.php ├── checkout │ ├── form-change-payment-method.php │ ├── recurring-coupon-totals.php │ ├── recurring-fee-totals.php │ ├── recurring-itemized-tax-totals.php │ ├── recurring-subscription-totals.php │ ├── recurring-subtotals.php │ ├── recurring-tax-totals.php │ ├── recurring-totals.php │ └── subscription-receipt.php ├── emails │ ├── admin-new-renewal-order.php │ ├── admin-new-switch-order.php │ ├── admin-payment-retry.php │ ├── cancelled-subscription.php │ ├── customer-completed-renewal-order.php │ ├── customer-completed-switch-order.php │ ├── customer-notification-auto-renewal.php │ ├── customer-notification-auto-trial-ending.php │ ├── customer-notification-expiring-subscription.php │ ├── customer-notification-manual-renewal.php │ ├── customer-notification-manual-trial-ending.php │ ├── customer-on-hold-renewal-order.php │ ├── customer-payment-retry.php │ ├── customer-processing-renewal-order.php │ ├── customer-renewal-invoice.php │ ├── email-order-details.php │ ├── expired-subscription.php │ ├── on-hold-subscription.php │ ├── plain │ │ ├── admin-new-renewal-order.php │ │ ├── admin-new-switch-order.php │ │ ├── admin-payment-retry.php │ │ ├── cancelled-subscription.php │ │ ├── customer-completed-renewal-order.php │ │ ├── customer-completed-switch-order.php │ │ ├── customer-notification-auto-renewal.php │ │ ├── customer-notification-auto-trial-ending.php │ │ ├── customer-notification-expiring-subscription.php │ │ ├── customer-notification-manual-renewal.php │ │ ├── customer-notification-manual-trial-ending.php │ │ ├── customer-on-hold-renewal-order.php │ │ ├── customer-payment-retry.php │ │ ├── customer-processing-renewal-order.php │ │ ├── customer-renewal-invoice.php │ │ ├── email-order-details.php │ │ ├── expired-subscription.php │ │ ├── on-hold-subscription.php │ │ └── subscription-info.php │ └── subscription-info.php ├── html-modal.php ├── myaccount │ ├── my-subscriptions.php │ ├── related-orders.php │ ├── related-subscriptions.php │ ├── subscription-details.php │ ├── subscription-totals-table.php │ ├── subscription-totals.php │ ├── subscriptions.php │ └── view-subscription.php └── single-product │ └── add-to-cart │ ├── subscription.php │ └── variable-subscription.php ├── wcs-functions.php ├── woocommerce-subscriptions-core.php └── wpml-config.xml /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.17.1 2 | -------------------------------------------------------------------------------- /assets/css/admin-empty-state.css: -------------------------------------------------------------------------------- 1 | .woo_subscriptions_empty_state__container { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | padding: 48px 0; 7 | position: static; 8 | height: 344px; 9 | left: calc(50% - 1240px / 2); 10 | top: 271px; 11 | flex: none; 12 | order: 1; 13 | flex-grow: 0; 14 | margin: 0; 15 | text-align: center; 16 | } 17 | .woo_subscriptions_empty_state__container .woo_subscriptions_empty_state__description { 18 | max-width: 535px; 19 | margin: 15px 0; 20 | } 21 | .woo_subscriptions_empty_state__button_container { 22 | margin: 8px 0; 23 | } 24 | .woo_subscriptions_empty_state__container .woo_subscriptions_empty_state__button_container * + * { 25 | margin-left: 10px; 26 | } 27 | -------------------------------------------------------------------------------- /assets/css/admin-order-statuses.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Pre WC 3.3 support for order status admin styles. 3 | */ 4 | .order-status { 5 | display: -webkit-inline-box; 6 | display: -webkit-inline-flex; 7 | display: -ms-inline-flexbox; 8 | display: inline-flex; 9 | line-height: 2.5em; 10 | color: #777; 11 | background: #e5e5e5; 12 | border-radius: 4px; 13 | border-bottom: 1px solid rgba( 0, 0, 0, 0.05 ); 14 | margin: -0.25em 0; 15 | cursor: inherit !important; 16 | white-space: nowrap; 17 | max-width: 100%; 18 | } 19 | 20 | .order-status.status-completed { 21 | background: #c8d7e1; 22 | color: #2e4453; 23 | } 24 | 25 | .order-status.status-on-hold { 26 | background: #f8dda7; 27 | color: #94660c; 28 | } 29 | 30 | .order-status.status-failed { 31 | background: #eba3a3; 32 | color: #761919; 33 | } 34 | 35 | .order-status.status-processing { 36 | background: #c6e1c6; 37 | color: #5b841b; 38 | } 39 | 40 | .order-status.status-trash { 41 | background: #eba3a3; 42 | color: #761919; 43 | } 44 | 45 | .order-status > span { 46 | margin: 0 1em; 47 | overflow: hidden; 48 | text-overflow: ellipsis; 49 | } 50 | -------------------------------------------------------------------------------- /assets/css/checkout.css: -------------------------------------------------------------------------------- 1 | /* Cart/Checkout Pages */ 2 | .shipping.recurring-total ul { 3 | list-style: none outside; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | .shipping.recurring-total ul li { 8 | margin: 0; 9 | padding: 0.25em 0 0.25em 22px; 10 | text-indent: -22px; 11 | list-style: none outside; 12 | } 13 | .shipping.recurring-total ul li input { 14 | margin: 3px 0.5ex; 15 | } 16 | .shipping.recurring-total ul li label { 17 | display: inline; 18 | } 19 | .shipping.recurring-total ul .amount { 20 | font-weight: 700; 21 | } 22 | .woocommerce-page table.shop_table_responsive tbody .recurring-totals th { 23 | display: table-cell; 24 | } 25 | .woocommerce-page 26 | table.shop_table_responsive 27 | tr.recurring-total 28 | td:not( [data-title] )::before { 29 | content: ''; 30 | } 31 | -------------------------------------------------------------------------------- /assets/css/view-subscription.css: -------------------------------------------------------------------------------- 1 | @media only screen and ( max-width: 768px ) { 2 | .subscription_details .button { 3 | box-sizing: border-box; 4 | margin-bottom: 2px; 5 | padding-left: 0.5rem; 6 | padding-right: 0.5rem; 7 | width: 100%; 8 | max-width: 200px; 9 | text-align: center; 10 | } 11 | } 12 | 13 | .subscription_details .button { 14 | display: inline-block; 15 | margin-bottom: 0.5em; 16 | } 17 | 18 | .subscription-auto-renew-toggle { 19 | margin-left: 5px; 20 | margin-bottom: 2px; 21 | position: relative; 22 | top: 4px; 23 | } 24 | 25 | .subscription-auto-renew-toggle__i { 26 | height: 20px; 27 | width: 32px; 28 | border: 2px solid #00ba8a; 29 | background-color: #00ba8a; 30 | display: inline-block; 31 | text-indent: -9999px; 32 | border-radius: 10em; 33 | position: relative; 34 | margin-top: -1px; 35 | vertical-align: text-top; 36 | } 37 | 38 | .subscription-auto-renew-toggle__i::before { 39 | content: ''; 40 | display: block; 41 | width: 16px; 42 | height: 16px; 43 | background: #fff; 44 | position: absolute; 45 | top: 0; 46 | right: 0; 47 | border-radius: 100%; 48 | } 49 | 50 | .subscription-auto-renew-toggle--off .subscription-auto-renew-toggle__i { 51 | border-color: #999; 52 | background-color: #999; 53 | } 54 | 55 | .subscription-auto-renew-toggle--off 56 | .subscription-auto-renew-toggle__i::before { 57 | right: auto; 58 | left: 0; 59 | } 60 | 61 | .subscription-auto-renew-toggle--loading .subscription-auto-renew-toggle__i { 62 | opacity: 0.5; 63 | } 64 | 65 | .subscription-auto-renew-toggle--hidden { 66 | display: none; 67 | } 68 | .subscription-auto-renew-toggle-disabled-note { 69 | margin-left: 1em; 70 | } 71 | 72 | /** 73 | * Early renewal Modal 74 | **/ 75 | .wcs_early_renew_modal_totals_table { 76 | overflow: scroll; 77 | height: 80%; 78 | margin-bottom: 1em; 79 | } 80 | 81 | .wcs_early_renew_modal_note { 82 | position: sticky; 83 | bottom: 0; 84 | min-width: 100%; 85 | width: 0; 86 | } 87 | 88 | #early_renewal_modal_submit { 89 | width: 100%; 90 | font-size: 1.4em; 91 | text-align: center; 92 | } 93 | -------------------------------------------------------------------------------- /assets/css/wcs-upgrade.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-top: 100px; 3 | padding-bottom: 2em; 4 | } 5 | .help_tip .tooltip { 6 | display: none; 7 | } 8 | .help_tip:hover .tooltip { 9 | display: block; 10 | } 11 | .tooltip { 12 | position: absolute; 13 | width: 480px; 14 | height: 270px; 15 | line-height: 1.5em; 16 | padding: 10px; 17 | font-size: 14px; 18 | text-align: left; 19 | color: rgb( 18, 18, 18 ); 20 | background: rgb( 249, 249, 249 ); 21 | border: 4px solid rgb( 249, 249, 249 ); 22 | border-radius: 5px; 23 | text-shadow: none; 24 | box-shadow: rgba( 0, 0, 0, 0.2 ) 0 0 4px 1px; 25 | margin-top: -332px; 26 | margin-left: 100px; 27 | } 28 | .tooltip::after { 29 | content: ''; 30 | position: absolute; 31 | width: 0; 32 | height: 0; 33 | border-width: 14px; 34 | border-style: solid; 35 | border-color: #f9f9f9 transparent transparent transparent; 36 | top: 292px; 37 | left: 366px; 38 | } 39 | #update-messages, 40 | #update-complete, 41 | #update-error { 42 | display: none; 43 | } 44 | .log-notice { 45 | color: #a0a0a0; 46 | } 47 | p.log-notice { 48 | font-size: 0.8em; 49 | color: #a0a0a0; 50 | } 51 | -------------------------------------------------------------------------------- /assets/images/add-edit-subscription-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/add-edit-subscription-screen.png -------------------------------------------------------------------------------- /assets/images/admin-change-payment-method.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/admin-change-payment-method.jpg -------------------------------------------------------------------------------- /assets/images/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/ajax-loader.gif -------------------------------------------------------------------------------- /assets/images/ajax-loader@2x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/ajax-loader@2x.gif -------------------------------------------------------------------------------- /assets/images/billing-schedules-meta-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/billing-schedules-meta-box.png -------------------------------------------------------------------------------- /assets/images/checkout-recurring-totals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/checkout-recurring-totals.png -------------------------------------------------------------------------------- /assets/images/drip-downloadable-content.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/drip-downloadable-content.jpg -------------------------------------------------------------------------------- /assets/images/gift-subscription.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/gift-subscription.png -------------------------------------------------------------------------------- /assets/images/renewal-retry-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/renewal-retry-settings.png -------------------------------------------------------------------------------- /assets/images/subscribe-all-the-things.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/subscribe-all-the-things.png -------------------------------------------------------------------------------- /assets/images/subscription-reports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/subscription-reports.png -------------------------------------------------------------------------------- /assets/images/subscription-suspended-email.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/subscription-suspended-email.jpg -------------------------------------------------------------------------------- /assets/images/subscriptions-importer-exporter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/subscriptions-importer-exporter.png -------------------------------------------------------------------------------- /assets/images/view-subscription.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/view-subscription.png -------------------------------------------------------------------------------- /assets/images/woocommerce_subscriptions_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/assets/images/woocommerce_subscriptions_logo.png -------------------------------------------------------------------------------- /assets/js/admin/admin-pointers.js: -------------------------------------------------------------------------------- 1 | jQuery( function ( $ ) { 2 | let observer = null; 3 | 4 | if ( arePointersEnabled() ) { 5 | observer = new MutationObserver( showSubscriptionPointers ); 6 | 7 | observer.observe( document.getElementById( 'poststuff' ), { 8 | attributes: true, 9 | childList: true, 10 | characterData: false, 11 | subtree:true, 12 | } ); 13 | } 14 | 15 | $( 'select#product-type' ).on( 'change', function () { 16 | if ( arePointersEnabled() ) { 17 | $( '#product-type' ).pointer( 'close' ); 18 | } 19 | } ); 20 | 21 | $( 22 | '#_subscription_price, #_subscription_period, #_subscription_length' 23 | ).on( 'change', function () { 24 | if ( arePointersEnabled() ) { 25 | $( '.options_group.subscription_pricing' ).pointer( 'close' ); 26 | $( '#product-type' ).pointer( 'close' ); 27 | } 28 | } ); 29 | 30 | function arePointersEnabled() { 31 | if ( $.getParameterByName( 'subscription_pointers' ) == 'true' ) { 32 | return true; 33 | } else { 34 | return false; 35 | } 36 | } 37 | 38 | function showSubscriptionPointers() { 39 | $( '#product-type' ) 40 | .pointer( { 41 | content: WCSPointers.typePointerContent, 42 | position: { 43 | edge: 'left', 44 | align: 'center', 45 | }, 46 | close: function () { 47 | if ( 48 | $( 'select#product-type' ).val() == 49 | WCSubscriptions.productType 50 | ) { 51 | $( 52 | '.options_group.subscription_pricing:not(".subscription_sync")' 53 | ) 54 | .pointer( { 55 | content: WCSPointers.pricePointerContent, 56 | position: 'bottom', 57 | close: function () { 58 | dismissSubscriptionPointer(); 59 | }, 60 | } ) 61 | .pointer( 'open' ); 62 | } 63 | dismissSubscriptionPointer(); 64 | }, 65 | } ) 66 | .pointer( 'open' ); 67 | } 68 | 69 | function dismissSubscriptionPointer() { 70 | $.post( ajaxurl, { 71 | pointer: 'wcs_pointer', 72 | action: 'dismiss-wp-pointer', 73 | } ); 74 | 75 | if ( observer ) { 76 | observer.disconnect(); 77 | } 78 | } 79 | } ); 80 | -------------------------------------------------------------------------------- /assets/js/admin/meta-boxes-coupon.js: -------------------------------------------------------------------------------- 1 | jQuery( function ( $ ) { 2 | 'use strict'; 3 | 4 | var renewals_field = document.querySelector( '.wcs_number_payments_field' ), 5 | $renewals_field = $( renewals_field ); 6 | 7 | /** 8 | * Subscription coupon actions. 9 | * @type {{init: function, type_options: function, move_field: function}} 10 | */ 11 | var wcs_meta_boxes_coupon_actions = { 12 | /** 13 | * Initialize variation actions. 14 | */ 15 | init: function () { 16 | if ( renewals_field ) { 17 | $( document.getElementById( 'discount_type' ) ) 18 | .on( 'change', this.type_options ) 19 | .trigger( 'change' ); 20 | this.move_field(); 21 | } 22 | }, 23 | 24 | /** 25 | * Show/hide fields by coupon type options. 26 | */ 27 | type_options: function () { 28 | var select_val = $( this ).val(); 29 | 30 | switch ( select_val ) { 31 | case 'recurring_fee': 32 | case 'recurring_percent': 33 | $renewals_field.show(); 34 | break; 35 | 36 | default: 37 | $renewals_field.hide(); 38 | break; 39 | } 40 | }, 41 | 42 | /** 43 | * Move the renewal form field in the DOM to a better location. 44 | */ 45 | move_field: function () { 46 | var parent = document.getElementById( 'general_coupon_data' ), 47 | shipping = parent.querySelector( '.free_shipping_field' ); 48 | 49 | parent.insertBefore( renewals_field, shipping ); 50 | }, 51 | }; 52 | 53 | wcs_meta_boxes_coupon_actions.init(); 54 | } ); 55 | -------------------------------------------------------------------------------- /assets/js/admin/wcs-meta-boxes-order.js: -------------------------------------------------------------------------------- 1 | jQuery( function ( $ ) { 2 | $( 'body.post-type-shop_order #post' ).on( 'submit', function () { 3 | if ( 4 | 'wcs_retry_renewal_payment' == 5 | $( 6 | "body.post-type-shop_order select[name='wc_order_action']" 7 | ).val() 8 | ) { 9 | return confirm( 10 | wcs_admin_order_meta_boxes.retry_renewal_payment_action_warning 11 | ); 12 | } 13 | } ); 14 | 15 | $( document ).on( 'change', '#wcs-order-price-lock', function () { 16 | // Block the checkbox element while we update the order. 17 | $( '#wcs_order_price_lock' ).block( { 18 | message: null, 19 | overlayCSS: { 20 | background: '#fff', 21 | opacity: 0.6, 22 | }, 23 | } ); 24 | 25 | var data = { 26 | wcs_order_price_lock: $( '#wcs-order-price-lock' ).is( ':checked' ) 27 | ? 'yes' 28 | : 'no', 29 | order_id: $( '#post_ID' ).val(), 30 | action: 'wcs_order_price_lock', 31 | woocommerce_meta_nonce: $( '#woocommerce_meta_nonce' ).val(), 32 | }; 33 | 34 | $.ajax( { 35 | type: 'post', 36 | url: woocommerce_admin_meta_boxes.ajax_url, 37 | data: data, 38 | complete: function () { 39 | $( '#wcs_order_price_lock' ).unblock(); 40 | }, 41 | } ); 42 | } ); 43 | } ); 44 | -------------------------------------------------------------------------------- /assets/js/frontend/payment-methods.js: -------------------------------------------------------------------------------- 1 | jQuery( function ( $ ) { 2 | /** 3 | * Displays an appropriate error message when the delete token button is clicked for a token used by subscriptions. 4 | */ 5 | $( '.wcs_deletion_error' ).on( 'click', function ( e ) { 6 | e.preventDefault(); 7 | 8 | var notice_content_container = $( '#wcs_delete_token_warning' ).find( 'li' ); 9 | 10 | // For block based WC notices we need to find the notice content container. 11 | if ( $( '#wcs_delete_token_warning' ).find( '.wc-block-components-notice-banner' ).length > 0 ) { 12 | notice_content_container = $( '#wcs_delete_token_warning' ).find( '.wc-block-components-notice-banner__content' ); 13 | } 14 | 15 | // Use the href to determine which notice needs to be displayed. 16 | if ( '#choose_default' === $( this ).attr( 'href' ) ) { 17 | notice_content_container.html( wcs_payment_methods.choose_default_error ); 18 | } else { 19 | notice_content_container.html( wcs_payment_methods.add_method_error ); 20 | } 21 | 22 | // Display the notice. 23 | $( '#wcs_delete_token_warning' ).slideDown(); 24 | } ); 25 | } ); 26 | -------------------------------------------------------------------------------- /assets/js/frontend/single-product.js: -------------------------------------------------------------------------------- 1 | ( function ( document, $ ) { 2 | var $cache = {}; 3 | 4 | /** 5 | * Cache our DOM selectors. 6 | */ 7 | function generate_cache() { 8 | $cache.document = $( document ); 9 | $cache.first_payment_date = $( '.first-payment-date' ); 10 | $cache.is_variable_subscription = 11 | 0 < $( 'div.product-type-variable-subscription' ).length; 12 | } 13 | 14 | /** 15 | * Attach DOM events. 16 | */ 17 | function attach_events() { 18 | if ( $cache.is_variable_subscription ) { 19 | $cache.document.on( 20 | 'found_variation', 21 | update_first_payment_element 22 | ); 23 | $cache.document.on( 'reset_data', clear_first_payment_element ); 24 | } 25 | } 26 | 27 | /** 28 | * Update the variation's first payment element. 29 | * 30 | * @param {jQuery.Event} event 31 | * @param {object} variation_data 32 | */ 33 | function update_first_payment_element( event, variation_data ) { 34 | $cache.first_payment_date.html( variation_data.first_payment_html ); 35 | } 36 | 37 | /** 38 | * Clear the variation's first payment element. 39 | */ 40 | function clear_first_payment_element() { 41 | $cache.first_payment_date.html( '' ); 42 | } 43 | 44 | /** 45 | * Initialise. 46 | */ 47 | function init() { 48 | generate_cache(); 49 | attach_events(); 50 | } 51 | 52 | $( init ); 53 | } )( document, jQuery ); 54 | -------------------------------------------------------------------------------- /assets/js/frontend/wcs-cart.js: -------------------------------------------------------------------------------- 1 | function hide_non_applicable_coupons() { 2 | var coupon_elements = document.getElementsByClassName( 'cart-discount' ); 3 | 4 | for ( var i = 0; i < coupon_elements.length; i++ ) { 5 | if ( 6 | 0 !== 7 | coupon_elements[ i ].getElementsByClassName( 'wcs-hidden-coupon' ) 8 | .length 9 | ) { 10 | coupon_elements[ i ].style.display = 'none'; 11 | } 12 | } 13 | } 14 | 15 | hide_non_applicable_coupons(); 16 | 17 | jQuery( function ( $ ) { 18 | $( document.body ).on( 'updated_cart_totals updated_checkout', function () { 19 | hide_non_applicable_coupons(); 20 | } ); 21 | 22 | /** 23 | * Update all subscriptions shipping methods which inherit the chosen method from the initial 24 | * cart when the customer changes the shipping method. 25 | */ 26 | $( document ).on( 27 | 'change', 28 | 'select.shipping_method, :input[name^=shipping_method]', 29 | function( event ) { 30 | var shipping_method_option = $( event.target ); 31 | var shipping_method_id = shipping_method_option.val(); 32 | var package_index = shipping_method_option.data( 'index' ); 33 | 34 | // We're only interested in the initial cart shipping method options which have int package indexes. 35 | if ( ! Number.isInteger( package_index ) ) { 36 | return; 37 | } 38 | 39 | // Find all recurring cart info elements with the same package index as the changed shipping method. 40 | $( '.recurring-cart-shipping-mapping-info[data-index=' + package_index + ']' ).each( function() { 41 | // Update the corresponding subscription's hidden chosen shipping method. 42 | $( 'input[name="shipping_method[' + $( this ).data( 'recurring_index' ) + ']"]' ).val( shipping_method_id ); 43 | } ); 44 | } 45 | ); 46 | 47 | $( '.payment_methods [name="payment_method"]' ).on( 'click', function () { 48 | if ( $( this ).hasClass( 'supports-payment-method-changes' ) ) { 49 | $( '.update-all-subscriptions-payment-method-wrap' ).show(); 50 | } else { 51 | $( '.update-all-subscriptions-payment-method-wrap' ).hide(); 52 | } 53 | } ); 54 | } ); 55 | -------------------------------------------------------------------------------- /build/index.asset.php: -------------------------------------------------------------------------------- 1 | array('wc-blocks-checkout', 'wc-price-format', 'wc-settings', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '7e9abfc482fe190e29673f828b33f482'); -------------------------------------------------------------------------------- /build/index.css: -------------------------------------------------------------------------------- 1 | .wcs-recurring-totals-panel{position:relative;padding:1em 0 0}.wcs-recurring-totals-panel::after{border-style:solid;border-width:1px 0;bottom:0;content:"";display:block;left:0;opacity:.3;pointer-events:none;position:absolute;right:0;top:0}.wcs-recurring-totals-panel+.wcs-recurring-totals-panel::after{border-top-width:0}.wcs-recurring-totals-panel .wc-block-components-panel .wc-block-components-totals-item{padding-left:0;padding-right:0}.wcs-recurring-totals-panel .wc-block-components-totals-item__label::first-letter{text-transform:capitalize}.wcs-recurring-totals-panel .wcs-recurring-totals-panel__title .wc-block-components-totals-item__label{font-weight:700}.wcs-recurring-totals-panel__title{margin:0}.wcs-recurring-totals-panel__details .wc-block-components-panel__button,.wcs-recurring-totals-panel__details .wc-block-components-panel__button:hover,.wcs-recurring-totals-panel__details .wc-block-components-panel__button:focus{font-size:.875em}.wcs-recurring-totals-panel__details .wc-block-components-panel__content>.wc-block-components-totals-item:first-child{margin-top:0}.wcs-recurring-totals-panel__details .wc-block-components-panel__content>.wc-block-components-totals-item:last-child{margin-bottom:0}.wcs-recurring-totals-panel__details .wcs-recurring-totals-panel__details-total .wc-block-components-totals-item__label{font-weight:700}.wcs-recurring-totals__subscription-length{float:right} 2 | 3 | -------------------------------------------------------------------------------- /includes/abstracts/abstract-wcs-background-upgrader.php: -------------------------------------------------------------------------------- 1 | scheduled_hook action to start repairing subscriptions in 34 | * @see $this->time_limit seconds (60 seconds by default). 35 | * 36 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0 37 | */ 38 | public function schedule_repair() { 39 | $this->schedule_background_update(); 40 | } 41 | 42 | /** 43 | * Add a message to the wcs-upgrade-subscriptions-paypal-suspended log 44 | * 45 | * @param string $message The message to be logged 46 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0 47 | */ 48 | protected function log( $message ) { 49 | $this->logger->add( $this->log_handle, $message ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /includes/abstracts/abstract-wcs-cache-manager.php: -------------------------------------------------------------------------------- 1 | init(); 49 | } 50 | 51 | return self::$instance; 52 | } 53 | 54 | /** 55 | * Stub for initialising the class outside the constructor, for things like attaching callbacks to hooks. 56 | */ 57 | protected function init() {} 58 | } 59 | -------------------------------------------------------------------------------- /includes/abstracts/abstract-wcs-debug-tool-cache-updater.php: -------------------------------------------------------------------------------- 1 | System Status > Tools page that need to 6 | * update a cached data store's cache. 7 | * 8 | * @author Prospress 9 | * @category Admin 10 | * @package WooCommerce Subscriptions/Admin 11 | * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 12 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 13 | */ 14 | 15 | if ( ! defined( 'ABSPATH' ) ) { 16 | exit; 17 | } // Exit if accessed directly 18 | 19 | /** 20 | * WCS_Debug_Tool_Cache_Updater Class 21 | * 22 | * Shared methods for tool on the WooCommerce > System Status > Tools page that need to 23 | * update a cached data store's cache. 24 | */ 25 | abstract class WCS_Debug_Tool_Cache_Updater extends WCS_Debug_Tool { 26 | 27 | /** 28 | * @var mixed $data_Store The store used for updating the cache. 29 | */ 30 | protected $data_store; 31 | 32 | /** 33 | * Attach callbacks and hooks, if the class's data store is using caching. 34 | */ 35 | public function init() { 36 | if ( $this->is_data_store_cached() ) { 37 | parent::init(); 38 | } 39 | } 40 | 41 | /** 42 | * Check if the store is a cache updater, and has methods required to erase or generate cache. 43 | */ 44 | protected function is_data_store_cached() { 45 | return is_a( $this->data_store, 'WCS_Cache_Updater' ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /includes/abstracts/abstract-wcs-debug-tool.php: -------------------------------------------------------------------------------- 1 | System Status > Tools administration screen. 7 | * 8 | * @author Prospress 9 | * @category Admin 10 | * @package WooCommerce Subscriptions/Admin 11 | * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 12 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 13 | */ 14 | 15 | if ( ! defined( 'ABSPATH' ) ) { 16 | exit; 17 | } // Exit if accessed directly 18 | 19 | /** 20 | * WCS_Debug_Tool Class 21 | * 22 | * Add a debug tool to the WooCommerce > System Status > Tools page. 23 | */ 24 | abstract class WCS_Debug_Tool { 25 | 26 | /** 27 | * @var string $tool_key The key used to add the tool to the array of available tools. 28 | */ 29 | protected $tool_key; 30 | 31 | /** 32 | * @var array $tool_data Data for this tool, containing: 33 | * - 'name': The section name given to the tool 34 | * - 'button': The text displayed on the tool's button 35 | * - 'desc': The long description for the tool. 36 | * - 'callback': The callback used to perform the tool's action. 37 | */ 38 | protected $tool_data; 39 | 40 | /** 41 | * Attach callbacks to hooks and validate required properties are assigned values. 42 | */ 43 | public function init() { 44 | 45 | if ( empty( $this->tool_key ) ) { 46 | throw new RuntimeException( __CLASS__ . ' must assign a tool key to $this->tool_key' ); 47 | } 48 | 49 | if ( empty( $this->tool_data ) ) { 50 | throw new RuntimeException( __CLASS__ . ' must assign an array of data about the tool to $this->tool_data' ); 51 | } 52 | 53 | add_filter( 'woocommerce_debug_tools', array( $this, 'add_debug_tools' ) ); 54 | } 55 | 56 | /** 57 | * Add subscription related tools to display on the WooCommerce > System Status > Tools administration screen 58 | * 59 | * @param array $tools Arrays defining the tools displayed on the System Status screen 60 | * @return array 61 | */ 62 | public function add_debug_tools( $tools ) { 63 | $tools[ $this->tool_key ] = $this->tool_data; 64 | return $tools; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /includes/abstracts/abstract-wcs-dynamic-hook-deprecator.php: -------------------------------------------------------------------------------- 1 | 'old_hook_prefix' */ 15 | protected $deprecated_hook_prefixes = array(); 16 | 17 | /** 18 | * Bootstraps the class and hooks required actions & filters. 19 | * 20 | * We need to use the special 'all' hook here because we don't actually know the full hook names 21 | * in advance, just their prefix. We can't simply hook in to 'plugins_loaded' and check the 22 | * $wp_filter global for our hooks either, because sometime, hooks are dynamically hooked based 23 | * on other hooks. Sigh. 24 | * 25 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0 26 | */ 27 | public function __construct() { 28 | add_filter( 'all', array( &$this, 'check_for_deprecated_hooks' ) ); 29 | } 30 | 31 | /** 32 | * Check if the current hook contains the prefix of any dynamic hook that has been deprecated. 33 | * 34 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0 35 | */ 36 | public function check_for_deprecated_hooks() { 37 | 38 | $current_filter = current_filter(); 39 | 40 | foreach ( $this->deprecated_hook_prefixes as $new_hook_prefix => $old_hook_prefixes ) { 41 | 42 | if ( is_array( $old_hook_prefixes ) ) { 43 | foreach ( $old_hook_prefixes as $old_hook_prefix ) { 44 | $this->check_for_deprecated_hook( $current_filter, $new_hook_prefix, $old_hook_prefix ); 45 | } 46 | } else { 47 | $this->check_for_deprecated_hook( $current_filter, $new_hook_prefix, $old_hook_prefixes ); 48 | } 49 | } 50 | } 51 | 52 | /** 53 | * Check if a given hook contains the prefix and if it does, attach the @see $this->maybe_handle_deprecated_hook() method 54 | * as a callback to it. 55 | * 56 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0 57 | */ 58 | protected function check_for_deprecated_hook( $current_hook, $new_hook_prefix, $old_hook_prefix ) { 59 | 60 | if ( false !== strpos( $current_hook, $new_hook_prefix ) ) { 61 | 62 | // Get the dynamic suffix on the hook, usually a payment gateway name, like 'stripe' or 'authorize_net_cim' 63 | $hook_suffix = str_replace( $new_hook_prefix, '', $current_hook ); 64 | $old_hook = $old_hook_prefix . $hook_suffix; 65 | 66 | // register the entire new and old hook 67 | $this->deprecated_hooks[ $current_hook ][] = $old_hook; 68 | 69 | // and attach our handler now that we know the hooks 70 | add_filter( $current_hook, array( &$this, 'maybe_handle_deprecated_hook' ), -1000, 8 ); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /includes/abstracts/abstract-wcs-scheduler.php: -------------------------------------------------------------------------------- 1 | date_types_to_schedule = apply_filters( 'woocommerce_subscriptions_date_types_to_schedule', array_keys( $date_types_to_schedule ) ); 34 | } 35 | 36 | protected function get_date_types_to_schedule() { 37 | return $this->date_types_to_schedule; 38 | } 39 | 40 | /** 41 | * When a subscription's date is updated, maybe schedule an event 42 | * 43 | * @param object $subscription An instance of a WC_Subscription object 44 | * @param string $date_type Can be 'trial_end', 'next_payment', 'end', 'end_of_prepaid_term' or a custom date type 45 | * @param string $datetime A MySQL formatted date/time string in the GMT/UTC timezone. 46 | */ 47 | abstract public function update_date( $subscription, $date_type, $datetime ); 48 | 49 | /** 50 | * When a subscription's date is deleted, clear it from the scheduler 51 | * 52 | * @param object $subscription An instance of a WC_Subscription object 53 | * @param string $date_type Can be 'trial_end', 'next_payment', 'end', 'end_of_prepaid_term' or a custom date type 54 | */ 55 | abstract public function delete_date( $subscription, $date_type ); 56 | 57 | /** 58 | * When a subscription's status is updated, maybe schedule an event 59 | * 60 | * @param object $subscription An instance of a WC_Subscription object 61 | * @param string $new_status A valid subscription status 62 | * @param string $old_status A valid subscription status 63 | */ 64 | abstract public function update_status( $subscription, $new_status, $old_status ); 65 | } 66 | -------------------------------------------------------------------------------- /includes/admin/debug-tools/class-wcs-debug-tool-cache-background-updater.php: -------------------------------------------------------------------------------- 1 | System Status > Tools administration screen. 7 | * 8 | * @author Prospress 9 | * @category Admin 10 | * @package WooCommerce Subscriptions/Admin 11 | * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 12 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 13 | */ 14 | 15 | if ( ! defined( 'ABSPATH' ) ) { 16 | exit; 17 | } // Exit if accessed directly 18 | 19 | /** 20 | * WCS_Debug_Tool_Cache_Background_Updater Class 21 | * 22 | * Provide APIs for a debug tool to update a cached data store's data in the background using Action Scheduler. 23 | */ 24 | class WCS_Debug_Tool_Cache_Background_Updater extends WCS_Background_Updater { 25 | 26 | /** 27 | * @var WCS_Cache_Updater The data store used to manage the cache. 28 | */ 29 | protected $data_store; 30 | 31 | /** 32 | * WCS_Debug_Tool_Cache_Background_Updater constructor. 33 | * 34 | * @param string $scheduled_hook The hook to schedule to run the update. 35 | * @param WCS_Cache_Updater $data_store 36 | */ 37 | public function __construct( $scheduled_hook, WCS_Cache_Updater $data_store ) { 38 | $this->scheduled_hook = $scheduled_hook; 39 | $this->data_store = $data_store; 40 | } 41 | 42 | /** 43 | * Get the items to be updated, if any. 44 | * 45 | * @return array An array of items to update, or empty array if there are no items to update. 46 | */ 47 | protected function get_items_to_update() { 48 | return $this->data_store->get_items_to_update(); 49 | } 50 | 51 | /** 52 | * Run the update for a single item. 53 | * 54 | * @param mixed $item The item to update. 55 | */ 56 | protected function update_item( $item ) { 57 | return $this->data_store->update_items_cache( $item ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /includes/admin/debug-tools/class-wcs-debug-tool-cache-eraser.php: -------------------------------------------------------------------------------- 1 | System Status > Tools page for 6 | * deleting a data store's cache/s. 7 | * 8 | * @author Prospress 9 | * @category Admin 10 | * @package WooCommerce Subscriptions/Admin 11 | * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 12 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 13 | */ 14 | 15 | if ( ! defined( 'ABSPATH' ) ) { 16 | exit; 17 | } // Exit if accessed directly 18 | 19 | /** 20 | * WCS_Debug_Tool_Cache_Eraser Class 21 | * 22 | * Add a debug tool to the WooCommerce > System Status > Tools page for 23 | * deleting a data store's cache/s. 24 | */ 25 | class WCS_Debug_Tool_Cache_Eraser extends WCS_Debug_Tool_Cache_Updater { 26 | 27 | /** 28 | * WCS_Debug_Tool_Cache_Eraser constructor. 29 | * 30 | * @param string $tool_key The key used to add the tool to the array of available tools. 31 | * @param string $tool_name The section name given to the tool on the admin screen. 32 | * @param string $tool_description The long description for the tool displayed on the admin screen. 33 | * @param WCS_Cache_Updater $data_store The cached data store this tool will use for erasing cache. 34 | */ 35 | public function __construct( $tool_key, $tool_name, $tool_description, WCS_Cache_Updater $data_store ) { 36 | $this->tool_key = $tool_key; 37 | $this->data_store = $data_store; 38 | $this->tool_data = array( 39 | 'name' => $tool_name, 40 | 'button' => $tool_name, 41 | 'desc' => $tool_description, 42 | 'callback' => array( $this, 'delete_caches' ), 43 | ); 44 | } 45 | 46 | /** 47 | * Clear all of the data store's caches. 48 | */ 49 | public function delete_caches() { 50 | if ( $this->is_data_store_cached() ) { 51 | $this->data_store->delete_all_caches(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /includes/admin/debug-tools/class-wcs-debug-tool-cache-generator.php: -------------------------------------------------------------------------------- 1 | System Status > Tools page for generating a cache. 6 | * 7 | * @author Prospress 8 | * @category Admin 9 | * @package WooCommerce Subscriptions/Admin 10 | * @version 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 11 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3 12 | */ 13 | 14 | if ( ! defined( 'ABSPATH' ) ) { 15 | exit; 16 | } // Exit if accessed directly 17 | 18 | /** 19 | * WCS_Debug_Tool_Cache_Generator Class 20 | * 21 | * Add a debug tool to the WooCommerce > System Status > Tools page for generating a cache. 22 | */ 23 | class WCS_Debug_Tool_Cache_Generator extends WCS_Debug_Tool_Cache_Updater { 24 | 25 | /** 26 | * @var WCS_Background_Updater $update The instance used to generate the cache data in the background. 27 | */ 28 | protected $cache_updater; 29 | 30 | /** 31 | * WCS_Debug_Tool_Cache_Generator constructor. 32 | * 33 | * @param string $tool_key The key used to add the tool to the array of available tools. 34 | * @param string $tool_name The section name given to the tool on the admin screen. 35 | * @param string $tool_description The long description for the tool displayed on the admin screen. 36 | * @param WCS_Cache_Updater $data_store 37 | * @param WCS_Background_Updater $cache_updater 38 | */ 39 | public function __construct( $tool_key, $tool_name, $tool_description, WCS_Cache_Updater $data_store, WCS_Background_Updater $cache_updater ) { 40 | $this->tool_key = $tool_key; 41 | $this->data_store = $data_store; 42 | $this->cache_updater = $cache_updater; 43 | $this->tool_data = array( 44 | 'name' => $tool_name, 45 | 'button' => $tool_name, 46 | 'desc' => $tool_description, 47 | 'callback' => array( $this, 'generate_caches' ), 48 | ); 49 | } 50 | 51 | /** 52 | * Attach callbacks and hooks, if the store supports getting uncached items, which is required to generate cache 53 | * and also acts as a proxy to determine if the related order store is using caching 54 | */ 55 | public function init() { 56 | if ( $this->is_data_store_cached() ) { 57 | parent::init(); 58 | $this->cache_updater->init(); 59 | } 60 | } 61 | 62 | /** 63 | * Generate the data store's cache by calling the @see $this->>cache_updater's update method. 64 | */ 65 | public function generate_caches() { 66 | $this->cache_updater->run_update(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /includes/admin/meta-boxes/views/html-related-orders-row.php: -------------------------------------------------------------------------------- 1 | get_edit_order_url() ) . '" aria-label="' . esc_attr( sprintf( __( 'Edit order number %s', 'woocommerce-subscriptions' ), $order->get_order_number() ) ) . '">' . 15 | // translators: placeholder is an order number. 16 | sprintf( esc_html_x( '#%s', 'hash before order number', 'woocommerce-subscriptions' ), esc_html( $order->get_order_number() ) ) . 17 | ''; 18 | 19 | // Relationship column 20 | $relationship = esc_html( $order->get_meta( '_relationship' ) ); 21 | 22 | // Date created column 23 | $date_created = $order->get_date_created(); 24 | 25 | if ( $date_created ) { 26 | $t_time = $order->get_date_created()->date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ); 27 | $date_to_display = ucfirst( wcs_get_human_time_diff( $date_created->getTimestamp() ) ); 28 | } else { 29 | $t_time = __( 'Unpublished', 'woocommerce-subscriptions' ); 30 | $date_to_display = $t_time; 31 | } 32 | 33 | if ( ! wcs_is_custom_order_tables_usage_enabled() ) { 34 | // Backwards compatibility for third-parties using the generic WP post time filter. 35 | // Only apply this filter if HPOS is not enabled, as the filter is not compatible with HPOS. 36 | $date_to_display = apply_filters( 'post_date_column_time', $date_to_display, get_post( $order->get_id() ) ); 37 | } 38 | 39 | $date_created = '' . esc_html( apply_filters( 'wc_subscriptions_related_order_date_column', $date_to_display, $order ) ) . ''; 40 | 41 | // Status column 42 | $classes = array( 43 | 'order-status', 44 | sanitize_html_class( 'status-' . $order->get_status() ), 45 | ); 46 | 47 | if ( wcs_is_subscription( $order ) ) { 48 | $status_name = wcs_get_subscription_status_name( $order->get_status() ); 49 | $classes[] = 'subscription-status'; 50 | } else { 51 | $status_name = wc_get_order_status_name( $order->get_status() ); 52 | } 53 | 54 | $status_html = '' . esc_html( $status_name ) . ''; 55 | 56 | // Total column 57 | $total = '' . wp_kses( 58 | $order->get_formatted_order_total(), 59 | array( 60 | 'small' => array(), 61 | 'span' => array( 62 | 'class' => array(), 63 | ), 64 | 'del' => array(), 65 | 'ins' => array(), 66 | ) 67 | ) . ''; 68 | 69 | $columns = array( 70 | $order_number, 71 | $relationship, 72 | $date_created, 73 | $status_html, 74 | $total, 75 | ); 76 | 77 | $columns = apply_filters( 'wcs_related_orders_table_row_columns', $columns ); 78 | 79 | ?> 80 |
15 | ', 20 | '', 21 | '' 22 | ); 23 | ?> 24 |
25 | 26 | 27 |
28 |
31 |
32 | 33 | ' . esc_html( $failed_ipn_log_handle ) . '', 38 | '', 39 | '' 40 | ); 41 | ?> 42 |
43 | -------------------------------------------------------------------------------- /includes/interfaces/interface-wcs-cache-updater.php: -------------------------------------------------------------------------------- 1 | product_id = $product_id; 40 | } 41 | 42 | /** 43 | * offsetGet 44 | * @param string $key 45 | * @return mixed 46 | */ 47 | #[\ReturnTypeWillChange] 48 | public function offsetGet( $key ) { 49 | return get_post_meta( $this->product_id, $this->maybe_prefix_meta_key( $key ) ); 50 | } 51 | 52 | /** 53 | * offsetSet 54 | * @param string $key 55 | * @param mixed $value 56 | */ 57 | #[\ReturnTypeWillChange] 58 | public function offsetSet( $key, $value ) { 59 | update_post_meta( $this->product_id, $this->maybe_prefix_meta_key( $key ), $value ); 60 | } 61 | 62 | /** 63 | * offsetExists 64 | * @param string $key 65 | * @return bool 66 | */ 67 | #[\ReturnTypeWillChange] 68 | public function offsetExists( $key ) { 69 | return metadata_exists( 'post', $this->product_id, $this->maybe_prefix_meta_key( $key ) ); 70 | } 71 | 72 | /** 73 | * Nothing to do here as we access post meta directly. 74 | */ 75 | #[\ReturnTypeWillChange] 76 | public function offsetUnset( $key ) { 77 | } 78 | 79 | /** 80 | * We only work with post meta data that has meta keys prefixed with an underscore, so 81 | * add a prefix if it is not already set. 82 | */ 83 | protected function maybe_prefix_meta_key( $key ) { 84 | if ( '_' != substr( $key, 0, 1 ) ) { 85 | $key = '_' . $key; 86 | } 87 | return $key; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /includes/legacy/class-wcs-product-legacy.php: -------------------------------------------------------------------------------- 1 | scheduled_hook = 'wcs_add_start_date_metadata'; 30 | $this->log_handle = 'wcs-add-start-date-metadata'; 31 | $this->logger = $logger; 32 | } 33 | 34 | /** 35 | * Update a subscription, saving its start date as metadata. 36 | * 37 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.4.0 38 | */ 39 | protected function update_item( $subscription_id ) { 40 | try { 41 | $subscription = wcs_get_subscription( $subscription_id ); 42 | 43 | if ( false === $subscription ) { 44 | throw new Exception( 'Failed to instantiate subscription object' ); 45 | } 46 | 47 | // Saving the subscription is enough to save the start date. 48 | $subscription->save(); 49 | 50 | $this->log( sprintf( 'Subscription ID %d start date metadata added.', $subscription_id ) ); 51 | } catch ( Exception $e ) { 52 | $this->log( sprintf( '--- Exception caught adding start date metadata to subscription %d - exception message: %s ---', $subscription_id, $e->getMessage() ) ); 53 | } 54 | } 55 | 56 | /** 57 | * Get a batch of subscriptions to repair. 58 | * 59 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.4.0 60 | * @return array A list of subscription ids which may need to be repaired. 61 | */ 62 | protected function get_items_to_update() { 63 | global $wpdb; 64 | 65 | return $wpdb->get_col( 66 | "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_subscription' 67 | AND post_status NOT IN ( 'trash', 'auto-draft' ) 68 | AND ID NOT IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_schedule_start' ) 69 | LIMIT 20" 70 | ); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /includes/upgrades/class-wcs-repair-subscription-address-indexes.php: -------------------------------------------------------------------------------- 1 | scheduled_hook = 'wcs_add_missing_subscription_address_indexes'; 33 | $this->log_handle = 'wcs-add-subscription-address-indexes'; 34 | $this->logger = $logger; 35 | } 36 | 37 | /** 38 | * Update a subscription, setting its address indexes. 39 | * 40 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0 41 | */ 42 | protected function update_item( $subscription_id ) { 43 | try { 44 | $subscription = wcs_get_subscription( $subscription_id ); 45 | 46 | if ( false === $subscription ) { 47 | throw new Exception( 'Failed to instantiate subscription object' ); 48 | } 49 | 50 | // Saving the subscription sets the address indexes if they don't exist. 51 | $subscription->save(); 52 | 53 | $this->log( sprintf( 'Subscription ID %d address index(es) added.', $subscription_id ) ); 54 | } catch ( Exception $e ) { 55 | $this->log( sprintf( '--- Exception caught repairing subscription %d - exception message: %s ---', $subscription_id, $e->getMessage() ) ); 56 | } 57 | } 58 | 59 | /** 60 | * Get a batch of subscriptions which need address indexes. 61 | * 62 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.3.0 63 | * @return array A list of subscription ids which need address indexes. 64 | */ 65 | protected function get_items_to_update() { 66 | return get_posts( array( 67 | 'post_type' => 'shop_subscription', 68 | 'posts_per_page' => 20, 69 | 'post_status' => 'any', 70 | 'fields' => 'ids', 71 | 'meta_query' => array( 72 | array( 73 | 'key' => '_billing_address_index', 74 | 'compare' => 'NOT EXISTS', 75 | ), 76 | ), 77 | ) ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /includes/upgrades/class-wcs-upgrade-1-3.php: -------------------------------------------------------------------------------- 1 | query( " UPDATE $wpdb->options 28 | SET option_name = TRIM(LEADING '_transient_timeout_' FROM option_name) 29 | WHERE option_name LIKE '_transient_timeout_wcs_blocker_%'" ); 30 | 31 | // Change transient keys from the < 1.1.5 format to new format 32 | $wpdb->query( " UPDATE $wpdb->options 33 | SET option_name = CONCAT('wcs_blocker_', TRIM(LEADING '_transient_timeout_block_scheduled_subscription_payments_' FROM option_name)) 34 | WHERE option_name LIKE '_transient_timeout_block_scheduled_subscription_payments_%'" ); 35 | 36 | // Delete old transient values 37 | $wpdb->query( " DELETE FROM $wpdb->options 38 | WHERE option_name LIKE '_transient_wcs_blocker_%' 39 | OR option_name LIKE '_transient_block_scheduled_subscription_payments_%'" ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /includes/upgrades/class-wcs-upgrade-2-1.php: -------------------------------------------------------------------------------- 1 | query( 'SET SQL_BIG_SELECTS = 1;' ); 31 | 32 | $cancelled_date_meta_key = wcs_get_date_meta_key( 'cancelled' ); 33 | 34 | // Run two separate insert queries for pending cancellation and cancelled subscriptions. This could easily be done in one query, but we'll run it in two separate queries to minimise issues with large databases. 35 | foreach ( array( 'wc-pending-cancel', 'wc-cancelled' ) as $post_status ) { 36 | 37 | $rows_inserted = $wpdb->query( $wpdb->prepare( 38 | "INSERT INTO {$wpdb->postmeta}(post_id, meta_key, meta_value) 39 | SELECT ID, %s, post_modified_gmt 40 | FROM {$wpdb->posts} as posts 41 | WHERE post_status = %s 42 | AND NOT EXISTS ( 43 | SELECT null 44 | FROM {$wpdb->postmeta} as postmeta 45 | WHERE postmeta.post_id = posts.ID 46 | AND postmeta.meta_key = %s 47 | ) 48 | ", 49 | $cancelled_date_meta_key, 50 | $post_status, 51 | $cancelled_date_meta_key 52 | ) ); 53 | 54 | WCS_Upgrade_Logger::add( sprintf( 'v2.1: Set _schedule_cancelled date to post_modified_gmt column value for %d subscriptions with %s status.', $rows_inserted, $post_status ) ); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /includes/upgrades/class-wcs-upgrade-3-1-0.php: -------------------------------------------------------------------------------- 1 | get_results( "SELECT webhook_id FROM {$wpdb->prefix}wc_webhooks WHERE `topic` LIKE 'subscription.%' AND `api_version` = 3" ); 25 | 26 | if ( ! empty( $results ) && is_array( $results ) ) { 27 | WCS_Upgrade_Logger::add( sprintf( '3.1.0 - Updating %d subscription webhooks to use API Version 1 when building the payload to preserve backwards compatibility.', count( $results ) ) ); 28 | 29 | foreach ( $results as $result ) { 30 | $webhook = ! empty( $result->webhook_id ) ? wc_get_webhook( $result->webhook_id ) : null; 31 | 32 | if ( $webhook ) { 33 | $webhook->set_api_version( 1 ); 34 | $webhook->save(); 35 | 36 | WCS_Upgrade_Logger::add( sprintf( 'Updated webhook: %s (#%d).', $webhook->get_name(), $webhook->get_id() ) ); 37 | } else { 38 | WCS_Upgrade_Logger::add( sprintf( 'Warning! Couldn\'t find and update webhook: %s', print_r( $result, true ) ) ); 39 | } 40 | } 41 | } else { 42 | WCS_Upgrade_Logger::add( '3.1.0 - No subscription webhooks found using API version 3. No updates needed.' ); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /includes/upgrades/templates/update-welcome-notice.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |4 | tags ?> 5 | ', '' ) ); ?> 6 | 7 |
8 | 9 |35 |
36 | 37 | 38 | 39 | is_type( 'variation' ) ) { 28 | $parent_product = wc_get_product( $product->get_parent_id() ); 29 | } else { 30 | $parent_product = $product; 31 | } 32 | 33 | return apply_filters( 'woocommerce_subscriptions_product_limitation', WC_Subscriptions_Product::get_meta_data( $parent_product, 'subscription_limit', 'no', 'use_default_value' ), $product ); 34 | } 35 | 36 | /** 37 | * Returns true if product is limited to one active subscription and user currently has this product on-hold. 38 | * 39 | * @param int|WC_Product $product A WC_Product object or the ID of a product 40 | * @return boolean 41 | */ 42 | function wcs_is_product_limited_for_user( $product, $user_id = 0 ) { 43 | if ( ! is_object( $product ) ) { 44 | $product = wc_get_product( $product ); 45 | } 46 | 47 | if ( empty( $user_id ) ) { 48 | $user_id = get_current_user_id(); 49 | } 50 | 51 | $is_limited_for_user = false; 52 | $product_limitation = wcs_get_product_limitation( $product ); 53 | 54 | // If the subscription is limited to 1 active and the customer has a subscription to this product on-hold. 55 | if ( 'active' == $product_limitation && wcs_user_has_subscription( $user_id, $product->get_id(), 'on-hold' ) ) { 56 | $is_limited_for_user = true; 57 | } elseif ( 'no' !== $product_limitation ) { 58 | $is_limited_for_user = wcs_user_has_subscription( $user_id, $product->get_id(), $product_limitation ); 59 | 60 | // If the product is limited for any status, there exists a chance that the customer has cancelled subscriptions which cannot be resubscribed to as they have no completed payments. 61 | if ( 'any' === $product_limitation && $is_limited_for_user ) { 62 | $is_limited_for_user = false; 63 | 64 | foreach ( wcs_get_users_subscriptions( $user_id ) as $subscription ) { 65 | // Skip if the subscription is not for the product we are checking. 66 | if ( ! $subscription->has_product( $product->get_id() ) ) { 67 | continue; 68 | } 69 | 70 | if ( ! $subscription->has_status( 'cancelled' ) || 0 !== $subscription->get_payment_count() ) { 71 | $is_limited_for_user = true; 72 | break; 73 | } 74 | } 75 | } 76 | } 77 | 78 | return apply_filters( 'woocommerce_subscriptions_product_limited_for_user', $is_limited_for_user, $product, $user_id ); 79 | } 80 | -------------------------------------------------------------------------------- /languages/woocommerce-subscriptions-fr.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/woocommerce-subscriptions-core/0795346299f189973e91811133eafea52b5c4f11/languages/woocommerce-subscriptions-fr.mo -------------------------------------------------------------------------------- /templates/admin/deprecated/html-variation-synchronisation.php: -------------------------------------------------------------------------------- 1 | 16 |15 | 18 |
get_actions() as $action ) { ?> 21 | 22 | 23 |
24 | 25 | 26 | is_dismissible() ) : ?> 27 | 28 | 29 |', 33 | '' 34 | )?> 35 |
36 | 37 | array( 'href' => array() ) ) ); ?>
39 |
40 | failed-scheduled-actions', 45 | '', 46 | '' 47 | );?> 48 |
49 | 50 | -------------------------------------------------------------------------------- /templates/admin/html-variation-synchronisation.php: -------------------------------------------------------------------------------- 1 | 18 | 50 | -------------------------------------------------------------------------------- /templates/admin/status.php: -------------------------------------------------------------------------------- 1 | 17 |
21 | 22 | 23 | |
24 | ||
---|---|---|
: | 48 |49 | | 50 | '; 67 | $row_number--; 68 | } 69 | } 70 | if ( isset( $data['note'] ) ) { 71 | if ( empty( $mark ) ) { 72 | echo wp_kses_post( $data['note'] ); 73 | } else { ?> 74 | '; 77 | } 78 | echo wp_kses_post( $data['note'] );?> 79 | 83 | | 84 |
get_formatted_billing_full_name() ) ); ?>
23 | ' : ''; ?> 24 | 25 |get_order_number(), $order->get_formatted_billing_full_name(), wcs_get_human_time_diff( $retry->get_time() ) ) ); ?>
24 | 25 | ' : ''; ?> 26 | 27 |get_billing_first_name() ) ); ?>
23 | 24 | ' : ''; ?> 25 | 26 |get_billing_first_name() ) ); ?>
23 | 24 | ' : ''; ?> 25 | 38 | 39 | 40 | 41 |21 | get_billing_first_name() 27 | ) 28 | ); 29 | ?> 30 |
31 |32 | %2$s.', 38 | 'woocommerce-subscriptions' 39 | ), 40 | $subscription_time_til_event, 41 | $subscription_event_date 42 | ), 43 | [ 'strong' => [] ] 44 | ); 45 | ?> 46 |
47 |48 | get_view_order_url() ) . '">' . esc_html__( 'account dashboard', 'woocommerce-subscriptions' ) . '' 55 | ), 56 | [ 'a' => [ 'href' => true ] ] 57 | ); 58 | ?> 59 |
60 | ' : ''; 62 | 63 | // Show subscription details. 64 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text, true ); 65 | 66 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 67 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 68 | 69 | /** 70 | * Show user-defined additional content - this is set in each email's settings. 71 | */ 72 | if ( $additional_content ) { 73 | echo $email_improvements_enabled ? '' : ''; 74 | echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) ); 75 | echo $email_improvements_enabled ? ' |
32 | %2$s.', 38 | 'woocommerce-subscriptions' 39 | ), 40 | $subscription_time_til_event, 41 | $subscription_event_date 42 | ), 43 | [ 'strong' => [] ] 44 | ); 45 | ?> 46 |
47 |21 | get_billing_first_name() 27 | ) 28 | ); 29 | ?> 30 |
31 |32 | %2$s.', 38 | 'woocommerce-subscriptions' 39 | ), 40 | $subscription_time_til_event, 41 | $subscription_event_date 42 | ), 43 | [ 'strong' => [] ] 44 | ); 45 | ?> 46 |
47 | ' : ''; 49 | 50 | // Show subscription details. 51 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text ); 52 | 53 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 54 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 55 | 56 | /** 57 | * Show user-defined additional content - this is set in each email's settings. 58 | */ 59 | if ( $additional_content ) { 60 | echo $email_improvements_enabled ? '' : ''; 61 | echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) ); 62 | echo $email_improvements_enabled ? ' |
get_billing_first_name() ) ); ?>
21 | 22 | ' : ''; 24 | 25 | /* 26 | * @hooked WC_Subscriptions_Email::order_download_details() Shows the order details table. 27 | * @hooked WC_Subscriptions_Email::order_details() Shows the order details table. 28 | */ 29 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 30 | 31 | /* 32 | * @hooked WC_Emails::order_meta() Shows order meta data. 33 | */ 34 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 35 | 36 | /* 37 | * @hooked WC_Emails::customer_details() Shows customer details 38 | * @hooked WC_Emails::email_address() Shows email address 39 | */ 40 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 41 | 42 | /** 43 | * Show user-defined additional content - this is set in each email's settings. 44 | */ 45 | if ( $additional_content ) { 46 | echo $email_improvements_enabled ? '' : ''; 47 | echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) ); 48 | echo $email_improvements_enabled ? ' |
get_billing_first_name() ) ); ?>
18 | 19 |get_time() ) ) ); ?>
20 | 21 | 22 |get_checkout_payment_url() ) . '">', '' ), array( 'a' => array( 'href' => true ) ) ); ?>
23 | 24 | ' : ''; ?> 25 | 26 | ' : ''; 34 | echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) ); 35 | echo $email_improvements_enabled ? '' : ''; 36 | } 37 | 38 | do_action( 'woocommerce_email_footer', $email ); 39 | -------------------------------------------------------------------------------- /templates/emails/customer-processing-renewal-order.php: -------------------------------------------------------------------------------- 1 | ' : ''; 15 | 16 | /* translators: %s: Customer first name */ ?> 17 |get_billing_first_name() ) ); ?>
18 | 19 |get_order_number() ) ); ?>
20 | ' : ''; 23 | 24 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 25 | 26 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 27 | 28 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 29 | 30 | /** 31 | * Show user-defined additional content - this is set in each email's settings. 32 | */ 33 | if ( $additional_content ) { 34 | echo $email_improvements_enabled ? '' : ''; 35 | echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) ); 36 | echo $email_improvements_enabled ? ' |
get_billing_first_name() ) ); ?>
18 | 19 | has_status( 'pending' ) ) : ?> 20 |21 | get_checkout_payment_url() ) . '">' 32 | . esc_html__( 'Pay Now »', 'woocommerce-subscriptions' ) . 33 | '' 34 | ), 35 | [ 36 | 'a' => [ 'href' => true ], 37 | ] 38 | ); 39 | ?> 40 |
41 | has_status( 'failed' ) ) : ?> 42 |43 | get_checkout_payment_url() ) . '">' 54 | . esc_html__( 'Pay Now »', 'woocommerce-subscriptions' ) . 55 | '' 56 | ), 57 | [ 58 | 'a' => [ 'href' => true ], 59 | ] 60 | ); 61 | ?> 62 |
63 | 64 | 65 | ' : ''; ?> 66 | 67 | ' : ''; 75 | echo wp_kses_post( wpautop( wptexturize( $additional_content ) ) ); 76 | echo $email_improvements_enabled ? '' : ''; 77 | } 78 | 79 | do_action( 'woocommerce_email_footer', $email ); 80 | -------------------------------------------------------------------------------- /templates/emails/plain/admin-new-renewal-order.php: -------------------------------------------------------------------------------- 1 | get_formatted_billing_full_name() ); 17 | 18 | echo "\n\n"; 19 | 20 | echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 21 | 22 | /** 23 | * @hooked WC_Subscriptions_Email::order_details() Shows the order details table. 24 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0 25 | */ 26 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 27 | 28 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 29 | 30 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 31 | 32 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 33 | 34 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 35 | 36 | /** 37 | * Show user-defined additional content - this is set in each email's settings. 38 | */ 39 | if ( $additional_content ) { 40 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 41 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 42 | } 43 | 44 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 45 | -------------------------------------------------------------------------------- /templates/emails/plain/admin-new-switch-order.php: -------------------------------------------------------------------------------- 1 | get_formatted_billing_full_name(), $count ); 19 | 20 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 21 | 22 | /** 23 | * @hooked WC_Subscriptions_Email::order_details() Shows the order details table. 24 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0 25 | */ 26 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 27 | 28 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 29 | 30 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 31 | 32 | remove_filter( 'woocommerce_order_item_meta_end', 'WC_Subscriptions_Switcher::print_switch_link', 10 ); 33 | 34 | foreach ( $subscriptions as $subscription ) { 35 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 36 | } 37 | 38 | add_filter( 'woocommerce_order_item_meta_end', 'WC_Subscriptions_Switcher::print_switch_link', 10, 3 ); 39 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 40 | 41 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 42 | 43 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 44 | 45 | /** 46 | * Show user-defined additional content - this is set in each email's settings. 47 | */ 48 | if ( $additional_content ) { 49 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 50 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 51 | } 52 | 53 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 54 | -------------------------------------------------------------------------------- /templates/emails/plain/admin-payment-retry.php: -------------------------------------------------------------------------------- 1 | get_order_number(), $order->get_formatted_billing_full_name(), wcs_get_human_time_diff( $retry->get_time() ) ) . "\n\n"; 21 | echo sprintf( __( 'The renewal order is as follows:', 'woocommerce-subscriptions' ) ) . "\n\n"; 22 | 23 | echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 24 | 25 | /** 26 | * @hooked WC_Emails::order_details() Shows the order details table. 27 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.5.0 28 | */ 29 | do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 30 | 31 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 32 | 33 | /** 34 | * @hooked WC_Emails::order_meta() Shows order meta data. 35 | */ 36 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 37 | 38 | /** 39 | * @hooked WC_Emails::customer_details() Shows customer details 40 | * @hooked WC_Emails::email_address() Shows email address 41 | */ 42 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 43 | 44 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 45 | 46 | /** 47 | * Show user-defined additional content - this is set in each email's settings. 48 | */ 49 | if ( $additional_content ) { 50 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 51 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 52 | } 53 | 54 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 55 | -------------------------------------------------------------------------------- /templates/emails/plain/cancelled-subscription.php: -------------------------------------------------------------------------------- 1 | get_formatted_billing_full_name() ); 17 | 18 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 19 | 20 | /** 21 | * @hooked WC_Subscriptions_Email::order_details() Shows the order details table. 22 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0 23 | */ 24 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 25 | 26 | echo "\n----------\n\n"; 27 | 28 | $last_order_time_created = $subscription->get_time( 'last_order_date_created', 'site' ); 29 | 30 | if ( ! empty( $last_order_time_created ) ) { 31 | // translators: placeholder is last time subscription was paid 32 | echo sprintf( __( 'Last Order Date: %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), $last_order_time_created ) ) . "\n"; 33 | } 34 | 35 | $end_time = $subscription->get_time( 'end', 'site' ); 36 | 37 | if ( ! empty( $end_time ) ) { 38 | // translators: placeholder is localised date string 39 | echo sprintf( __( 'End of Prepaid Term: %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), $end_time ) ) . "\n"; 40 | } 41 | 42 | do_action( 'woocommerce_email_order_meta', $subscription, $sent_to_admin, $plain_text, $email ); 43 | 44 | echo "\n" . sprintf( _x( 'View Subscription: %s', 'in plain emails for subscription information', 'woocommerce-subscriptions' ), wcs_get_edit_post_link( $subscription->get_id() ) ) . "\n"; 45 | 46 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 47 | 48 | do_action( 'woocommerce_email_customer_details', $subscription, $sent_to_admin, $plain_text, $email ); 49 | 50 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 51 | 52 | /** 53 | * Show user-defined additional content - this is set in each email's settings. 54 | */ 55 | if ( $additional_content ) { 56 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 57 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 58 | } 59 | 60 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 61 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-completed-renewal-order.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() ) ) . "\n\n"; 17 | esc_html_e( 'We have finished processing your subscription renewal order.', 'woocommerce-subscriptions' ) . "\n\n"; 18 | 19 | echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 20 | 21 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 22 | 23 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 24 | 25 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 26 | 27 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 28 | 29 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 30 | 31 | /** 32 | * Show user-defined additional content - this is set in each email's settings. 33 | */ 34 | if ( $additional_content ) { 35 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 36 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 37 | } 38 | 39 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 40 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-completed-switch-order.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() ) ) . "\n\n"; 17 | esc_html_e( 'You have successfully changed your subscription items. Your new order and subscription details are shown below for your reference:', 'woocommerce-subscriptions' ); 18 | 19 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 20 | 21 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 22 | 23 | // translators: placeholder is order's view url 24 | echo "\n" . sprintf( __( 'View your order: %s', 'woocommerce-subscriptions' ), $order->get_view_order_url() ); 25 | 26 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 27 | 28 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 29 | 30 | foreach ( $subscriptions as $subscription ) { 31 | 32 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 33 | 34 | // translators: placeholder is subscription's view url 35 | echo "\n" . sprintf( __( 'View your subscription: %s', 'woocommerce-subscriptions' ), $subscription->get_view_order_url() ); 36 | } 37 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 38 | 39 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 40 | 41 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 42 | 43 | /** 44 | * Show user-defined additional content - this is set in each email's settings. 45 | */ 46 | if ( $additional_content ) { 47 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 48 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 49 | } 50 | 51 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 52 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-notification-auto-renewal.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() 21 | ) 22 | ); 23 | 24 | echo "\n\n"; 25 | 26 | echo esc_html( 27 | sprintf( 28 | // translators: %1$s: human readable time difference (eg 3 days, 1 day), %2$s: date in local format. 29 | __( 30 | 'Your subscription will automatically renew in %1$s — that’s %2$s.', 31 | 'woocommerce-subscriptions' 32 | ), 33 | $subscription_time_til_event, 34 | $subscription_event_date 35 | ) 36 | ); 37 | 38 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 39 | 40 | // Show subscription details. 41 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text, true ); 42 | 43 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 44 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 45 | 46 | esc_html_e( 'You can manage this subscription from your account dashboard: ', 'woocommerce-subscriptions' ); 47 | echo esc_url( wc_get_page_permalink( 'myaccount' ) ); 48 | 49 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 50 | 51 | /** 52 | * Show user-defined additional content - this is set in each email's settings. 53 | */ 54 | if ( $additional_content ) { 55 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 56 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 57 | } 58 | 59 | echo esc_html( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); 60 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-notification-auto-trial-ending.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() 21 | ) 22 | ); 23 | 24 | echo "\n\n"; 25 | 26 | echo esc_html( 27 | sprintf( 28 | // translators: %1$s: human readable time difference (eg 3 days, 1 day), %2$s: date in local format. 29 | __( 30 | 'Your paid subscription begins when your free trial expires in %1$s — that’s %2$s.', 31 | 'woocommerce-subscriptions' 32 | ), 33 | $subscription_time_til_event, 34 | $subscription_event_date 35 | ) 36 | ); 37 | 38 | echo "\n\n"; 39 | 40 | // translators: %1$s: link to account dashboard. 41 | esc_html_e( 'Payment will be deducted using the payment method on file. You can manage this subscription from your account dashboard: ', 'woocommerce-subscriptions' ); 42 | echo esc_url( wc_get_page_permalink( 'myaccount' ) ); 43 | 44 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 45 | 46 | // Show subscription details. 47 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text, true ); 48 | 49 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 50 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 51 | 52 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 53 | 54 | /** 55 | * Show user-defined additional content - this is set in each email's settings. 56 | */ 57 | if ( $additional_content ) { 58 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 59 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 60 | } 61 | 62 | echo esc_html( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); 63 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-notification-expiring-subscription.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() 21 | ) 22 | ); 23 | 24 | echo "\n\n"; 25 | 26 | echo esc_html( 27 | sprintf( 28 | // translators: %1$s: human readable time difference (eg 3 days, 1 day), %2$s: date in local format. 29 | __( 30 | 'Your subscription expires in %1$s — that’s %2$s.', 31 | 'woocommerce-subscriptions' 32 | ), 33 | $subscription_time_til_event, 34 | $subscription_event_date 35 | ) 36 | ); 37 | 38 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 39 | 40 | // Show subscription details. 41 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text, true ); 42 | 43 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 44 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 45 | 46 | /** 47 | * Show user-defined additional content - this is set in each email's settings. 48 | */ 49 | if ( $additional_content ) { 50 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 51 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 52 | } 53 | 54 | echo esc_html( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); 55 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-notification-manual-renewal.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() 21 | ) 22 | ); 23 | 24 | echo "\n\n"; 25 | 26 | echo esc_html( 27 | sprintf( 28 | // translators: %1$s: human readable time difference (eg 3 days, 1 day), %2$s: date in local format. 29 | __( 30 | 'Your subscription is up for renewal in %1$s — that’s %2$s.', 31 | 'woocommerce-subscriptions' 32 | ), 33 | $subscription_time_til_event, 34 | $subscription_event_date 35 | ) 36 | ); 37 | 38 | echo "\n\n"; 39 | 40 | esc_html_e( 'This subscription will not renew automatically.', 'woocommerce-subscriptions' ); 41 | echo "\n"; 42 | if ( $can_renew_early ) { 43 | esc_html_e( 44 | 'You can renew it manually in a few short steps via the Subscriptions tab in your account dashboard.', 45 | 'woocommerce-subscriptions' 46 | ); 47 | } 48 | 49 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 50 | 51 | if ( $can_renew_early ) { 52 | esc_html_e( 'Renew my subscription: ', 'woocommerce-subscriptions' ); 53 | echo esc_url( $url_for_renewal ); 54 | } else { 55 | esc_html_e( 'Manage my subscription: ', 'woocommerce-subscriptions' ); 56 | echo esc_url( $url_for_renewal ); 57 | } 58 | 59 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 60 | 61 | // Show subscription details. 62 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text ); 63 | 64 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 65 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 66 | 67 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 68 | 69 | /** 70 | * Show user-defined additional content - this is set in each email's settings. 71 | */ 72 | if ( $additional_content ) { 73 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 74 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 75 | } 76 | 77 | echo esc_html( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); 78 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-notification-manual-trial-ending.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() 21 | ) 22 | ); 23 | 24 | echo "\n\n"; 25 | 26 | echo esc_html( 27 | sprintf( 28 | // translators: %1$s: human readable time difference (eg 3 days, 1 day), %2$s: date in local format. 29 | __( 30 | 'Your free trial expires in %1$s — that’s %2$s.', 31 | 'woocommerce-subscriptions' 32 | ), 33 | $subscription_time_til_event, 34 | $subscription_event_date 35 | ) 36 | ); 37 | 38 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 39 | 40 | // Show subscription details. 41 | \WC_Subscriptions_Email::subscription_details( $subscription, $order, $sent_to_admin, $plain_text ); 42 | 43 | /** This action is documented in templates/emails/customer-notification-auto-renewal.php */ 44 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 45 | 46 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 47 | 48 | /** 49 | * Show user-defined additional content - this is set in each email's settings. 50 | */ 51 | if ( $additional_content ) { 52 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 53 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 54 | } 55 | 56 | echo esc_html( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); 57 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-on-hold-renewal-order.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() ) ) . "\n\n"; 17 | echo esc_html__( 'Thanks for your renewal order. It’s on-hold until we confirm that payment has been received. In the meantime, here’s a reminder of your order:', 'woocommerce-subscriptions' ) . "\n\n"; 18 | 19 | /* 20 | * @hooked WC_Emails::order_details() Shows the order details table. 21 | * @hooked WC_Structured_Data::generate_order_data() Generates structured data. 22 | * @hooked WC_Structured_Data::output_structured_data() Outputs structured data. 23 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.5.0 24 | */ 25 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 26 | 27 | echo "\n----------------------------------------\n\n"; 28 | 29 | /* 30 | * @hooked WC_Emails::order_meta() Shows order meta data. 31 | */ 32 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 33 | 34 | /* 35 | * @hooked WC_Emails::customer_details() Shows customer details 36 | * @hooked WC_Emails::email_address() Shows email address 37 | */ 38 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 39 | 40 | echo "\n\n----------------------------------------\n\n"; 41 | 42 | /** 43 | * Show user-defined additional content - this is set in each email's settings. 44 | */ 45 | if ( $additional_content ) { 46 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 47 | echo "\n\n----------------------------------------\n\n"; 48 | } 49 | 50 | echo wp_kses_post( apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ) ); 51 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-payment-retry.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() ) ) . "\n\n"; 17 | /* translators: %s: lowercase human time diff in the form returned by wcs_get_human_time_diff(), e.g. 'in 12 hours' */ 18 | echo sprintf( esc_html_x( 'The automatic payment to renew your subscription has failed. We will retry the payment %s.', 'In customer renewal invoice email', 'woocommerce-subscriptions' ), esc_html( wcs_get_human_time_diff( $retry->get_time() ) ) ) . "\n\n"; 19 | 20 | // translators: %1$s: link to checkout payment url, note: no full stop due to url at the end 21 | echo sprintf( esc_html_x( 'To reactivate the subscription now, you can also log in and pay for the renewal from your account page: %1$s', 'In customer renewal invoice email', 'woocommerce-subscriptions' ), esc_attr( $order->get_checkout_payment_url() ) ); 22 | 23 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 24 | 25 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 26 | 27 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 28 | 29 | /** 30 | * Show user-defined additional content - this is set in each email's settings. 31 | */ 32 | if ( $additional_content ) { 33 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 34 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 35 | } 36 | 37 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 38 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-processing-renewal-order.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() ) ) . "\n\n"; 17 | /* translators: %s: Order number */ 18 | echo sprintf( esc_html__( 'Just to let you know — we\'ve received your subscription renewal order #%s, and it is now being processed:', 'woocommerce-subscriptions' ), esc_html( $order->get_order_number() ) ); 19 | 20 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 21 | 22 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 23 | 24 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 25 | 26 | do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email ); 27 | 28 | do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email ); 29 | 30 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 31 | 32 | /** 33 | * Show user-defined additional content - this is set in each email's settings. 34 | */ 35 | if ( $additional_content ) { 36 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 37 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 38 | } 39 | 40 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 41 | -------------------------------------------------------------------------------- /templates/emails/plain/customer-renewal-invoice.php: -------------------------------------------------------------------------------- 1 | get_billing_first_name() ) ) . "\n\n"; 17 | 18 | if ( $order->has_status( 'pending' ) ) { 19 | // translators: %1$s: name of the blog, %2$s: link to checkout payment url, note: no full stop due to url at the end 20 | printf( esc_html_x( 'An order has been created for you to renew your subscription on %1$s. To pay for this invoice please use the following link: %2$s', 'In customer renewal invoice email', 'woocommerce-subscriptions' ), esc_html( get_bloginfo( 'name' ) ), esc_attr( $order->get_checkout_payment_url() ) ) . "\n\n"; 21 | } elseif ( $order->has_status( 'failed' ) ) { 22 | // translators: %1$s: name of the blog, %2$s: link to checkout payment url, note: no full stop due to url at the end 23 | printf( esc_html_x( 'The automatic payment to renew your subscription with %1$s has failed. To reactivate the subscription, please log in and pay for the renewal from your account page: %2$s', 'In customer renewal invoice email', 'woocommerce-subscriptions' ), esc_html( get_bloginfo( 'name' ) ), esc_attr( $order->get_checkout_payment_url() ) ); 24 | } 25 | 26 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 27 | 28 | do_action( 'woocommerce_subscriptions_email_order_details', $order, $sent_to_admin, $plain_text, $email ); 29 | 30 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 31 | 32 | /** 33 | * Show user-defined additional content - this is set in each email's settings. 34 | */ 35 | if ( $additional_content ) { 36 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 37 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 38 | } 39 | 40 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 41 | -------------------------------------------------------------------------------- /templates/emails/plain/email-order-details.php: -------------------------------------------------------------------------------- 1 | get_order_number() ) . "\n"; 17 | echo sprintf( __( 'Order date: %s', 'woocommerce-subscriptions' ), wcs_format_datetime( wcs_get_objects_property( $order, 'date_created' ) ) ) . "\n"; 18 | } else { 19 | echo sprintf( __( 'Subscription Number: %s', 'woocommerce-subscriptions' ), $order->get_order_number() ) . "\n"; 20 | } 21 | echo "\n" . WC_Subscriptions_Email::email_order_items_table( $order, $order_items_table_args ); 22 | 23 | echo "----------\n\n"; 24 | 25 | if ( $totals = $order->get_order_item_totals() ) { 26 | foreach ( $totals as $total ) { 27 | echo $total['label'] . "\t " . $total['value'] . "\n"; 28 | } 29 | } 30 | 31 | do_action( 'woocommerce_email_after_' . $order_type . '_table', $order, $sent_to_admin, $plain_text, $email ); 32 | -------------------------------------------------------------------------------- /templates/emails/plain/expired-subscription.php: -------------------------------------------------------------------------------- 1 | get_formatted_billing_full_name() ); 17 | 18 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 19 | 20 | /** 21 | * @hooked WC_Subscriptions_Email::order_details() Shows the order details table. 22 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0 23 | */ 24 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 25 | 26 | echo "\n----------\n\n"; 27 | 28 | $last_order_time_created = $subscription->get_time( 'last_order_date_created', 'site' ); 29 | 30 | if ( ! empty( $last_order_time_created ) ) { 31 | // translators: placeholder is last time subscription was paid 32 | echo sprintf( __( 'Last Order Date: %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), $last_order_time_created ) ) . "\n"; 33 | } 34 | 35 | $end_time = $subscription->get_time( 'end', 'site' ); 36 | 37 | if ( ! empty( $end_time ) ) { 38 | // translators: placeholder is localised date string 39 | echo sprintf( __( 'End Date: %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), $end_time ) ) . "\n"; 40 | } 41 | 42 | do_action( 'woocommerce_email_order_meta', $subscription, $sent_to_admin, $plain_text, $email ); 43 | 44 | echo "\n" . sprintf( _x( 'View Subscription: %s', 'in plain emails for subscription information', 'woocommerce-subscriptions' ), wcs_get_edit_post_link( $subscription->get_id() ) ) . "\n"; 45 | 46 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 47 | 48 | do_action( 'woocommerce_email_customer_details', $subscription, $sent_to_admin, $plain_text, $email ); 49 | 50 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 51 | 52 | /** 53 | * Show user-defined additional content - this is set in each email's settings. 54 | */ 55 | if ( $additional_content ) { 56 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 57 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 58 | } 59 | 60 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 61 | -------------------------------------------------------------------------------- /templates/emails/plain/on-hold-subscription.php: -------------------------------------------------------------------------------- 1 | get_formatted_billing_full_name() ); 17 | 18 | echo "\n\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; 19 | 20 | /** 21 | * @hooked WC_Subscriptions_Email::order_details() Shows the order details table. 22 | * @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.1.0 23 | */ 24 | do_action( 'woocommerce_subscriptions_email_order_details', $subscription, $sent_to_admin, $plain_text, $email ); 25 | 26 | echo "\n----------\n\n"; 27 | 28 | $last_order_time_created = $subscription->get_time( 'last_order_date_created', 'site' ); 29 | 30 | if ( ! empty( $last_order_time_created ) ) { 31 | // translators: placeholder is last time subscription was paid 32 | echo sprintf( __( 'Last Order: %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), $last_order_time_created ) ) . "\n"; 33 | } 34 | 35 | // translators: placeholder is localised date string 36 | echo sprintf( __( 'Date Suspended: %s', 'woocommerce-subscriptions' ), date_i18n( wc_date_format(), time() ) ) . "\n"; 37 | 38 | do_action( 'woocommerce_email_order_meta', $subscription, $sent_to_admin, $plain_text, $email ); 39 | 40 | echo "\n" . sprintf( _x( 'View Subscription: %s', 'in plain emails for subscription information', 'woocommerce-subscriptions' ), wcs_get_edit_post_link( $subscription->get_id() ) ) . "\n"; 41 | 42 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 43 | 44 | do_action( 'woocommerce_email_customer_details', $subscription, $sent_to_admin, $plain_text, $email ); 45 | 46 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 47 | 48 | /** 49 | * Show user-defined additional content - this is set in each email's settings. 50 | */ 51 | if ( $additional_content ) { 52 | echo esc_html( wp_strip_all_tags( wptexturize( $additional_content ) ) ); 53 | echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; 54 | } 55 | 56 | echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) ); 57 | -------------------------------------------------------------------------------- /templates/html-modal.php: -------------------------------------------------------------------------------- 1 | 12 |