From e4ed22fb7b98958581d75a77c66b900ab3c9a6cc Mon Sep 17 00:00:00 2001 From: Woo Date: Fri, 18 Oct 2024 15:24:19 +0000 Subject: [PATCH] Updates to 6.1.0 --- admin/Analytics.php | 118 + admin/Analytics/Rest_API.php | 80 + .../Rest_API/Conversions/Controller.php | 226 + .../Rest_API/Conversions/Stats/Controller.php | 76 + .../Rest_API/Conversions/Stats/Store.php | 213 + .../Analytics/Rest_API/Conversions/Store.php | 378 + .../Email_Tracking/Stats_Controller.php | 78 + .../Rest_API/Email_Tracking/Stats_Store.php | 337 + .../Rest_API/Log_Stats_Controller.php | 57 + admin/Analytics/Rest_API/Log_Stats_Store.php | 52 + .../Unsubscribers/Stats_Controller.php | 60 + .../Rest_API/Unsubscribers/Stats_Store.php | 149 + .../Rest_API/Upstream/Generic_Controller.php | 90 + .../Rest_API/Upstream/Generic_Query.php | 68 + .../Upstream/Generic_Stats_Controller.php | 135 + .../Rest_API/Upstream/Generic_Stats_Store.php | 137 + .../Workflow_Runs/Stats_Controller.php | 62 + .../Rest_API/Workflow_Runs/Stats_Store.php | 136 + admin/AssetData.php | 50 + admin/WCAdminConnectPages.php | 206 + admin/admin.php | 1079 +++ admin/ajax.php | 763 ++ admin/assets/.externalized-admin.json | 1 + admin/assets/build/analytics-rtl.css | 2 + admin/assets/build/analytics.asset.php | 1 + admin/assets/build/analytics.css | 2 + admin/assets/build/analytics.js | 3 + admin/assets/build/index-rtl.css | 8 + admin/assets/build/index.asset.php | 1 + admin/assets/build/index.css | 8 + admin/assets/build/index.js | 31 + admin/assets/css/aw-main.css | 1 + admin/assets/css/aw-main.css.map | 1 + admin/assets/css/editor.css | 1 + admin/assets/css/editor.css.map | 1 + admin/assets/css/preview.css | 1 + admin/assets/css/preview.css.map | 1 + admin/assets/img/blank.gif | Bin 0 -> 1101 bytes admin/assets/img/header-badge.svg | 14 + admin/assets/img/loader.svg | 8 + admin/assets/img/presets.svg | 28 + admin/assets/img/welcome-notice-robot.png | Bin 0 -> 6457 bytes admin/assets/js/automatewoo.js | 414 + admin/assets/js/dashboard.js | 210 + admin/assets/js/min/automatewoo.min.js | 2 + admin/assets/js/min/automatewoo.min.js.map | 1 + admin/assets/js/min/dashboard.min.js | 2 + admin/assets/js/min/dashboard.min.js.map | 1 + admin/assets/js/min/modal.min.js | 2 + admin/assets/js/min/modal.min.js.map | 1 + admin/assets/js/min/preview.min.js | 2 + admin/assets/js/min/preview.min.js.map | 1 + admin/assets/js/min/rules.min.js | 2 + admin/assets/js/min/rules.min.js.map | 1 + admin/assets/js/min/settings.min.js | 2 + admin/assets/js/min/settings.min.js.map | 1 + admin/assets/js/min/sms-test.min.js | 2 + admin/assets/js/min/sms-test.min.js.map | 1 + admin/assets/js/min/tools.min.js | 2 + admin/assets/js/min/tools.min.js.map | 1 + admin/assets/js/min/tracks.min.js | 2 + admin/assets/js/min/tracks.min.js.map | 1 + admin/assets/js/min/validate.min.js | 2 + admin/assets/js/min/validate.min.js.map | 1 + admin/assets/js/min/variables.min.js | 2 + admin/assets/js/min/variables.min.js.map | 1 + admin/assets/js/min/workflows.min.js | 2 + admin/assets/js/min/workflows.min.js.map | 1 + admin/assets/js/modal.js | 104 + admin/assets/js/preview.js | 48 + admin/assets/js/rules.js | 636 ++ admin/assets/js/settings.js | 27 + admin/assets/js/sms-test.js | 83 + admin/assets/js/tools.js | 21 + admin/assets/js/tracks.js | 76 + admin/assets/js/validate.js | 218 + admin/assets/js/variables.js | 180 + admin/assets/js/workflows.js | 1301 +++ admin/assets/src/analytics/index.js | 4 + .../assets/src/analytics/register-reports.js | 50 + .../analytics/reports/conversions-table.js | 275 + .../src/analytics/reports/conversions.js | 73 + .../src/analytics/reports/email-tracking.js | 100 + .../src/analytics/reports/filters-config.js | 88 + .../src/analytics/reports/runs-by-date.js | 57 + .../src/base/components/card-row/index.js | 27 + admin/assets/src/base/components/index.js | 6 + .../src/base/components/placeholder/index.js | 22 + .../src/base/components/progress-bar/index.js | 37 + .../base/components/workflow-search/index.js | 106 + admin/assets/src/base/hooks/index.js | 1 + .../src/base/hooks/use-before-unload.js | 27 + admin/assets/src/base/utils.js | 44 + admin/assets/src/data/base/action-types.js | 6 + admin/assets/src/data/base/actions.js | 20 + admin/assets/src/data/base/reducer.js | 45 + admin/assets/src/data/base/selectors.js | 7 + admin/assets/src/data/constants.js | 1 + admin/assets/src/data/index.js | 6 + admin/assets/src/data/presets/action-types.js | 12 + admin/assets/src/data/presets/actions.js | 57 + admin/assets/src/data/presets/constants.js | 1 + admin/assets/src/data/presets/index.js | 22 + admin/assets/src/data/presets/reducer.js | 56 + admin/assets/src/data/presets/resolvers.js | 25 + admin/assets/src/data/presets/selectors.js | 9 + admin/assets/src/index.js | 32 + admin/assets/src/jsconfig.json | 8 + .../src/manual-workflow-runner/api-utils.js | 65 + .../find-items-step/data.js | 140 + .../find-items-step/high-volume-warning.js | 67 + .../find-items-step/index.js | 99 + .../find-items-step/item-finder.js | 136 + .../find-items-step/items-table.js | 47 + .../find-items-step/no-results.js | 38 + .../src/manual-workflow-runner/index.js | 200 + .../large-text-and-icon/index.js | 31 + .../src/manual-workflow-runner/next-button.js | 17 + .../manual-workflow-runner/queue-step/data.js | 68 + .../queue-step/index.js | 176 + .../select-workflow-step.js | 89 + .../src/manual-workflow-runner/utils.js | 38 + admin/assets/src/notice-tracking.js | 52 + admin/assets/src/page-tabs/index.js | 33 + admin/assets/src/presets/index.js | 88 + admin/assets/src/presets/list-item-guide.js | 46 + .../src/presets/list-item-placeholder.js | 23 + admin/assets/src/presets/list-item-preset.js | 52 + admin/assets/src/presets/list-item.js | 30 + admin/assets/src/presets/list-load-error.js | 25 + admin/assets/src/presets/list-placeholder.js | 16 + admin/assets/src/presets/list.js | 46 + admin/assets/src/presets/utils.js | 19 + admin/assets/src/settings.js | 26 + .../src/upstream/utils/async-requests.js | 38 + .../components/report-chart/index.js | 439 + .../components/report-chart/test/index.js | 32 + .../components/report-chart/utils.js | 54 + .../components/report-error/index.js | 46 + .../components/report-summary/index.js | 248 + .../components/report-summary/test/index.js | 148 + .../components/report-table/download-icon.js | 18 + .../components/report-table/index.js | 693 ++ .../components/report-table/utils.js | 64 + .../lib/currency-context.js | 37 + .../utils/admin-settings.js | 8 + admin/assets/src/workflow-tab-handler.js | 165 + admin/assets/src/workflow-tinymce.js | 30 + admin/controllers.php | 78 + admin/controllers/base.php | 264 + admin/controllers/carts.php | 93 + admin/controllers/dashboard.php | 327 + admin/controllers/guests.php | 144 + admin/controllers/logs.php | 114 + admin/controllers/opt-ins.php | 101 + admin/controllers/preview.php | 81 + admin/controllers/queue.php | 125 + admin/controllers/reports.php | 121 + admin/controllers/settings.php | 93 + admin/controllers/tools.php | 205 + admin/coupons-list.php | 126 + admin/dashboard-widgets/abstract.php | 109 + .../dashboard-widgets/analytics-abstract.php | 77 + .../analytics-conversions.php | 82 + admin/dashboard-widgets/analytics-email.php | 92 + .../analytics-workflows-run.php | 72 + admin/dashboard-widgets/chart-abstract.php | 164 + admin/dashboard-widgets/chart-conversions.php | 109 + admin/dashboard-widgets/chart-email.php | 147 + .../dashboard-widgets/chart-workflows-run.php | 86 + admin/dashboard-widgets/key-figures.php | 92 + admin/dashboard-widgets/logs.php | 106 + admin/dashboard-widgets/queue.php | 84 + admin/dashboard-widgets/workflows.php | 117 + admin/data-layer-formatter.php | 163 + admin/json-search.php | 259 + admin/list-table.php | 391 + admin/reports-tabs/abstract.php | 86 + admin/reports-tabs/conversions-list.php | 64 + admin/reports-tabs/conversions.php | 27 + admin/reports-tabs/email-tracking.php | 27 + admin/reports-tabs/runs-by-date.php | 27 + admin/reports/abstract-graph.php | 98 + admin/reports/carts.php | 194 + admin/reports/conversions-list.php | 199 + admin/reports/conversions.php | 309 + admin/reports/email-tracking.php | 457 + admin/reports/guests.php | 188 + admin/reports/logs.php | 175 + admin/reports/opt-ins.php | 185 + admin/reports/queue.php | 201 + admin/reports/runs-by-date.php | 262 + admin/settings-tabs/abstract.php | 697 ++ admin/settings-tabs/active-campaign.php | 79 + admin/settings-tabs/bitly.php | 77 + admin/settings-tabs/campaign-monitor.php | 83 + admin/settings-tabs/carts.php | 71 + admin/settings-tabs/general.php | 271 + admin/settings-tabs/mailchimp.php | 119 + admin/settings-tabs/status.php | 55 + admin/settings-tabs/twilio.php | 94 + admin/user-tags-export.php | 116 + admin/views/action-fields.php | 79 + admin/views/action.php | 89 + admin/views/data-upgrade-prompt.php | 39 + admin/views/email-preview-loader.php | 9 + admin/views/email-preview-ui.php | 51 + admin/views/hoverable-date.php | 37 + admin/views/js-workflow-preset-alert.php | 49 + admin/views/js-workflow-templates.php | 34 + admin/views/meta-box-actions.php | 66 + admin/views/meta-box-manual-workflow.php | 37 + admin/views/meta-box-options.php | 105 + admin/views/meta-box-rules.php | 9 + admin/views/meta-box-save.php | 124 + admin/views/meta-box-timing.php | 197 + admin/views/meta-box-trigger.php | 65 + admin/views/meta-box-variables.php | 48 + admin/views/modal-cart-info.php | 127 + admin/views/modal-log-info.php | 74 + admin/views/modal-queued-event-info.php | 39 + admin/views/modal-variable-info.php | 70 + admin/views/page-dashboard.php | 43 + admin/views/page-data-upgrade.php | 185 + admin/views/page-guest-details.php | 89 + admin/views/page-heading.php | 18 + admin/views/page-reports.php | 38 + admin/views/page-settings.php | 34 + admin/views/page-table-with-sidebar.php | 37 + admin/views/page-tools-form-confirm.php | 53 + admin/views/page-tools-form.php | 76 + admin/views/page-tools-list.php | 41 + admin/views/rules.php | 198 + admin/views/settings-form.php | 23 + admin/views/simple-notice.php | 39 + admin/views/sms-test-twilio.php | 69 + admin/views/system-check.php | 55 + admin/views/tool-header.php | 25 + admin/views/trigger-fields.php | 77 + admin/views/welcome-notice.php | 45 + admin/workflow-edit.php | 554 ++ admin/workflow-list.php | 232 + assets/css/automatewoo-communication-page.css | 1 + .../automatewoo-communication-page.css.map | 1 + assets/css/automatewoo-main.css | 1 + assets/css/automatewoo-main.css.map | 1 + assets/img/automatewoo-icon.png | Bin 0 -> 1352 bytes assets/js/.externalized-blocks.json | 1 + assets/js/automatewoo-presubmit.js | 101 + assets/js/automatewoo-presubmit.min.js | 2 + assets/js/automatewoo-presubmit.min.js.map | 1 + .../marketing-optin-block-frontend.asset.php | 1 + .../build/marketing-optin-block-frontend.js | 1 + assets/js/build/marketing-optin-block-rtl.css | 1 + .../js/build/marketing-optin-block.asset.php | 1 + assets/js/build/marketing-optin-block.css | 1 + assets/js/build/marketing-optin-block.js | 1 + assets/js/marketing-optin-block/attributes.js | 13 + assets/js/marketing-optin-block/block.js | 41 + assets/js/marketing-optin-block/block.json | 22 + assets/js/marketing-optin-block/edit.js | 75 + assets/js/marketing-optin-block/frontend.js | 17 + assets/js/marketing-optin-block/index.js | 20 + automatewoo.php | 227 + changelog.txt | 1918 ++++ includes/AbstractOptionsStore.php | 65 + includes/Abstract_Model_With_Meta_Table.php | 349 + includes/Action.php | 455 + .../AW_AsyncRequest_QueueRunner.php | 40 + includes/ActionScheduler/ActionScheduler.php | 181 + .../ActionSchedulerInterface.php | 131 + .../ActionScheduler/AsyncActionRunner.php | 86 + includes/Actions.php | 159 + includes/Actions/ActionInterface.php | 114 + includes/Actions/Active_Campaign_Abstract.php | 103 + includes/Actions/Active_Campaign_Add_Tag.php | 85 + .../Active_Campaign_Create_Contact.php | 87 + .../Actions/Active_Campaign_Remove_Tag.php | 61 + .../Active_Campaign_Update_Contact_Field.php | 79 + includes/Actions/Add_To_Mad_Mimi_List.php | 79 + .../Actions/Campaign_Monitor_Abstract.php | 73 + .../Campaign_Monitor_Add_Subscriber.php | 58 + .../Campaign_Monitor_Remove_Subscriber.php | 77 + includes/Actions/Change_Post_Status.php | 48 + includes/Actions/Change_Workflow_Status.php | 46 + includes/Actions/Clear_Queued_Events.php | 62 + includes/Actions/Custom_Function.php | 40 + includes/Actions/Customer_Add_Tags.php | 56 + includes/Actions/Customer_Change_Role.php | 73 + includes/Actions/Customer_Remove_Tags.php | 41 + includes/Actions/Customer_Update_Meta.php | 56 + includes/Actions/Mailchimp_Abstract.php | 69 + includes/Actions/Mailchimp_Add_To_Group.php | 106 + .../Actions/Mailchimp_Remove_From_Group.php | 58 + includes/Actions/Mailchimp_Subscribe.php | 66 + includes/Actions/Mailchimp_Unsubscribe.php | 67 + .../Mailchimp_Update_Contact_Field.php | 107 + includes/Actions/Mailchimp_Update_Tags.php | 93 + includes/Actions/Mailpoet_Abstract.php | 29 + includes/Actions/Mailpoet_Subscribe.php | 62 + includes/Actions/Mailpoet_Unsubscribe.php | 57 + includes/Actions/Memberships_Abstract.php | 21 + includes/Actions/Memberships_Change_Plan.php | 159 + .../Actions/Memberships_Change_Status.php | 123 + .../Memberships_Delete_User_Membership.php | 82 + includes/Actions/Order_Add_Note.php | 97 + includes/Actions/Order_Change_Status.php | 62 + includes/Actions/Order_Item_Update_Meta.php | 50 + includes/Actions/Order_Resend_Email.php | 120 + includes/Actions/Order_Trigger_Action.php | 105 + .../Order_Update_Customer_Shipping_Note.php | 78 + includes/Actions/Order_Update_Meta.php | 72 + .../Actions/Points_Rewards_Add_Points.php | 31 + .../Points_Rewards_Edit_Points_Abstract.php | 87 + .../Actions/Points_Rewards_Remove_Points.php | 31 + includes/Actions/PreviewableInterface.php | 24 + includes/Actions/Send_Email.php | 159 + includes/Actions/Send_Email_Abstract.php | 120 + includes/Actions/Send_Email_Plain_Text.php | 131 + includes/Actions/Send_Email_Raw.php | 136 + includes/Actions/Send_SMS_Twilio.php | 209 + includes/Actions/Subscription_Add_Coupon.php | 68 + includes/Actions/Subscription_Add_Note.php | 51 + includes/Actions/Subscription_Add_Product.php | 99 + .../Actions/Subscription_Change_Status.php | 62 + .../Subscription_Edit_Coupon_Abstract.php | 71 + .../Subscription_Edit_Product_Abstract.php | 132 + .../Actions/Subscription_Remove_Coupon.php | 56 + .../Actions/Subscription_Remove_Product.php | 84 + .../Actions/Subscription_Send_Invoice.php | 47 + includes/Actions/Subscription_Update_Meta.php | 47 + .../Subscriptions/AbstractEditDateItem.php | 77 + .../Subscriptions/AbstractEditItem.php | 240 + .../Subscriptions/AbstractEditShipping.php | 141 + .../Actions/Subscriptions/AddShipping.php | 96 + .../Subscriptions/RecalculateTaxes.php | 58 + .../RegenerateDownloadPermissions.php | 51 + .../Actions/Subscriptions/RemoveShipping.php | 97 + .../Actions/Subscriptions/UpdateCurrency.php | 100 + .../Actions/Subscriptions/UpdateEndDate.php | 65 + .../Subscriptions/UpdateNextPaymentDate.php | 65 + .../Actions/Subscriptions/UpdateProduct.php | 154 + .../Actions/Subscriptions/UpdateSchedule.php | 153 + .../Actions/Subscriptions/UpdateShipping.php | 87 + .../Subscriptions/UpdateTrialEndDate.php | 65 + includes/Actions/TestableInterface.php | 24 + includes/Actions/Update_Product_Meta.php | 56 + includes/Active_Triggers_Cache.php | 101 + .../SubscriptionsAddonDeactivatedNote.php | 66 + includes/ActivityPanelInbox/UpdateNote.php | 111 + includes/Addons.php | 50 + includes/AdminNotices.php | 203 + includes/AdminNotices/AbstractAdminNotice.php | 41 + includes/AdminNotices/AddonWelcome.php | 74 + .../AdminNotices/AdminNoticeInterface.php | 21 + .../AdminNotices/NewWorkflowHelperManager.php | 75 + includes/AdminNotices/UpdateNoticeManager.php | 84 + includes/AdminNotices/WcAdminDisabled.php | 63 + .../AdminNotices/WelcomeNoticeManager.php | 88 + includes/Ajax.php | 100 + includes/Async_Events.php | 206 + .../Async_Events/Abstract_Async_Event.php | 109 + includes/Async_Events/BookingCreated.php | 160 + .../Async_Events/BookingStatusChanged.php | 79 + includes/Async_Events/MC4WP_Form_Success.php | 61 + includes/Async_Events/MembershipCreated.php | 37 + .../Membership_Status_Changed.php | 49 + includes/Async_Events/Order_Created.php | 117 + includes/Async_Events/Order_Paid.php | 71 + includes/Async_Events/Order_Pending.php | 78 + .../Async_Events/Order_Status_Changed.php | 48 + includes/Async_Events/Review_Approved.php | 43 + .../Async_Events/Subscription_Created.php | 45 + .../Subscription_Renewal_Payment_Complete.php | 45 + .../Subscription_Renewal_Payment_Failed.php | 32 + .../Subscription_Status_Changed.php | 49 + .../UniqueEventsForRequestHelper.php | 42 + includes/Async_Events/User_Registered.php | 32 + includes/AutomateWoo.php | 496 ++ includes/AutomateWoo_Legacy.php | 100 + includes/Blocks/Marketing_Optin_Block.php | 116 + includes/Cache.php | 132 + includes/Cart.php | 573 ++ includes/Cart_Factory.php | 119 + includes/Cart_Item.php | 251 + includes/Cart_Query.php | 100 + includes/Carts.php | 397 + includes/Carts/CartRestorer.php | 164 + includes/Clean.php | 234 + includes/Communication_Account_Tab.php | 110 + includes/Communication_Page.php | 82 + includes/Constants.php | 76 + includes/Conversions.php | 136 + includes/Cookies.php | 51 + includes/Coupon_Generator.php | 246 + includes/Cron.php | 192 + includes/Customer.php | 1018 +++ includes/Customer_Factory.php | 354 + includes/Customer_Query.php | 27 + includes/Customers.php | 130 + includes/DataTypes/AbstractDataType.php | 89 + includes/DataTypes/Booking.php | 75 + includes/DataTypes/Card.php | 48 + includes/DataTypes/Cart.php | 56 + includes/DataTypes/Comment.php | 44 + includes/DataTypes/Customer.php | 97 + includes/DataTypes/DataTypes.php | 166 + includes/DataTypes/Download.php | 79 + includes/DataTypes/Guest.php | 73 + includes/DataTypes/Membership.php | 63 + includes/DataTypes/Order.php | 83 + includes/DataTypes/OrderItem.php | 56 + includes/DataTypes/OrderNote.php | 48 + includes/DataTypes/Post.php | 46 + includes/DataTypes/Product.php | 47 + includes/DataTypes/ProductCategory.php | 51 + includes/DataTypes/ProductTag.php | 33 + includes/DataTypes/Refund.php | 32 + includes/DataTypes/Review.php | 45 + includes/DataTypes/SenseiCourse.php | 33 + includes/DataTypes/SenseiGroup.php | 33 + includes/DataTypes/SenseiLesson.php | 33 + includes/DataTypes/SenseiQuiz.php | 33 + includes/DataTypes/SenseiTeacher.php | 70 + includes/DataTypes/Shop.php | 53 + includes/DataTypes/Subscription.php | 79 + includes/DataTypes/SubscriptionItem.php | 37 + includes/DataTypes/User.php | 70 + includes/DataTypes/Wishlist.php | 47 + includes/DataTypes/Workflow.php | 49 + includes/Data_Layer.php | 716 ++ includes/DatabaseTables/Carts.php | 76 + includes/DatabaseTables/CustomerMeta.php | 58 + includes/DatabaseTables/Customers.php | 67 + includes/DatabaseTables/GuestMeta.php | 54 + includes/DatabaseTables/Guests.php | 63 + includes/DatabaseTables/LogMeta.php | 54 + includes/DatabaseTables/Logs.php | 59 + includes/DatabaseTables/Queue.php | 57 + includes/DatabaseTables/QueueMeta.php | 53 + includes/DatabaseUpdates/2.6.0.php | 238 + includes/DatabaseUpdates/2.6.1.php | 23 + includes/DatabaseUpdates/2.7.0.php | 53 + includes/DatabaseUpdates/2.9.7.php | 65 + includes/DatabaseUpdates/3.0.0.php | 184 + includes/DatabaseUpdates/3.5.0.php | 99 + includes/DatabaseUpdates/3.6.0.php | 66 + includes/DatabaseUpdates/4.0.0.php | 86 + includes/DatabaseUpdates/5.0.0.php | 105 + includes/DatabaseUpdates/5.1.0.php | 146 + includes/DatabaseUpdates/5.3.0.php | 61 + includes/DatabaseUpdates/6.0.0.php | 43 + .../AbstractDatabaseUpdate.php | 127 + includes/Database_Table.php | 81 + includes/Database_Tables.php | 82 + includes/DateTime.php | 123 + includes/Download.php | 147 + includes/Emails.php | 191 + includes/Entity/Action.php | 9 + includes/Entity/NamedEntityWithOptions.php | 41 + includes/Entity/Rule.php | 86 + includes/Entity/RuleGroup.php | 80 + includes/Entity/ToArray.php | 19 + includes/Entity/Trigger.php | 9 + includes/Entity/Workflow.php | 472 + includes/Entity/WorkflowTiming.php | 14 + includes/Entity/WorkflowTimingBase.php | 30 + includes/Entity/WorkflowTimingDelayed.php | 69 + includes/Entity/WorkflowTimingFixed.php | 42 + includes/Entity/WorkflowTimingImmediate.php | 12 + includes/Entity/WorkflowTimingScheduled.php | 69 + includes/Entity/WorkflowTimingVariable.php | 40 + includes/Error.php | 49 + includes/Event_Helpers/Review_Posted.php | 61 + .../Subscription_Status_Changed.php | 64 + includes/Event_Helpers/User_Registration.php | 57 + includes/Exception.php | 8 + includes/Exceptions/Exception.php | 11 + includes/Exceptions/InvalidArgument.php | 55 + includes/Exceptions/InvalidClass.php | 39 + includes/Exceptions/InvalidIntegration.php | 38 + includes/Exceptions/InvalidPath.php | 36 + includes/Exceptions/InvalidPreviewData.php | 55 + includes/Exceptions/InvalidStatus.php | 35 + includes/Exceptions/InvalidValue.php | 29 + includes/Exceptions/InvalidWorkflow.php | 46 + includes/Exceptions/UserFacingException.php | 13 + includes/Factories.php | 81 + includes/Factory.php | 171 + includes/Fields/Attribute.php | 31 + includes/Fields/Attribute_Term.php | 79 + includes/Fields/Before_After_Day.php | 121 + includes/Fields/BookingStatus.php | 29 + includes/Fields/Category.php | 56 + includes/Fields/Checkbox.php | 74 + includes/Fields/Countries.php | 24 + includes/Fields/Coupon.php | 85 + includes/Fields/Date.php | 28 + includes/Fields/EmailAddressWithName.php | 68 + includes/Fields/Email_Content.php | 91 + includes/Fields/Field.php | 323 + includes/Fields/HTML_Textarea.php | 47 + includes/Fields/Number.php | 67 + includes/Fields/Order_Note_Type.php | 28 + includes/Fields/Order_Status.php | 30 + includes/Fields/Payment_Gateway.php | 34 + includes/Fields/Positive_Number.php | 23 + includes/Fields/Price.php | 68 + includes/Fields/Product.php | 105 + .../Fields/Searchable_Select_Abstract.php | 129 + includes/Fields/Select.php | 215 + includes/Fields/Sensei_Course.php | 55 + includes/Fields/Sensei_Group.php | 55 + includes/Fields/Sensei_Lesson.php | 55 + includes/Fields/Sensei_Question.php | 55 + includes/Fields/Sensei_Quiz.php | 55 + includes/Fields/Subscription_Products.php | 87 + includes/Fields/Subscription_Status.php | 33 + includes/Fields/Tag.php | 52 + includes/Fields/Taxonomy.php | 56 + includes/Fields/Taxonomy_Term.php | 57 + includes/Fields/Text.php | 66 + includes/Fields/Text_Area.php | 101 + includes/Fields/Time.php | 114 + includes/Fields/User_Role.php | 41 + includes/Fields/User_Tags.php | 36 + includes/Fields/Workflow.php | 84 + includes/Fields_Helper.php | 67 + includes/Format.php | 364 + includes/Formatters/Boolean_Formatter.php | 17 + includes/Formatters/Float_Formatter.php | 19 + includes/Formatters/Formattable.php | 15 + includes/Formatters/Int_String_Formatter.php | 19 + includes/Frontend.php | 176 + includes/Frontend_Endpoints.php | 203 + .../Frontend_Endpoints/Login_Redirect.php | 100 + includes/Frontend_Form_Handler.php | 113 + includes/Guest.php | 502 ++ includes/Guest_Factory.php | 108 + includes/Guest_Query.php | 53 + includes/HPOS_Helper.php | 21 + includes/Hooks.php | 186 + includes/Installer.php | 322 + includes/Integration.php | 72 + includes/Integrations.php | 372 + includes/Integrations/ActiveCampaign.php | 576 ++ includes/Integrations/Bitly.php | 136 + includes/Integrations/Campaign_Monitor.php | 135 + includes/Integrations/Mad_Mimi.php | 109 + includes/Integrations/Mailchimp.php | 432 + includes/Integrations/Mailpoet.php | 191 + includes/Integrations/Twilio.php | 131 + includes/Jobs/AbandonedCarts.php | 145 + includes/Jobs/AbstractActionSchedulerJob.php | 117 + .../AbstractBatchedActionSchedulerJob.php | 242 + .../AbstractOneTimeActionSchedulerJob.php | 82 + ...ractRecurringBatchedActionSchedulerJob.php | 26 + ...ractRecurringOneTimeActionSchedulerJob.php | 45 + includes/Jobs/ActionSchedulerJobInterface.php | 20 + includes/Jobs/ActionSchedulerJobMonitor.php | 65 + .../BatchedActionSchedulerJobInterface.php | 46 + includes/Jobs/BatchedWorkflows.php | 155 + includes/Jobs/CheckGmtOffsetChange.php | 56 + includes/Jobs/CheckMidnightJob.php | 84 + includes/Jobs/CleanInactiveCarts.php | 57 + includes/Jobs/DeleteExpiredCoupons.php | 133 + includes/Jobs/DeleteFailedQueuedWorkflows.php | 90 + includes/Jobs/JobException.php | 53 + includes/Jobs/JobInterface.php | 24 + includes/Jobs/JobRegistry.php | 151 + includes/Jobs/JobRegistryInterface.php | 35 + includes/Jobs/JobService.php | 127 + includes/Jobs/Midnight.php | 155 + .../OneTimeActionSchedulerJobInterface.php | 38 + includes/Jobs/ProductGoesOnSale.php | 58 + includes/Jobs/RecurringJobInterface.php | 51 + includes/Jobs/RunQueuedWorkflows.php | 106 + includes/Jobs/SetupGuestCustomers.php | 145 + includes/Jobs/SetupRegisteredCustomers.php | 109 + includes/Jobs/StartOnHookInterface.php | 22 + includes/Jobs/ToolTaskRunner.php | 80 + includes/Jobs/Traits/ItemDeletionDate.php | 30 + .../Jobs/Traits/ValidateItemAsIntegerId.php | 27 + includes/Jobs/WishlistItemOnSale.php | 106 + includes/Language.php | 160 + includes/LegacyAddonHandler.php | 76 + includes/Log.php | 545 ++ includes/Log_Factory.php | 24 + includes/Log_Query.php | 130 + includes/Logger.php | 161 + includes/Logic_Helper.php | 45 + includes/Logs.php | 64 + includes/Mailer.php | 475 + includes/Mailer_Abstract.php | 334 + includes/Mailer_Plain_Text.php | 31 + includes/Mailer_Raw_HTML.php | 42 + includes/Memberships_Helper.php | 40 + includes/Model.php | 295 + includes/Notifications.php | 68 + .../Notifications/AbstractNotification.php | 112 + .../Addons/AbstractAddonCheck.php | 64 + .../Notifications/Addons/BirthdaysCheck.php | 56 + .../Addons/ReferAFriendCheck.php | 56 + .../Integrations/AbstractIntegrationCheck.php | 70 + .../Integrations/ActiveCampaignCheck.php | 56 + .../Notifications/Integrations/BitlyCheck.php | 56 + .../Integrations/CampaignMonitorCheck.php | 56 + .../Integrations/MailchimpCheck.php | 56 + .../Integrations/TwilioCheck.php | 56 + includes/Notifications/PHPMinVersionCheck.php | 73 + includes/Notifications/SystemChecks.php | 124 + includes/Notifications/WCMinVersionCheck.php | 74 + .../Notifications/WelcomeNotification.php | 108 + includes/NotificationsInitializer.php | 196 + includes/Options.php | 291 + includes/OptionsStore.php | 84 + includes/Options_API.php | 77 + includes/Options_Abstract.php | 51 + includes/Order_Guest.php | 88 + includes/Order_Helper.php | 156 + includes/Order_Note.php | 64 + .../CustomerLastPurchasedDateUpdater.php | 109 + .../Observers/GuestMostRecentOrderUpdater.php | 76 + .../Observers/Traits/HandleOrderDeleted.php | 66 + .../Traits/HandleOrderStatusChanged.php | 45 + includes/Orders/StatusTransition.php | 86 + includes/Permissions.php | 20 + includes/Phone_Numbers.php | 389 + includes/Points_Rewards_Integration.php | 106 + includes/Post_Types.php | 133 + includes/PreSubmit.php | 181 + includes/Preview_Data.php | 510 ++ includes/Privacy.php | 47 + includes/Privacy_Abstract.php | 56 + includes/Privacy_Erasers.php | 271 + includes/Privacy_Exporters.php | 394 + includes/Privacy_Policy_Guide.php | 65 + includes/Proxies/Bookings.php | 123 + includes/Proxies/BookingsInterface.php | 34 + includes/Query_Abstract.php | 481 + includes/Query_Data_Layer_Abstract.php | 170 + includes/Queue_Manager.php | 51 + includes/Queue_Query.php | 149 + includes/Queued_Event.php | 431 + includes/Queued_Event_Factory.php | 24 + includes/Registry.php | 167 + .../Registry/ItemConstructorArgsTrait.php | 22 + includes/Remote_Request.php | 187 + includes/Replace_Helper.php | 78 + includes/Rest_Api.php | 114 + .../Controllers/AbstractController.php | 34 + .../Controllers/ConversionsController.php | 152 + .../Rest_Api/Controllers/LogsController.php | 208 + .../Controllers/ManualWorkflowRunner.php | 277 + .../Rest_Api/Controllers/WorkflowPresets.php | 204 + includes/Rest_Api/Controllers/Workflows.php | 335 + includes/Rest_Api/Schema/Context.php | 21 + includes/Rest_Api/Schema/LogSchema.php | 156 + includes/Rest_Api/Schema/WorkflowSchema.php | 244 + .../Utilities/Controller_Namespace.php | 27 + .../Utilities/CreateUpdateWorkflow.php | 420 + includes/Rest_Api/Utilities/DateHelper.php | 47 + .../Rest_Api/Utilities/DeleteWorkflow.php | 83 + includes/Rest_Api/Utilities/GetWorkflow.php | 37 + includes/Rest_Api/Utilities/Pagination.php | 105 + includes/Rest_Api/Utilities/RestException.php | 24 + includes/Review.php | 128 + includes/Review_Factory.php | 24 + includes/RuleQuickFilters/ClauseGenerator.php | 126 + .../Clauses/AbstractClause.php | 90 + .../RuleQuickFilters/Clauses/ArrayClause.php | 42 + .../Clauses/ClauseInterface.php | 33 + .../Clauses/DateTimeClause.php | 88 + .../RuleQuickFilters/Clauses/NoOpClause.php | 43 + .../Clauses/NumericClause.php | 42 + .../RuleQuickFilters/Clauses/SetClause.php | 40 + .../RuleQuickFilters/Clauses/StringClause.php | 42 + .../Queries/AbstractPostDatastoreType.php | 469 + .../Queries/AbstractQuery.php | 169 + .../Queries/DatastoreTypeInterface.php | 37 + .../OrderHighPerformanceDatastoreType.php | 504 ++ .../Queries/OrderPostDatastoreType.php | 99 + .../RuleQuickFilters/Queries/OrderQuery.php | 52 + .../Queries/QueryInterface.php | 80 + ...bscriptionHighPerformanceDatastoreType.php | 128 + .../Queries/SubscriptionPostDatastoreType.php | 73 + .../Queries/SubscriptionQuery.php | 52 + includes/RuleQuickFilters/QueryLoader.php | 47 + includes/Rules.php | 212 + includes/Rules/Abstract_Bool.php | 27 + includes/Rules/Abstract_Date.php | 532 ++ includes/Rules/Abstract_Meta.php | 83 + includes/Rules/Abstract_Number.php | 70 + includes/Rules/Abstract_Object.php | 50 + includes/Rules/Abstract_Select.php | 31 + includes/Rules/Abstract_Select_Single.php | 29 + includes/Rules/Abstract_Sensei_Rule.php | 112 + includes/Rules/Abstract_String.php | 20 + includes/Rules/CartItemCount.php | 36 + includes/Rules/CartTotal.php | 37 + includes/Rules/Cart_Coupons.php | 44 + includes/Rules/Cart_Created_Date.php | 51 + includes/Rules/Cart_Item_Categories.php | 59 + includes/Rules/Cart_Item_Tags.php | 58 + includes/Rules/Cart_Items.php | 57 + .../Rules/Customer_2nd_Last_Order_Date.php | 55 + .../Rules/Customer_Account_Created_Date.php | 51 + .../Customer_Active_Membership_Plans.php | 66 + includes/Rules/Customer_City.php | 31 + includes/Rules/Customer_Company.php | 33 + includes/Rules/Customer_Country.php | 74 + includes/Rules/Customer_Email.php | 63 + includes/Rules/Customer_First_Order_Date.php | 51 + .../Customer_Has_Active_Subscription.php | 42 + includes/Rules/Customer_Is_Guest.php | 42 + .../Customer_Is_Mailchimp_Subscriber.php | 43 + includes/Rules/Customer_Last_Order_Date.php | 50 + includes/Rules/Customer_Last_Review_Date.php | 51 + includes/Rules/Customer_Meta.php | 43 + includes/Rules/Customer_Order_Count.php | 35 + includes/Rules/Customer_Order_Statuses.php | 59 + includes/Rules/Customer_Phone.php | 62 + includes/Rules/Customer_Postcode.php | 64 + .../Rules/Customer_Purchased_Categories.php | 58 + .../Rules/Customer_Purchased_Products.php | 57 + includes/Rules/Customer_Review_Count.php | 35 + includes/Rules/Customer_Role.php | 52 + includes/Rules/Customer_Run_Count.php | 39 + includes/Rules/Customer_State.php | 96 + includes/Rules/Customer_State_Text_Match.php | 36 + includes/Rules/Customer_Tags.php | 56 + includes/Rules/Customer_Total_Spent.php | 35 + includes/Rules/GuestEmail.php | 33 + includes/Rules/GuestOrderCount.php | 40 + includes/Rules/GuestRunCount.php | 39 + .../NonPrimaryDataTypeQuickFilterable.php | 32 + includes/Rules/Interfaces/QuickFilterable.php | 36 + includes/Rules/OrderHasCrossSells.php | 44 + includes/Rules/OrderIsCustomersFirst.php | 58 + includes/Rules/OrderIsPos.php | 45 + includes/Rules/OrderRunCount.php | 40 + includes/Rules/OrderShippingCountry.php | 65 + includes/Rules/OrderShippingMethodString.php | 33 + includes/Rules/OrderTotal.php | 57 + includes/Rules/Order_Billing_Country.php | 64 + includes/Rules/Order_Coupon_Count.php | 35 + includes/Rules/Order_Coupons.php | 65 + includes/Rules/Order_Coupons_Text_Match.php | 33 + includes/Rules/Order_Created_Date.php | 73 + includes/Rules/Order_Created_Via.php | 78 + .../Rules/Order_Customer_Provided_Note.php | 57 + includes/Rules/Order_Is_Guest_Order.php | 67 + .../Rules/Order_Is_Subscription_Parent.php | 33 + .../Rules/Order_Is_Subscription_Renewal.php | 43 + includes/Rules/Order_Item_Categories.php | 56 + includes/Rules/Order_Item_Count.php | 36 + includes/Rules/Order_Item_Meta.php | 42 + includes/Rules/Order_Item_Product.php | 53 + includes/Rules/Order_Item_Quantity.php | 33 + includes/Rules/Order_Item_Subtotal.php | 33 + includes/Rules/Order_Item_Tags.php | 55 + includes/Rules/Order_Item_Tax_Total.php | 33 + includes/Rules/Order_Item_Total.php | 47 + includes/Rules/Order_Items.php | 56 + includes/Rules/Order_Items_Text_Match.php | 37 + includes/Rules/Order_Line_Count.php | 33 + includes/Rules/Order_Meta.php | 83 + includes/Rules/Order_Paid_Date.php | 73 + includes/Rules/Order_Payment_Gateway.php | 73 + includes/Rules/Order_Shipping_Method.php | 56 + includes/Rules/Order_Status.php | 65 + ...n_Failed_Automatic_Payment_Retry_Count.php | 44 + .../Rules/Order_Subscription_Order_Type.php | 61 + .../Rules/Points_Rewards_Customer_Points.php | 53 + .../Rules/Preloaded_Select_Rule_Abstract.php | 45 + includes/Rules/Product.php | 49 + includes/Rules/Product_Categories.php | 51 + .../Rules/Product_Select_Rule_Abstract.php | 51 + includes/Rules/Review_Rating.php | 33 + includes/Rules/Rule.php | 485 ++ .../Rules/Searchable_Select_Rule_Abstract.php | 68 + includes/Rules/Select_Rule_Abstract.php | 130 + includes/Rules/Sensei_Have_Failed_Quiz.php | 40 + .../Sensei_Have_Not_Completed_Course.php | 52 + .../Sensei_Have_Not_Completed_Lesson.php | 59 + .../Sensei_Have_Not_Started_First_Lesson.php | 60 + .../Rules/Sensei_Have_Not_Yet_Taken_Quiz.php | 40 + includes/Rules/Sensei_Have_Passed_Quiz.php | 40 + includes/Rules/ShopCurrentDateTime.php | 62 + includes/Rules/SubscriptionPaymentCount.php | 42 + .../Rules/Subscription_Can_Renew_Early.php | 51 + includes/Rules/Subscription_Coupon_Count.php | 28 + includes/Rules/Subscription_Coupons.php | 30 + .../Rules/Subscription_Coupons_Text_Match.php | 29 + includes/Rules/Subscription_Created_Date.php | 73 + includes/Rules/Subscription_End_Date.php | 75 + .../Rules/Subscription_Has_Payment_Method.php | 62 + .../Rules/Subscription_Item_Categories.php | 28 + includes/Rules/Subscription_Items.php | 23 + .../Rules/Subscription_Last_Payment_Date.php | 50 + includes/Rules/Subscription_Meta.php | 42 + .../Rules/Subscription_Next_Payment_Date.php | 73 + .../Rules/Subscription_Payment_Method.php | 56 + .../Subscription_Requires_Manual_Renewal.php | 57 + includes/Rules/Subscription_Run_Count.php | 56 + includes/Rules/Subscription_Status.php | 67 + .../Rules/Subscription_Trial_End_Date.php | 74 + includes/Rules/Utilities/ArrayQuickFilter.php | 44 + .../Rules/Utilities/DataTypeConditions.php | 23 + includes/Rules/Utilities/DateQuickFilter.php | 111 + .../Rules/Utilities/NumericQuickFilter.php | 54 + .../Rules/Utilities/StringQuickFilter.php | 58 + .../Rules/Workflow_Last_Customer_Run_Date.php | 55 + includes/Sensei_Workflow_Helper.php | 150 + includes/Session_Tracker.php | 607 ++ includes/Shipment_Tracking_Integration.php | 42 + includes/ShopDataItem.php | 33 + includes/Subscription_Workflow_Helper.php | 296 + includes/SystemChecks/AbstractSystemCheck.php | 52 + .../ActionSchedulerJobsRunning.php | 62 + includes/SystemChecks/DatabaseTablesExist.php | 48 + includes/System_Checks.php | 98 + includes/Temporary_Data.php | 81 + includes/Time_Helper.php | 96 + includes/Tools/Abstract.php | 91 + .../Tools/Background_Processed_Abstract.php | 58 + includes/Tools/Guest_Eraser.php | 116 + includes/Tools/Optin_Importer.php | 57 + includes/Tools/Optout_Importer.php | 171 + includes/Tools/Reset_Workflow_Records.php | 103 + includes/Tools/ToolsService.php | 80 + includes/Tracking.php | 148 + includes/Traits/ArrayValidator.php | 71 + includes/Traits/IntegerValidator.php | 26 + includes/Traits/IntegrationValidator.php | 32 + includes/Traits/MailServiceAction.php | 103 + includes/Traits/NamedEntity.php | 35 + includes/Traits/OptionsEntity.php | 57 + includes/Traits/StringValidator.php | 26 + includes/Traits/TagField.php | 59 + includes/Trigger.php | 666 ++ includes/Triggers.php | 266 + includes/Triggers/Abandoned_Cart_Customer.php | 23 + includes/Triggers/Abandoned_Cart_Guest.php | 61 + includes/Triggers/Abandoned_Cart_User.php | 63 + .../Triggers/AbstractBatchedDailyTrigger.php | 23 + includes/Triggers/AbstractManual.php | 30 + includes/Triggers/Abstract_Abandoned_Cart.php | 131 + .../Abstract_Downloadable_Content.php | 133 + includes/Triggers/Abstract_Memberships.php | 40 + includes/Triggers/Abstract_Order_Base.php | 87 + .../Triggers/Abstract_Order_Status_Base.php | 121 + includes/Triggers/Abstract_Subscriptions.php | 84 + .../Triggers/BatchedWorkflowInterface.php | 34 + includes/Triggers/BookingCreated.php | 85 + includes/Triggers/BookingStatusChanged.php | 166 + .../Customer_Before_Saved_Card_Expiry.php | 170 + includes/Triggers/Customer_New_Account.php | 49 + includes/Triggers/Customer_Opted_In.php | 47 + includes/Triggers/Customer_Opted_Out.php | 47 + .../Triggers/Customer_Order_Count_Reaches.php | 96 + .../Triggers/Customer_Total_Spend_Reaches.php | 91 + includes/Triggers/Customer_Win_Back.php | 279 + .../Downloadable_Product_Purchased.php | 91 + includes/Triggers/File_Downloaded.php | 53 + includes/Triggers/File_Not_Yet_Downloaded.php | 109 + includes/Triggers/Guest_Created.php | 40 + includes/Triggers/MC4WP_Form_Submission.php | 81 + includes/Triggers/ManualInterface.php | 34 + includes/Triggers/Membership_Created.php | 138 + .../Triggers/Membership_Status_Changed.php | 152 + includes/Triggers/OrderManual.php | 64 + .../Triggers/OrderNoteAddedEachLineItem.php | 59 + includes/Triggers/Order_Cancelled.php | 27 + includes/Triggers/Order_Completed.php | 27 + includes/Triggers/Order_Created.php | 33 + .../Triggers/Order_Created_Each_Line_Item.php | 36 + includes/Triggers/Order_Note_Added.php | 116 + includes/Triggers/Order_On_Hold.php | 27 + includes/Triggers/Order_Paid.php | 33 + .../Triggers/Order_Paid_Each_Line_Item.php | 35 + includes/Triggers/Order_Pending.php | 27 + includes/Triggers/Order_Processing.php | 27 + includes/Triggers/Order_Refunded.php | 81 + includes/Triggers/Order_Refunded_Manual.php | 31 + includes/Triggers/Order_Status_Changes.php | 101 + .../Order_Status_Changes_Each_Line_Item.php | 29 + includes/Triggers/Review_Posted.php | 80 + includes/Triggers/Sensei_Course_Completed.php | 77 + ...ensei_Course_Completed_By_All_Students.php | 108 + .../Sensei_Course_Not_Yet_Completed.php | 129 + includes/Triggers/Sensei_Course_Signed_Up.php | 77 + includes/Triggers/Sensei_Lesson_Completed.php | 95 + includes/Triggers/Sensei_Lesson_Started.php | 100 + includes/Triggers/Sensei_Quiz_Completed.php | 116 + includes/Triggers/Sensei_Quiz_Failed.php | 23 + includes/Triggers/Sensei_Quiz_Passed.php | 25 + .../Sensei_Specific_Answer_Selected.php | 114 + .../Sensei_Student_Added_To_Group.php | 76 + .../Sensei_Student_Removed_From_Group.php | 81 + includes/Triggers/SubscriptionManual.php | 64 + includes/Triggers/Subscription_Before_End.php | 88 + .../Triggers/Subscription_Before_Renewal.php | 233 + includes/Triggers/Subscription_Created.php | 81 + .../Subscription_Created_Each_Line_Item.php | 49 + includes/Triggers/Subscription_Note_Added.php | 69 + .../Triggers/Subscription_Order_Created.php | 69 + includes/Triggers/Subscription_Order_Paid.php | 67 + .../Subscription_Order_Status_Changes.php | 68 + .../Subscription_Payment_Complete.php | 113 + .../Triggers/Subscription_Payment_Failed.php | 93 + .../Triggers/Subscription_Status_Changed.php | 147 + ...cription_Status_Changed_Each_Line_Item.php | 43 + includes/Triggers/Subscription_Trial_End.php | 71 + .../User_Purchases_From_Taxonomy_Term.php | 84 + ...hases_Product_Variation_With_Attribute.php | 153 + .../Triggers/Utilities/BookingDataLayer.php | 68 + includes/Triggers/Utilities/BookingsGroup.php | 20 + .../Triggers/Utilities/CustomTimeOfDay.php | 74 + .../Utilities/HandleOrderNoteAdded.php | 63 + includes/Triggers/Utilities/OrderGroup.php | 20 + .../Triggers/Utilities/SubscriptionGroup.php | 20 + includes/Triggers/Wishlist_Item_Added.php | 116 + .../Triggers/Wishlist_Item_Goes_On_Sale.php | 93 + includes/Triggers/Wishlist_Reminder.php | 176 + .../Triggers/Workflow_Times_Run_Reaches.php | 83 + includes/Usage_Tracking/Conversions.php | 46 + includes/Usage_Tracking/Event_Helper.php | 44 + .../Event_Tracker_Interface.php | 24 + includes/Usage_Tracking/Initializer.php | 106 + includes/Usage_Tracking/Install.php | 30 + includes/Usage_Tracking/Tracker.php | 266 + includes/Usage_Tracking/Tracks.php | 55 + includes/Usage_Tracking/Tracks_Interface.php | 20 + .../Usage_Tracking/WorkflowTracksData.php | 99 + includes/Usage_Tracking/Workflows.php | 51 + includes/Usage_Tracking/readme.md | 104 + includes/User_Tags.php | 476 + includes/Variable.php | 172 + includes/Variables.php | 362 + includes/Variables/AbstractBookingTime.php | 50 + includes/Variables/AbstractTime.php | 39 + includes/Variables/Abstract_Datetime.php | 221 + .../Variables/Abstract_Generate_Coupon.php | 120 + includes/Variables/Abstract_Meta.php | 18 + includes/Variables/Abstract_Price.php | 51 + .../Variables/Abstract_Product_Display.php | 172 + .../Variables/Abstract_Shipment_Tracking.php | 26 + includes/Variables/BookingCost.php | 37 + includes/Variables/BookingEndDate.php | 36 + includes/Variables/BookingEndTime.php | 35 + includes/Variables/BookingId.php | 35 + includes/Variables/BookingPersons.php | 58 + includes/Variables/BookingResource.php | 40 + includes/Variables/BookingStartDate.php | 36 + includes/Variables/BookingStartTime.php | 35 + includes/Variables/BookingStatus.php | 35 + includes/Variables/Card_Expiry_Month.php | 27 + includes/Variables/Card_Expiry_Year.php | 27 + includes/Variables/Card_Last4.php | 27 + includes/Variables/Card_Type.php | 27 + includes/Variables/CartId.php | 35 + includes/Variables/Cart_Item_Count.php | 28 + includes/Variables/Cart_Items.php | 91 + includes/Variables/Cart_Link.php | 56 + includes/Variables/Cart_Total.php | 33 + includes/Variables/Category_ID.php | 27 + includes/Variables/Category_Permalink.php | 30 + includes/Variables/Category_Title.php | 27 + includes/Variables/CommentAuthorName.php | 30 + includes/Variables/Comment_Author_IP.php | 27 + includes/Variables/Comment_Content.php | 28 + includes/Variables/Comment_ID.php | 27 + .../Variables/Customer_Address_Line_1.php | 39 + .../Variables/Customer_Address_Line_2.php | 39 + includes/Variables/Customer_City.php | 29 + includes/Variables/Customer_Company.php | 29 + includes/Variables/Customer_Country.php | 35 + includes/Variables/Customer_Email.php | 29 + includes/Variables/Customer_First_Name.php | 29 + includes/Variables/Customer_Full_Name.php | 28 + .../Variables/Customer_Generate_Coupon.php | 23 + includes/Variables/Customer_Last_Name.php | 29 + includes/Variables/Customer_Meta.php | 34 + includes/Variables/Customer_Order_Count.php | 30 + includes/Variables/Customer_Phone.php | 29 + includes/Variables/Customer_Points.php | 70 + includes/Variables/Customer_Postcode.php | 29 + includes/Variables/Customer_State.php | 47 + includes/Variables/Customer_Tags.php | 31 + includes/Variables/Customer_Total_Spent.php | 33 + .../Variables/Customer_Unsubscribe_URL.php | 30 + includes/Variables/Customer_User_ID.php | 29 + includes/Variables/Customer_Username.php | 39 + includes/Variables/Download_File_Name.php | 32 + includes/Variables/Download_URL.php | 32 + includes/Variables/Guest_Email.php | 27 + includes/Variables/Guest_First_Name.php | 26 + includes/Variables/Guest_Generate_Coupon.php | 23 + includes/Variables/Guest_Last_Name.php | 27 + .../Variables/Membership_Date_Expires.php | 29 + .../Variables/Membership_Date_Started.php | 30 + includes/Variables/Membership_ID.php | 28 + includes/Variables/Membership_Meta.php | 37 + includes/Variables/Membership_Plan_ID.php | 30 + includes/Variables/Membership_Plan_Name.php | 31 + includes/Variables/Membership_Renewal_URL.php | 29 + includes/Variables/Membership_Status.php | 28 + includes/Variables/Order_Admin_Url.php | 36 + includes/Variables/Order_Billing_Address.php | 27 + includes/Variables/Order_Billing_Phone.php | 27 + includes/Variables/Order_Cross_Sells.php | 59 + includes/Variables/Order_Customer_Details.php | 30 + includes/Variables/Order_Customer_Note.php | 27 + includes/Variables/Order_Date.php | 29 + includes/Variables/Order_Date_Completed.php | 37 + includes/Variables/Order_Date_Paid.php | 37 + includes/Variables/Order_Date_Shipped.php | 46 + includes/Variables/Order_ID.php | 27 + includes/Variables/Order_Item_Attribute.php | 44 + includes/Variables/Order_Item_Meta.php | 34 + includes/Variables/Order_Item_Quantity.php | 27 + includes/Variables/Order_Items.php | 47 + includes/Variables/Order_Itemscount.php | 81 + includes/Variables/Order_Meta.php | 31 + includes/Variables/Order_Meta_Date.php | 37 + includes/Variables/Order_Note_Content.php | 27 + includes/Variables/Order_Number.php | 27 + includes/Variables/Order_Payment_Method.php | 41 + includes/Variables/Order_Payment_Url.php | 27 + includes/Variables/Order_Related_Products.php | 78 + includes/Variables/Order_Reorder_Url.php | 46 + includes/Variables/Order_Shipping_Address.php | 27 + .../Order_Shipping_Address_Line_1.php | 35 + .../Order_Shipping_Address_Line_2.php | 36 + includes/Variables/Order_Shipping_City.php | 35 + .../Variables/Order_Shipping_Company_Name.php | 36 + includes/Variables/Order_Shipping_Country.php | 61 + .../Variables/Order_Shipping_First_Name.php | 35 + .../Variables/Order_Shipping_Last_Name.php | 35 + includes/Variables/Order_Shipping_Method.php | 46 + .../Variables/Order_Shipping_Postcode.php | 35 + .../Variables/Order_Shipping_Provider.php | 32 + includes/Variables/Order_Shipping_State.php | 53 + includes/Variables/Order_Status.php | 33 + includes/Variables/Order_Subtotal.php | 33 + includes/Variables/Order_Total.php | 34 + includes/Variables/Order_Tracking_Number.php | 32 + includes/Variables/Order_Tracking_Url.php | 32 + includes/Variables/Order_View_Url.php | 29 + .../Variables/Product_Add_To_Cart_Url.php | 31 + includes/Variables/Product_Current_Price.php | 33 + includes/Variables/Product_Description.php | 31 + includes/Variables/Product_Featured_Image.php | 34 + includes/Variables/Product_ID.php | 27 + includes/Variables/Product_Meta.php | 41 + includes/Variables/Product_Meta_Date.php | 27 + includes/Variables/Product_Parent_Sku.php | 37 + includes/Variables/Product_Permalink.php | 27 + includes/Variables/Product_Regular_Price.php | 33 + .../Variables/Product_Short_Description.php | 30 + includes/Variables/Product_Sku.php | 27 + includes/Variables/Product_Title.php | 27 + includes/Variables/Refund_Amount.php | 36 + includes/Variables/Refund_Reason.php | 34 + includes/Variables/Review_Content.php | 27 + includes/Variables/Review_Rating.php | 27 + .../Sensei_Course_Certificate_URL.php | 56 + includes/Variables/Sensei_Course_ID.php | 33 + .../Variables/Sensei_Course_Results_URL.php | 36 + .../Variables/Sensei_Course_Start_Date.php | 53 + includes/Variables/Sensei_Course_Students.php | 94 + .../Sensei_Course_Students_Admin_URL.php | 48 + includes/Variables/Sensei_Course_Title.php | 33 + includes/Variables/Sensei_Course_URL.php | 33 + includes/Variables/Sensei_Group_ID.php | 33 + includes/Variables/Sensei_Group_Title.php | 33 + includes/Variables/Sensei_Lesson_ID.php | 33 + includes/Variables/Sensei_Lesson_Title.php | 33 + includes/Variables/Sensei_Lesson_URL.php | 33 + includes/Variables/Sensei_Quiz_Grade.php | 47 + includes/Variables/Sensei_Quiz_ID.php | 33 + includes/Variables/Sensei_Quiz_Passmark.php | 33 + includes/Variables/Sensei_Quiz_Title.php | 33 + includes/Variables/Sensei_Quiz_URL.php | 33 + includes/Variables/Sensei_Teacher_Email.php | 33 + .../Variables/Sensei_Teacher_First_Name.php | 33 + .../Variables/Sensei_Teacher_Full_Name.php | 33 + .../Variables/Sensei_Teacher_Last_Name.php | 33 + includes/Variables/Sensei_Teacher_User_ID.php | 33 + .../Variables/Sensei_Teacher_Username.php | 33 + includes/Variables/Shop/ShopUrl.php | 35 + includes/Variables/Shop_Admin_Email.php | 26 + includes/Variables/Shop_Current_Datetime.php | 28 + includes/Variables/Shop_Products.php | 269 + includes/Variables/Shop_Tagline.php | 26 + includes/Variables/Shop_Title.php | 25 + includes/Variables/Shop_Url.php | 26 + includes/Variables/Subscription_Admin_Url.php | 34 + .../Subscription_Billing_Address.php | 30 + ...Subscription_Change_Payment_Method_Url.php | 34 + .../Subscription_Early_Renewal_Url.php | 43 + includes/Variables/Subscription_End_Date.php | 32 + includes/Variables/Subscription_ID.php | 31 + .../Variables/Subscription_Item_Attribute.php | 24 + includes/Variables/Subscription_Item_Meta.php | 24 + .../Variables/Subscription_Item_Quantity.php | 23 + includes/Variables/Subscription_Items.php | 54 + .../Subscription_Last_Payment_Date.php | 32 + includes/Variables/Subscription_Meta.php | 35 + .../Subscription_Next_Payment_Date.php | 32 + .../Variables/Subscription_Payment_Count.php | 33 + .../Variables/Subscription_Payment_Method.php | 30 + .../Subscription_Retry_Payment_Date.php | 33 + .../Subscription_Shipping_Address.php | 30 + .../Variables/Subscription_Start_Date.php | 38 + includes/Variables/Subscription_Status.php | 31 + includes/Variables/Subscription_Total.php | 33 + .../Variables/Subscription_Trial_End_Date.php | 32 + .../Variables/Subscription_View_Order_Url.php | 32 + includes/Variables/Wishlist_Items.php | 41 + includes/Variables/Wishlist_Itemscount.php | 32 + includes/Variables/Wishlist_View_Link.php | 28 + includes/Variables_Processor.php | 179 + includes/WC_Emails.php | 75 + includes/Wishlist.php | 156 + includes/Wishlists.php | 177 + includes/WooCommerce_Blocks_Integration.php | 106 + includes/WooCommerce_Payments_Integration.php | 86 + includes/Workflow.php | 1789 ++++ includes/Workflow_Email.php | 411 + includes/Workflow_Fatal_Error_Monitor.php | 62 + includes/Workflow_Location.php | 258 + includes/Workflow_Query.php | 238 + includes/Workflows.php | 205 + includes/Workflows/Factory.php | 261 + includes/Workflows/Presets/ArrayPreset.php | 107 + .../Presets/Parser/ParserException.php | 11 + .../Workflows/Presets/Parser/PresetParser.php | 212 + .../Presets/Parser/PresetParserInterface.php | 25 + .../Workflows/Presets/PresetInterface.php | 50 + includes/Workflows/Presets/PresetService.php | 112 + .../Workflows/Presets/Storage/FileStorage.php | 187 + .../Presets/Storage/PHPFileStorage.php | 74 + .../Storage/PresetStorageInterface.php | 38 + .../Presets/Storage/StorageException.php | 23 + includes/Workflows/Status.php | 112 + .../Workflows/TimingDescriptionGenerator.php | 238 + .../ExcludedParsedVariable.php | 27 + .../VariableParsing/ParsedVariable.php | 56 + .../VariableParsing/VariableParser.php | 119 + includes/abstracts/addon.php | 274 + includes/compatibility-functions.php | 8 + includes/customer-functions.php | 120 + includes/deprecated.php | 11 + includes/helpers.php | 872 ++ includes/mailer-api.php | 109 + includes/product-functions.php | 144 + languages/automatewoo.pot | 7703 +++++++++++++++++ license.txt | 674 ++ presets/abandoned-cart-12-hours.php | 49 + presets/abandoned-cart-4-hours.php | 49 + presets/credit-cards-expiry-no-coupon.php | 41 + presets/credit-cards-expiry-with-coupon.php | 43 + ...ss-sell-first-time-customers-no-coupon.php | 53 + ...-sell-first-time-customers-with-coupon.php | 55 + .../cross-sell-related-products-no-coupon.php | 45 + ...ross-sell-related-products-with-coupon.php | 45 + .../cross-sell-repeat-customers-no-coupon.php | 56 + ...ross-sell-repeat-customers-with-coupon.php | 56 + presets/loyalty-birthday-with-coupon.php | 8 + ...rd-high-spending-customers-with-coupon.php | 47 + ...ty-reward-repeat-customers-with-coupon.php | 65 + ...ard-repeat-customers-with-custom-offer.php | 65 + presets/new-customers-welcome-no-coupon.php | 53 + presets/new-customers-welcome-with-coupon.php | 53 + ...ews-remind-customers-to-leave-a-review.php | 44 + .../reviews-thank-you-for-5-star-review.php | 53 + .../reviews-thank-you-multiple-reviews.php | 53 + presets/reviews-thank-you-with-coupon.php | 48 + ...ck-customers-recent-products-no-coupon.php | 49 + ...-customers-recent-products-with-coupon.php | 49 + presets/wishlist-remind-customers.php | 8 + .../communication-form-no-customer.php | 32 + .../communication-form.php | 42 + .../communication-preferences-list.php | 62 + .../communication-terms-text.php | 15 + .../communication-preferences/signup-form.php | 42 + templates/email/cart-table.php | 124 + templates/email/list-comma-separated.php | 28 + templates/email/order-table.php | 18 + templates/email/plain/email-footer.php | 20 + templates/email/plain/email-header.php | 14 + templates/email/product-grid-2-col.php | 63 + templates/email/product-grid-3-col.php | 63 + templates/email/product-rows.php | 58 + templates/email/review-grid-2-col.php | 55 + templates/email/review-grid-3-col.php | 55 + templates/email/review-rows.php | 49 + templates/email/styles.php | 172 + templates/honeypot-field.php | 22 + templates/optin-checkbox.php | 18 + vendor/autoload.php | 25 + vendor/composer/ClassLoader.php | 579 ++ vendor/composer/InstalledVersions.php | 359 + vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 973 +++ vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 11 + vendor/composer/autoload_real.php | 38 + vendor/composer/autoload_static.php | 1004 +++ vendor/composer/installed.json | 5 + vendor/composer/installed.php | 23 + vendor/composer/platform_check.php | 26 + wpml-config.xml | 16 + 1215 files changed, 119600 insertions(+) create mode 100644 admin/Analytics.php create mode 100644 admin/Analytics/Rest_API.php create mode 100644 admin/Analytics/Rest_API/Conversions/Controller.php create mode 100644 admin/Analytics/Rest_API/Conversions/Stats/Controller.php create mode 100644 admin/Analytics/Rest_API/Conversions/Stats/Store.php create mode 100644 admin/Analytics/Rest_API/Conversions/Store.php create mode 100644 admin/Analytics/Rest_API/Email_Tracking/Stats_Controller.php create mode 100644 admin/Analytics/Rest_API/Email_Tracking/Stats_Store.php create mode 100644 admin/Analytics/Rest_API/Log_Stats_Controller.php create mode 100644 admin/Analytics/Rest_API/Log_Stats_Store.php create mode 100644 admin/Analytics/Rest_API/Unsubscribers/Stats_Controller.php create mode 100644 admin/Analytics/Rest_API/Unsubscribers/Stats_Store.php create mode 100644 admin/Analytics/Rest_API/Upstream/Generic_Controller.php create mode 100644 admin/Analytics/Rest_API/Upstream/Generic_Query.php create mode 100644 admin/Analytics/Rest_API/Upstream/Generic_Stats_Controller.php create mode 100644 admin/Analytics/Rest_API/Upstream/Generic_Stats_Store.php create mode 100644 admin/Analytics/Rest_API/Workflow_Runs/Stats_Controller.php create mode 100644 admin/Analytics/Rest_API/Workflow_Runs/Stats_Store.php create mode 100644 admin/AssetData.php create mode 100644 admin/WCAdminConnectPages.php create mode 100644 admin/admin.php create mode 100644 admin/ajax.php create mode 100644 admin/assets/.externalized-admin.json create mode 100644 admin/assets/build/analytics-rtl.css create mode 100644 admin/assets/build/analytics.asset.php create mode 100644 admin/assets/build/analytics.css create mode 100644 admin/assets/build/analytics.js create mode 100644 admin/assets/build/index-rtl.css create mode 100644 admin/assets/build/index.asset.php create mode 100644 admin/assets/build/index.css create mode 100644 admin/assets/build/index.js create mode 100644 admin/assets/css/aw-main.css create mode 100644 admin/assets/css/aw-main.css.map create mode 100644 admin/assets/css/editor.css create mode 100644 admin/assets/css/editor.css.map create mode 100644 admin/assets/css/preview.css create mode 100644 admin/assets/css/preview.css.map create mode 100644 admin/assets/img/blank.gif create mode 100644 admin/assets/img/header-badge.svg create mode 100644 admin/assets/img/loader.svg create mode 100644 admin/assets/img/presets.svg create mode 100644 admin/assets/img/welcome-notice-robot.png create mode 100644 admin/assets/js/automatewoo.js create mode 100644 admin/assets/js/dashboard.js create mode 100644 admin/assets/js/min/automatewoo.min.js create mode 100644 admin/assets/js/min/automatewoo.min.js.map create mode 100644 admin/assets/js/min/dashboard.min.js create mode 100644 admin/assets/js/min/dashboard.min.js.map create mode 100644 admin/assets/js/min/modal.min.js create mode 100644 admin/assets/js/min/modal.min.js.map create mode 100644 admin/assets/js/min/preview.min.js create mode 100644 admin/assets/js/min/preview.min.js.map create mode 100644 admin/assets/js/min/rules.min.js create mode 100644 admin/assets/js/min/rules.min.js.map create mode 100644 admin/assets/js/min/settings.min.js create mode 100644 admin/assets/js/min/settings.min.js.map create mode 100644 admin/assets/js/min/sms-test.min.js create mode 100644 admin/assets/js/min/sms-test.min.js.map create mode 100644 admin/assets/js/min/tools.min.js create mode 100644 admin/assets/js/min/tools.min.js.map create mode 100644 admin/assets/js/min/tracks.min.js create mode 100644 admin/assets/js/min/tracks.min.js.map create mode 100644 admin/assets/js/min/validate.min.js create mode 100644 admin/assets/js/min/validate.min.js.map create mode 100644 admin/assets/js/min/variables.min.js create mode 100644 admin/assets/js/min/variables.min.js.map create mode 100644 admin/assets/js/min/workflows.min.js create mode 100644 admin/assets/js/min/workflows.min.js.map create mode 100644 admin/assets/js/modal.js create mode 100644 admin/assets/js/preview.js create mode 100644 admin/assets/js/rules.js create mode 100644 admin/assets/js/settings.js create mode 100644 admin/assets/js/sms-test.js create mode 100644 admin/assets/js/tools.js create mode 100644 admin/assets/js/tracks.js create mode 100644 admin/assets/js/validate.js create mode 100644 admin/assets/js/variables.js create mode 100644 admin/assets/js/workflows.js create mode 100644 admin/assets/src/analytics/index.js create mode 100644 admin/assets/src/analytics/register-reports.js create mode 100644 admin/assets/src/analytics/reports/conversions-table.js create mode 100644 admin/assets/src/analytics/reports/conversions.js create mode 100644 admin/assets/src/analytics/reports/email-tracking.js create mode 100644 admin/assets/src/analytics/reports/filters-config.js create mode 100644 admin/assets/src/analytics/reports/runs-by-date.js create mode 100644 admin/assets/src/base/components/card-row/index.js create mode 100644 admin/assets/src/base/components/index.js create mode 100644 admin/assets/src/base/components/placeholder/index.js create mode 100644 admin/assets/src/base/components/progress-bar/index.js create mode 100644 admin/assets/src/base/components/workflow-search/index.js create mode 100644 admin/assets/src/base/hooks/index.js create mode 100644 admin/assets/src/base/hooks/use-before-unload.js create mode 100644 admin/assets/src/base/utils.js create mode 100644 admin/assets/src/data/base/action-types.js create mode 100644 admin/assets/src/data/base/actions.js create mode 100644 admin/assets/src/data/base/reducer.js create mode 100644 admin/assets/src/data/base/selectors.js create mode 100644 admin/assets/src/data/constants.js create mode 100644 admin/assets/src/data/index.js create mode 100644 admin/assets/src/data/presets/action-types.js create mode 100644 admin/assets/src/data/presets/actions.js create mode 100644 admin/assets/src/data/presets/constants.js create mode 100644 admin/assets/src/data/presets/index.js create mode 100644 admin/assets/src/data/presets/reducer.js create mode 100644 admin/assets/src/data/presets/resolvers.js create mode 100644 admin/assets/src/data/presets/selectors.js create mode 100644 admin/assets/src/index.js create mode 100644 admin/assets/src/jsconfig.json create mode 100644 admin/assets/src/manual-workflow-runner/api-utils.js create mode 100644 admin/assets/src/manual-workflow-runner/find-items-step/data.js create mode 100644 admin/assets/src/manual-workflow-runner/find-items-step/high-volume-warning.js create mode 100644 admin/assets/src/manual-workflow-runner/find-items-step/index.js create mode 100644 admin/assets/src/manual-workflow-runner/find-items-step/item-finder.js create mode 100644 admin/assets/src/manual-workflow-runner/find-items-step/items-table.js create mode 100644 admin/assets/src/manual-workflow-runner/find-items-step/no-results.js create mode 100644 admin/assets/src/manual-workflow-runner/index.js create mode 100644 admin/assets/src/manual-workflow-runner/large-text-and-icon/index.js create mode 100644 admin/assets/src/manual-workflow-runner/next-button.js create mode 100644 admin/assets/src/manual-workflow-runner/queue-step/data.js create mode 100644 admin/assets/src/manual-workflow-runner/queue-step/index.js create mode 100644 admin/assets/src/manual-workflow-runner/select-workflow-step.js create mode 100644 admin/assets/src/manual-workflow-runner/utils.js create mode 100644 admin/assets/src/notice-tracking.js create mode 100644 admin/assets/src/page-tabs/index.js create mode 100644 admin/assets/src/presets/index.js create mode 100644 admin/assets/src/presets/list-item-guide.js create mode 100644 admin/assets/src/presets/list-item-placeholder.js create mode 100644 admin/assets/src/presets/list-item-preset.js create mode 100644 admin/assets/src/presets/list-item.js create mode 100644 admin/assets/src/presets/list-load-error.js create mode 100644 admin/assets/src/presets/list-placeholder.js create mode 100644 admin/assets/src/presets/list.js create mode 100644 admin/assets/src/presets/utils.js create mode 100644 admin/assets/src/settings.js create mode 100644 admin/assets/src/upstream/utils/async-requests.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-chart/index.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-chart/test/index.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-chart/utils.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-error/index.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-summary/index.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-summary/test/index.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-table/download-icon.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-table/index.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/analytics/components/report-table/utils.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/lib/currency-context.js create mode 100644 admin/assets/src/upstream/woocommerce-admin-analytics/utils/admin-settings.js create mode 100644 admin/assets/src/workflow-tab-handler.js create mode 100644 admin/assets/src/workflow-tinymce.js create mode 100644 admin/controllers.php create mode 100644 admin/controllers/base.php create mode 100644 admin/controllers/carts.php create mode 100644 admin/controllers/dashboard.php create mode 100644 admin/controllers/guests.php create mode 100644 admin/controllers/logs.php create mode 100644 admin/controllers/opt-ins.php create mode 100644 admin/controllers/preview.php create mode 100644 admin/controllers/queue.php create mode 100644 admin/controllers/reports.php create mode 100644 admin/controllers/settings.php create mode 100644 admin/controllers/tools.php create mode 100644 admin/coupons-list.php create mode 100644 admin/dashboard-widgets/abstract.php create mode 100644 admin/dashboard-widgets/analytics-abstract.php create mode 100644 admin/dashboard-widgets/analytics-conversions.php create mode 100644 admin/dashboard-widgets/analytics-email.php create mode 100644 admin/dashboard-widgets/analytics-workflows-run.php create mode 100644 admin/dashboard-widgets/chart-abstract.php create mode 100644 admin/dashboard-widgets/chart-conversions.php create mode 100644 admin/dashboard-widgets/chart-email.php create mode 100644 admin/dashboard-widgets/chart-workflows-run.php create mode 100644 admin/dashboard-widgets/key-figures.php create mode 100644 admin/dashboard-widgets/logs.php create mode 100644 admin/dashboard-widgets/queue.php create mode 100644 admin/dashboard-widgets/workflows.php create mode 100644 admin/data-layer-formatter.php create mode 100644 admin/json-search.php create mode 100644 admin/list-table.php create mode 100644 admin/reports-tabs/abstract.php create mode 100644 admin/reports-tabs/conversions-list.php create mode 100644 admin/reports-tabs/conversions.php create mode 100644 admin/reports-tabs/email-tracking.php create mode 100644 admin/reports-tabs/runs-by-date.php create mode 100644 admin/reports/abstract-graph.php create mode 100644 admin/reports/carts.php create mode 100644 admin/reports/conversions-list.php create mode 100644 admin/reports/conversions.php create mode 100644 admin/reports/email-tracking.php create mode 100644 admin/reports/guests.php create mode 100644 admin/reports/logs.php create mode 100644 admin/reports/opt-ins.php create mode 100644 admin/reports/queue.php create mode 100644 admin/reports/runs-by-date.php create mode 100644 admin/settings-tabs/abstract.php create mode 100644 admin/settings-tabs/active-campaign.php create mode 100644 admin/settings-tabs/bitly.php create mode 100644 admin/settings-tabs/campaign-monitor.php create mode 100644 admin/settings-tabs/carts.php create mode 100644 admin/settings-tabs/general.php create mode 100644 admin/settings-tabs/mailchimp.php create mode 100644 admin/settings-tabs/status.php create mode 100644 admin/settings-tabs/twilio.php create mode 100644 admin/user-tags-export.php create mode 100644 admin/views/action-fields.php create mode 100644 admin/views/action.php create mode 100644 admin/views/data-upgrade-prompt.php create mode 100644 admin/views/email-preview-loader.php create mode 100644 admin/views/email-preview-ui.php create mode 100644 admin/views/hoverable-date.php create mode 100644 admin/views/js-workflow-preset-alert.php create mode 100644 admin/views/js-workflow-templates.php create mode 100755 admin/views/meta-box-actions.php create mode 100755 admin/views/meta-box-manual-workflow.php create mode 100755 admin/views/meta-box-options.php create mode 100755 admin/views/meta-box-rules.php create mode 100755 admin/views/meta-box-save.php create mode 100755 admin/views/meta-box-timing.php create mode 100755 admin/views/meta-box-trigger.php create mode 100755 admin/views/meta-box-variables.php create mode 100644 admin/views/modal-cart-info.php create mode 100644 admin/views/modal-log-info.php create mode 100644 admin/views/modal-queued-event-info.php create mode 100644 admin/views/modal-variable-info.php create mode 100644 admin/views/page-dashboard.php create mode 100644 admin/views/page-data-upgrade.php create mode 100644 admin/views/page-guest-details.php create mode 100644 admin/views/page-heading.php create mode 100644 admin/views/page-reports.php create mode 100644 admin/views/page-settings.php create mode 100644 admin/views/page-table-with-sidebar.php create mode 100644 admin/views/page-tools-form-confirm.php create mode 100644 admin/views/page-tools-form.php create mode 100644 admin/views/page-tools-list.php create mode 100644 admin/views/rules.php create mode 100644 admin/views/settings-form.php create mode 100644 admin/views/simple-notice.php create mode 100644 admin/views/sms-test-twilio.php create mode 100644 admin/views/system-check.php create mode 100644 admin/views/tool-header.php create mode 100644 admin/views/trigger-fields.php create mode 100644 admin/views/welcome-notice.php create mode 100644 admin/workflow-edit.php create mode 100644 admin/workflow-list.php create mode 100644 assets/css/automatewoo-communication-page.css create mode 100644 assets/css/automatewoo-communication-page.css.map create mode 100644 assets/css/automatewoo-main.css create mode 100644 assets/css/automatewoo-main.css.map create mode 100644 assets/img/automatewoo-icon.png create mode 100644 assets/js/.externalized-blocks.json create mode 100644 assets/js/automatewoo-presubmit.js create mode 100644 assets/js/automatewoo-presubmit.min.js create mode 100644 assets/js/automatewoo-presubmit.min.js.map create mode 100644 assets/js/build/marketing-optin-block-frontend.asset.php create mode 100644 assets/js/build/marketing-optin-block-frontend.js create mode 100644 assets/js/build/marketing-optin-block-rtl.css create mode 100644 assets/js/build/marketing-optin-block.asset.php create mode 100644 assets/js/build/marketing-optin-block.css create mode 100644 assets/js/build/marketing-optin-block.js create mode 100644 assets/js/marketing-optin-block/attributes.js create mode 100644 assets/js/marketing-optin-block/block.js create mode 100644 assets/js/marketing-optin-block/block.json create mode 100644 assets/js/marketing-optin-block/edit.js create mode 100644 assets/js/marketing-optin-block/frontend.js create mode 100644 assets/js/marketing-optin-block/index.js create mode 100644 automatewoo.php create mode 100644 changelog.txt create mode 100644 includes/AbstractOptionsStore.php create mode 100644 includes/Abstract_Model_With_Meta_Table.php create mode 100644 includes/Action.php create mode 100644 includes/ActionScheduler/AW_AsyncRequest_QueueRunner.php create mode 100644 includes/ActionScheduler/ActionScheduler.php create mode 100644 includes/ActionScheduler/ActionSchedulerInterface.php create mode 100644 includes/ActionScheduler/AsyncActionRunner.php create mode 100644 includes/Actions.php create mode 100644 includes/Actions/ActionInterface.php create mode 100644 includes/Actions/Active_Campaign_Abstract.php create mode 100644 includes/Actions/Active_Campaign_Add_Tag.php create mode 100644 includes/Actions/Active_Campaign_Create_Contact.php create mode 100644 includes/Actions/Active_Campaign_Remove_Tag.php create mode 100644 includes/Actions/Active_Campaign_Update_Contact_Field.php create mode 100644 includes/Actions/Add_To_Mad_Mimi_List.php create mode 100644 includes/Actions/Campaign_Monitor_Abstract.php create mode 100644 includes/Actions/Campaign_Monitor_Add_Subscriber.php create mode 100644 includes/Actions/Campaign_Monitor_Remove_Subscriber.php create mode 100644 includes/Actions/Change_Post_Status.php create mode 100644 includes/Actions/Change_Workflow_Status.php create mode 100644 includes/Actions/Clear_Queued_Events.php create mode 100644 includes/Actions/Custom_Function.php create mode 100644 includes/Actions/Customer_Add_Tags.php create mode 100644 includes/Actions/Customer_Change_Role.php create mode 100644 includes/Actions/Customer_Remove_Tags.php create mode 100644 includes/Actions/Customer_Update_Meta.php create mode 100644 includes/Actions/Mailchimp_Abstract.php create mode 100644 includes/Actions/Mailchimp_Add_To_Group.php create mode 100644 includes/Actions/Mailchimp_Remove_From_Group.php create mode 100644 includes/Actions/Mailchimp_Subscribe.php create mode 100644 includes/Actions/Mailchimp_Unsubscribe.php create mode 100644 includes/Actions/Mailchimp_Update_Contact_Field.php create mode 100644 includes/Actions/Mailchimp_Update_Tags.php create mode 100644 includes/Actions/Mailpoet_Abstract.php create mode 100644 includes/Actions/Mailpoet_Subscribe.php create mode 100644 includes/Actions/Mailpoet_Unsubscribe.php create mode 100644 includes/Actions/Memberships_Abstract.php create mode 100644 includes/Actions/Memberships_Change_Plan.php create mode 100644 includes/Actions/Memberships_Change_Status.php create mode 100644 includes/Actions/Memberships_Delete_User_Membership.php create mode 100644 includes/Actions/Order_Add_Note.php create mode 100644 includes/Actions/Order_Change_Status.php create mode 100644 includes/Actions/Order_Item_Update_Meta.php create mode 100644 includes/Actions/Order_Resend_Email.php create mode 100644 includes/Actions/Order_Trigger_Action.php create mode 100644 includes/Actions/Order_Update_Customer_Shipping_Note.php create mode 100644 includes/Actions/Order_Update_Meta.php create mode 100644 includes/Actions/Points_Rewards_Add_Points.php create mode 100644 includes/Actions/Points_Rewards_Edit_Points_Abstract.php create mode 100644 includes/Actions/Points_Rewards_Remove_Points.php create mode 100644 includes/Actions/PreviewableInterface.php create mode 100644 includes/Actions/Send_Email.php create mode 100644 includes/Actions/Send_Email_Abstract.php create mode 100644 includes/Actions/Send_Email_Plain_Text.php create mode 100644 includes/Actions/Send_Email_Raw.php create mode 100644 includes/Actions/Send_SMS_Twilio.php create mode 100644 includes/Actions/Subscription_Add_Coupon.php create mode 100644 includes/Actions/Subscription_Add_Note.php create mode 100644 includes/Actions/Subscription_Add_Product.php create mode 100644 includes/Actions/Subscription_Change_Status.php create mode 100644 includes/Actions/Subscription_Edit_Coupon_Abstract.php create mode 100644 includes/Actions/Subscription_Edit_Product_Abstract.php create mode 100644 includes/Actions/Subscription_Remove_Coupon.php create mode 100644 includes/Actions/Subscription_Remove_Product.php create mode 100644 includes/Actions/Subscription_Send_Invoice.php create mode 100644 includes/Actions/Subscription_Update_Meta.php create mode 100644 includes/Actions/Subscriptions/AbstractEditDateItem.php create mode 100644 includes/Actions/Subscriptions/AbstractEditItem.php create mode 100644 includes/Actions/Subscriptions/AbstractEditShipping.php create mode 100644 includes/Actions/Subscriptions/AddShipping.php create mode 100644 includes/Actions/Subscriptions/RecalculateTaxes.php create mode 100644 includes/Actions/Subscriptions/RegenerateDownloadPermissions.php create mode 100644 includes/Actions/Subscriptions/RemoveShipping.php create mode 100644 includes/Actions/Subscriptions/UpdateCurrency.php create mode 100644 includes/Actions/Subscriptions/UpdateEndDate.php create mode 100644 includes/Actions/Subscriptions/UpdateNextPaymentDate.php create mode 100644 includes/Actions/Subscriptions/UpdateProduct.php create mode 100644 includes/Actions/Subscriptions/UpdateSchedule.php create mode 100644 includes/Actions/Subscriptions/UpdateShipping.php create mode 100644 includes/Actions/Subscriptions/UpdateTrialEndDate.php create mode 100644 includes/Actions/TestableInterface.php create mode 100644 includes/Actions/Update_Product_Meta.php create mode 100644 includes/Active_Triggers_Cache.php create mode 100644 includes/ActivityPanelInbox/SubscriptionsAddonDeactivatedNote.php create mode 100644 includes/ActivityPanelInbox/UpdateNote.php create mode 100644 includes/Addons.php create mode 100644 includes/AdminNotices.php create mode 100644 includes/AdminNotices/AbstractAdminNotice.php create mode 100644 includes/AdminNotices/AddonWelcome.php create mode 100644 includes/AdminNotices/AdminNoticeInterface.php create mode 100644 includes/AdminNotices/NewWorkflowHelperManager.php create mode 100644 includes/AdminNotices/UpdateNoticeManager.php create mode 100644 includes/AdminNotices/WcAdminDisabled.php create mode 100644 includes/AdminNotices/WelcomeNoticeManager.php create mode 100644 includes/Ajax.php create mode 100644 includes/Async_Events.php create mode 100644 includes/Async_Events/Abstract_Async_Event.php create mode 100644 includes/Async_Events/BookingCreated.php create mode 100644 includes/Async_Events/BookingStatusChanged.php create mode 100644 includes/Async_Events/MC4WP_Form_Success.php create mode 100644 includes/Async_Events/MembershipCreated.php create mode 100644 includes/Async_Events/Membership_Status_Changed.php create mode 100644 includes/Async_Events/Order_Created.php create mode 100644 includes/Async_Events/Order_Paid.php create mode 100644 includes/Async_Events/Order_Pending.php create mode 100644 includes/Async_Events/Order_Status_Changed.php create mode 100644 includes/Async_Events/Review_Approved.php create mode 100644 includes/Async_Events/Subscription_Created.php create mode 100644 includes/Async_Events/Subscription_Renewal_Payment_Complete.php create mode 100644 includes/Async_Events/Subscription_Renewal_Payment_Failed.php create mode 100644 includes/Async_Events/Subscription_Status_Changed.php create mode 100644 includes/Async_Events/UniqueEventsForRequestHelper.php create mode 100644 includes/Async_Events/User_Registered.php create mode 100644 includes/AutomateWoo.php create mode 100644 includes/AutomateWoo_Legacy.php create mode 100644 includes/Blocks/Marketing_Optin_Block.php create mode 100644 includes/Cache.php create mode 100644 includes/Cart.php create mode 100644 includes/Cart_Factory.php create mode 100644 includes/Cart_Item.php create mode 100644 includes/Cart_Query.php create mode 100644 includes/Carts.php create mode 100755 includes/Carts/CartRestorer.php create mode 100644 includes/Clean.php create mode 100644 includes/Communication_Account_Tab.php create mode 100644 includes/Communication_Page.php create mode 100644 includes/Constants.php create mode 100644 includes/Conversions.php create mode 100644 includes/Cookies.php create mode 100644 includes/Coupon_Generator.php create mode 100644 includes/Cron.php create mode 100644 includes/Customer.php create mode 100644 includes/Customer_Factory.php create mode 100644 includes/Customer_Query.php create mode 100644 includes/Customers.php create mode 100644 includes/DataTypes/AbstractDataType.php create mode 100644 includes/DataTypes/Booking.php create mode 100644 includes/DataTypes/Card.php create mode 100644 includes/DataTypes/Cart.php create mode 100644 includes/DataTypes/Comment.php create mode 100644 includes/DataTypes/Customer.php create mode 100644 includes/DataTypes/DataTypes.php create mode 100644 includes/DataTypes/Download.php create mode 100644 includes/DataTypes/Guest.php create mode 100644 includes/DataTypes/Membership.php create mode 100644 includes/DataTypes/Order.php create mode 100644 includes/DataTypes/OrderItem.php create mode 100644 includes/DataTypes/OrderNote.php create mode 100644 includes/DataTypes/Post.php create mode 100644 includes/DataTypes/Product.php create mode 100644 includes/DataTypes/ProductCategory.php create mode 100644 includes/DataTypes/ProductTag.php create mode 100644 includes/DataTypes/Refund.php create mode 100644 includes/DataTypes/Review.php create mode 100644 includes/DataTypes/SenseiCourse.php create mode 100644 includes/DataTypes/SenseiGroup.php create mode 100644 includes/DataTypes/SenseiLesson.php create mode 100644 includes/DataTypes/SenseiQuiz.php create mode 100644 includes/DataTypes/SenseiTeacher.php create mode 100644 includes/DataTypes/Shop.php create mode 100644 includes/DataTypes/Subscription.php create mode 100644 includes/DataTypes/SubscriptionItem.php create mode 100644 includes/DataTypes/User.php create mode 100644 includes/DataTypes/Wishlist.php create mode 100644 includes/DataTypes/Workflow.php create mode 100644 includes/Data_Layer.php create mode 100644 includes/DatabaseTables/Carts.php create mode 100644 includes/DatabaseTables/CustomerMeta.php create mode 100644 includes/DatabaseTables/Customers.php create mode 100644 includes/DatabaseTables/GuestMeta.php create mode 100644 includes/DatabaseTables/Guests.php create mode 100644 includes/DatabaseTables/LogMeta.php create mode 100644 includes/DatabaseTables/Logs.php create mode 100644 includes/DatabaseTables/Queue.php create mode 100644 includes/DatabaseTables/QueueMeta.php create mode 100644 includes/DatabaseUpdates/2.6.0.php create mode 100644 includes/DatabaseUpdates/2.6.1.php create mode 100644 includes/DatabaseUpdates/2.7.0.php create mode 100644 includes/DatabaseUpdates/2.9.7.php create mode 100644 includes/DatabaseUpdates/3.0.0.php create mode 100644 includes/DatabaseUpdates/3.5.0.php create mode 100644 includes/DatabaseUpdates/3.6.0.php create mode 100644 includes/DatabaseUpdates/4.0.0.php create mode 100644 includes/DatabaseUpdates/5.0.0.php create mode 100644 includes/DatabaseUpdates/5.1.0.php create mode 100644 includes/DatabaseUpdates/5.3.0.php create mode 100644 includes/DatabaseUpdates/6.0.0.php create mode 100644 includes/DatabaseUpdates/AbstractDatabaseUpdate.php create mode 100644 includes/Database_Table.php create mode 100644 includes/Database_Tables.php create mode 100644 includes/DateTime.php create mode 100644 includes/Download.php create mode 100644 includes/Emails.php create mode 100644 includes/Entity/Action.php create mode 100644 includes/Entity/NamedEntityWithOptions.php create mode 100644 includes/Entity/Rule.php create mode 100644 includes/Entity/RuleGroup.php create mode 100644 includes/Entity/ToArray.php create mode 100644 includes/Entity/Trigger.php create mode 100644 includes/Entity/Workflow.php create mode 100644 includes/Entity/WorkflowTiming.php create mode 100644 includes/Entity/WorkflowTimingBase.php create mode 100644 includes/Entity/WorkflowTimingDelayed.php create mode 100644 includes/Entity/WorkflowTimingFixed.php create mode 100644 includes/Entity/WorkflowTimingImmediate.php create mode 100644 includes/Entity/WorkflowTimingScheduled.php create mode 100644 includes/Entity/WorkflowTimingVariable.php create mode 100644 includes/Error.php create mode 100644 includes/Event_Helpers/Review_Posted.php create mode 100644 includes/Event_Helpers/Subscription_Status_Changed.php create mode 100644 includes/Event_Helpers/User_Registration.php create mode 100644 includes/Exception.php create mode 100644 includes/Exceptions/Exception.php create mode 100644 includes/Exceptions/InvalidArgument.php create mode 100644 includes/Exceptions/InvalidClass.php create mode 100644 includes/Exceptions/InvalidIntegration.php create mode 100644 includes/Exceptions/InvalidPath.php create mode 100644 includes/Exceptions/InvalidPreviewData.php create mode 100644 includes/Exceptions/InvalidStatus.php create mode 100644 includes/Exceptions/InvalidValue.php create mode 100644 includes/Exceptions/InvalidWorkflow.php create mode 100644 includes/Exceptions/UserFacingException.php create mode 100644 includes/Factories.php create mode 100644 includes/Factory.php create mode 100644 includes/Fields/Attribute.php create mode 100644 includes/Fields/Attribute_Term.php create mode 100644 includes/Fields/Before_After_Day.php create mode 100644 includes/Fields/BookingStatus.php create mode 100644 includes/Fields/Category.php create mode 100644 includes/Fields/Checkbox.php create mode 100644 includes/Fields/Countries.php create mode 100644 includes/Fields/Coupon.php create mode 100644 includes/Fields/Date.php create mode 100644 includes/Fields/EmailAddressWithName.php create mode 100644 includes/Fields/Email_Content.php create mode 100644 includes/Fields/Field.php create mode 100644 includes/Fields/HTML_Textarea.php create mode 100644 includes/Fields/Number.php create mode 100644 includes/Fields/Order_Note_Type.php create mode 100644 includes/Fields/Order_Status.php create mode 100644 includes/Fields/Payment_Gateway.php create mode 100644 includes/Fields/Positive_Number.php create mode 100644 includes/Fields/Price.php create mode 100644 includes/Fields/Product.php create mode 100644 includes/Fields/Searchable_Select_Abstract.php create mode 100644 includes/Fields/Select.php create mode 100644 includes/Fields/Sensei_Course.php create mode 100644 includes/Fields/Sensei_Group.php create mode 100644 includes/Fields/Sensei_Lesson.php create mode 100644 includes/Fields/Sensei_Question.php create mode 100644 includes/Fields/Sensei_Quiz.php create mode 100644 includes/Fields/Subscription_Products.php create mode 100644 includes/Fields/Subscription_Status.php create mode 100644 includes/Fields/Tag.php create mode 100644 includes/Fields/Taxonomy.php create mode 100644 includes/Fields/Taxonomy_Term.php create mode 100644 includes/Fields/Text.php create mode 100644 includes/Fields/Text_Area.php create mode 100644 includes/Fields/Time.php create mode 100644 includes/Fields/User_Role.php create mode 100644 includes/Fields/User_Tags.php create mode 100644 includes/Fields/Workflow.php create mode 100644 includes/Fields_Helper.php create mode 100644 includes/Format.php create mode 100644 includes/Formatters/Boolean_Formatter.php create mode 100644 includes/Formatters/Float_Formatter.php create mode 100644 includes/Formatters/Formattable.php create mode 100644 includes/Formatters/Int_String_Formatter.php create mode 100644 includes/Frontend.php create mode 100644 includes/Frontend_Endpoints.php create mode 100644 includes/Frontend_Endpoints/Login_Redirect.php create mode 100644 includes/Frontend_Form_Handler.php create mode 100644 includes/Guest.php create mode 100644 includes/Guest_Factory.php create mode 100644 includes/Guest_Query.php create mode 100644 includes/HPOS_Helper.php create mode 100644 includes/Hooks.php create mode 100644 includes/Installer.php create mode 100644 includes/Integration.php create mode 100644 includes/Integrations.php create mode 100644 includes/Integrations/ActiveCampaign.php create mode 100644 includes/Integrations/Bitly.php create mode 100644 includes/Integrations/Campaign_Monitor.php create mode 100644 includes/Integrations/Mad_Mimi.php create mode 100644 includes/Integrations/Mailchimp.php create mode 100644 includes/Integrations/Mailpoet.php create mode 100644 includes/Integrations/Twilio.php create mode 100644 includes/Jobs/AbandonedCarts.php create mode 100644 includes/Jobs/AbstractActionSchedulerJob.php create mode 100644 includes/Jobs/AbstractBatchedActionSchedulerJob.php create mode 100644 includes/Jobs/AbstractOneTimeActionSchedulerJob.php create mode 100644 includes/Jobs/AbstractRecurringBatchedActionSchedulerJob.php create mode 100644 includes/Jobs/AbstractRecurringOneTimeActionSchedulerJob.php create mode 100644 includes/Jobs/ActionSchedulerJobInterface.php create mode 100644 includes/Jobs/ActionSchedulerJobMonitor.php create mode 100644 includes/Jobs/BatchedActionSchedulerJobInterface.php create mode 100644 includes/Jobs/BatchedWorkflows.php create mode 100644 includes/Jobs/CheckGmtOffsetChange.php create mode 100644 includes/Jobs/CheckMidnightJob.php create mode 100644 includes/Jobs/CleanInactiveCarts.php create mode 100644 includes/Jobs/DeleteExpiredCoupons.php create mode 100644 includes/Jobs/DeleteFailedQueuedWorkflows.php create mode 100644 includes/Jobs/JobException.php create mode 100644 includes/Jobs/JobInterface.php create mode 100644 includes/Jobs/JobRegistry.php create mode 100644 includes/Jobs/JobRegistryInterface.php create mode 100644 includes/Jobs/JobService.php create mode 100644 includes/Jobs/Midnight.php create mode 100644 includes/Jobs/OneTimeActionSchedulerJobInterface.php create mode 100644 includes/Jobs/ProductGoesOnSale.php create mode 100644 includes/Jobs/RecurringJobInterface.php create mode 100644 includes/Jobs/RunQueuedWorkflows.php create mode 100644 includes/Jobs/SetupGuestCustomers.php create mode 100644 includes/Jobs/SetupRegisteredCustomers.php create mode 100644 includes/Jobs/StartOnHookInterface.php create mode 100644 includes/Jobs/ToolTaskRunner.php create mode 100644 includes/Jobs/Traits/ItemDeletionDate.php create mode 100644 includes/Jobs/Traits/ValidateItemAsIntegerId.php create mode 100644 includes/Jobs/WishlistItemOnSale.php create mode 100644 includes/Language.php create mode 100644 includes/LegacyAddonHandler.php create mode 100644 includes/Log.php create mode 100644 includes/Log_Factory.php create mode 100644 includes/Log_Query.php create mode 100644 includes/Logger.php create mode 100644 includes/Logic_Helper.php create mode 100644 includes/Logs.php create mode 100644 includes/Mailer.php create mode 100644 includes/Mailer_Abstract.php create mode 100644 includes/Mailer_Plain_Text.php create mode 100644 includes/Mailer_Raw_HTML.php create mode 100644 includes/Memberships_Helper.php create mode 100644 includes/Model.php create mode 100644 includes/Notifications.php create mode 100644 includes/Notifications/AbstractNotification.php create mode 100644 includes/Notifications/Addons/AbstractAddonCheck.php create mode 100644 includes/Notifications/Addons/BirthdaysCheck.php create mode 100644 includes/Notifications/Addons/ReferAFriendCheck.php create mode 100644 includes/Notifications/Integrations/AbstractIntegrationCheck.php create mode 100644 includes/Notifications/Integrations/ActiveCampaignCheck.php create mode 100644 includes/Notifications/Integrations/BitlyCheck.php create mode 100644 includes/Notifications/Integrations/CampaignMonitorCheck.php create mode 100644 includes/Notifications/Integrations/MailchimpCheck.php create mode 100644 includes/Notifications/Integrations/TwilioCheck.php create mode 100644 includes/Notifications/PHPMinVersionCheck.php create mode 100644 includes/Notifications/SystemChecks.php create mode 100644 includes/Notifications/WCMinVersionCheck.php create mode 100644 includes/Notifications/WelcomeNotification.php create mode 100644 includes/NotificationsInitializer.php create mode 100644 includes/Options.php create mode 100644 includes/OptionsStore.php create mode 100644 includes/Options_API.php create mode 100644 includes/Options_Abstract.php create mode 100644 includes/Order_Guest.php create mode 100644 includes/Order_Helper.php create mode 100644 includes/Order_Note.php create mode 100644 includes/Orders/Observers/CustomerLastPurchasedDateUpdater.php create mode 100644 includes/Orders/Observers/GuestMostRecentOrderUpdater.php create mode 100644 includes/Orders/Observers/Traits/HandleOrderDeleted.php create mode 100644 includes/Orders/Observers/Traits/HandleOrderStatusChanged.php create mode 100644 includes/Orders/StatusTransition.php create mode 100644 includes/Permissions.php create mode 100644 includes/Phone_Numbers.php create mode 100644 includes/Points_Rewards_Integration.php create mode 100644 includes/Post_Types.php create mode 100644 includes/PreSubmit.php create mode 100644 includes/Preview_Data.php create mode 100644 includes/Privacy.php create mode 100644 includes/Privacy_Abstract.php create mode 100644 includes/Privacy_Erasers.php create mode 100644 includes/Privacy_Exporters.php create mode 100644 includes/Privacy_Policy_Guide.php create mode 100644 includes/Proxies/Bookings.php create mode 100644 includes/Proxies/BookingsInterface.php create mode 100644 includes/Query_Abstract.php create mode 100644 includes/Query_Data_Layer_Abstract.php create mode 100644 includes/Queue_Manager.php create mode 100644 includes/Queue_Query.php create mode 100644 includes/Queued_Event.php create mode 100644 includes/Queued_Event_Factory.php create mode 100644 includes/Registry.php create mode 100644 includes/Registry/ItemConstructorArgsTrait.php create mode 100644 includes/Remote_Request.php create mode 100644 includes/Replace_Helper.php create mode 100644 includes/Rest_Api.php create mode 100644 includes/Rest_Api/Controllers/AbstractController.php create mode 100644 includes/Rest_Api/Controllers/ConversionsController.php create mode 100644 includes/Rest_Api/Controllers/LogsController.php create mode 100644 includes/Rest_Api/Controllers/ManualWorkflowRunner.php create mode 100644 includes/Rest_Api/Controllers/WorkflowPresets.php create mode 100644 includes/Rest_Api/Controllers/Workflows.php create mode 100644 includes/Rest_Api/Schema/Context.php create mode 100644 includes/Rest_Api/Schema/LogSchema.php create mode 100644 includes/Rest_Api/Schema/WorkflowSchema.php create mode 100644 includes/Rest_Api/Utilities/Controller_Namespace.php create mode 100644 includes/Rest_Api/Utilities/CreateUpdateWorkflow.php create mode 100644 includes/Rest_Api/Utilities/DateHelper.php create mode 100644 includes/Rest_Api/Utilities/DeleteWorkflow.php create mode 100644 includes/Rest_Api/Utilities/GetWorkflow.php create mode 100644 includes/Rest_Api/Utilities/Pagination.php create mode 100644 includes/Rest_Api/Utilities/RestException.php create mode 100644 includes/Review.php create mode 100644 includes/Review_Factory.php create mode 100644 includes/RuleQuickFilters/ClauseGenerator.php create mode 100644 includes/RuleQuickFilters/Clauses/AbstractClause.php create mode 100644 includes/RuleQuickFilters/Clauses/ArrayClause.php create mode 100644 includes/RuleQuickFilters/Clauses/ClauseInterface.php create mode 100644 includes/RuleQuickFilters/Clauses/DateTimeClause.php create mode 100644 includes/RuleQuickFilters/Clauses/NoOpClause.php create mode 100644 includes/RuleQuickFilters/Clauses/NumericClause.php create mode 100644 includes/RuleQuickFilters/Clauses/SetClause.php create mode 100644 includes/RuleQuickFilters/Clauses/StringClause.php create mode 100644 includes/RuleQuickFilters/Queries/AbstractPostDatastoreType.php create mode 100644 includes/RuleQuickFilters/Queries/AbstractQuery.php create mode 100644 includes/RuleQuickFilters/Queries/DatastoreTypeInterface.php create mode 100644 includes/RuleQuickFilters/Queries/OrderHighPerformanceDatastoreType.php create mode 100644 includes/RuleQuickFilters/Queries/OrderPostDatastoreType.php create mode 100644 includes/RuleQuickFilters/Queries/OrderQuery.php create mode 100644 includes/RuleQuickFilters/Queries/QueryInterface.php create mode 100644 includes/RuleQuickFilters/Queries/SubscriptionHighPerformanceDatastoreType.php create mode 100644 includes/RuleQuickFilters/Queries/SubscriptionPostDatastoreType.php create mode 100644 includes/RuleQuickFilters/Queries/SubscriptionQuery.php create mode 100644 includes/RuleQuickFilters/QueryLoader.php create mode 100644 includes/Rules.php create mode 100644 includes/Rules/Abstract_Bool.php create mode 100644 includes/Rules/Abstract_Date.php create mode 100644 includes/Rules/Abstract_Meta.php create mode 100644 includes/Rules/Abstract_Number.php create mode 100644 includes/Rules/Abstract_Object.php create mode 100644 includes/Rules/Abstract_Select.php create mode 100644 includes/Rules/Abstract_Select_Single.php create mode 100644 includes/Rules/Abstract_Sensei_Rule.php create mode 100644 includes/Rules/Abstract_String.php create mode 100644 includes/Rules/CartItemCount.php create mode 100644 includes/Rules/CartTotal.php create mode 100644 includes/Rules/Cart_Coupons.php create mode 100644 includes/Rules/Cart_Created_Date.php create mode 100644 includes/Rules/Cart_Item_Categories.php create mode 100644 includes/Rules/Cart_Item_Tags.php create mode 100644 includes/Rules/Cart_Items.php create mode 100644 includes/Rules/Customer_2nd_Last_Order_Date.php create mode 100644 includes/Rules/Customer_Account_Created_Date.php create mode 100644 includes/Rules/Customer_Active_Membership_Plans.php create mode 100644 includes/Rules/Customer_City.php create mode 100644 includes/Rules/Customer_Company.php create mode 100644 includes/Rules/Customer_Country.php create mode 100644 includes/Rules/Customer_Email.php create mode 100644 includes/Rules/Customer_First_Order_Date.php create mode 100644 includes/Rules/Customer_Has_Active_Subscription.php create mode 100644 includes/Rules/Customer_Is_Guest.php create mode 100644 includes/Rules/Customer_Is_Mailchimp_Subscriber.php create mode 100644 includes/Rules/Customer_Last_Order_Date.php create mode 100644 includes/Rules/Customer_Last_Review_Date.php create mode 100644 includes/Rules/Customer_Meta.php create mode 100644 includes/Rules/Customer_Order_Count.php create mode 100644 includes/Rules/Customer_Order_Statuses.php create mode 100644 includes/Rules/Customer_Phone.php create mode 100644 includes/Rules/Customer_Postcode.php create mode 100644 includes/Rules/Customer_Purchased_Categories.php create mode 100644 includes/Rules/Customer_Purchased_Products.php create mode 100644 includes/Rules/Customer_Review_Count.php create mode 100644 includes/Rules/Customer_Role.php create mode 100644 includes/Rules/Customer_Run_Count.php create mode 100644 includes/Rules/Customer_State.php create mode 100644 includes/Rules/Customer_State_Text_Match.php create mode 100644 includes/Rules/Customer_Tags.php create mode 100644 includes/Rules/Customer_Total_Spent.php create mode 100644 includes/Rules/GuestEmail.php create mode 100644 includes/Rules/GuestOrderCount.php create mode 100644 includes/Rules/GuestRunCount.php create mode 100644 includes/Rules/Interfaces/NonPrimaryDataTypeQuickFilterable.php create mode 100644 includes/Rules/Interfaces/QuickFilterable.php create mode 100644 includes/Rules/OrderHasCrossSells.php create mode 100644 includes/Rules/OrderIsCustomersFirst.php create mode 100644 includes/Rules/OrderIsPos.php create mode 100644 includes/Rules/OrderRunCount.php create mode 100644 includes/Rules/OrderShippingCountry.php create mode 100644 includes/Rules/OrderShippingMethodString.php create mode 100644 includes/Rules/OrderTotal.php create mode 100644 includes/Rules/Order_Billing_Country.php create mode 100644 includes/Rules/Order_Coupon_Count.php create mode 100644 includes/Rules/Order_Coupons.php create mode 100644 includes/Rules/Order_Coupons_Text_Match.php create mode 100644 includes/Rules/Order_Created_Date.php create mode 100644 includes/Rules/Order_Created_Via.php create mode 100644 includes/Rules/Order_Customer_Provided_Note.php create mode 100644 includes/Rules/Order_Is_Guest_Order.php create mode 100644 includes/Rules/Order_Is_Subscription_Parent.php create mode 100644 includes/Rules/Order_Is_Subscription_Renewal.php create mode 100644 includes/Rules/Order_Item_Categories.php create mode 100644 includes/Rules/Order_Item_Count.php create mode 100644 includes/Rules/Order_Item_Meta.php create mode 100644 includes/Rules/Order_Item_Product.php create mode 100644 includes/Rules/Order_Item_Quantity.php create mode 100644 includes/Rules/Order_Item_Subtotal.php create mode 100644 includes/Rules/Order_Item_Tags.php create mode 100644 includes/Rules/Order_Item_Tax_Total.php create mode 100644 includes/Rules/Order_Item_Total.php create mode 100644 includes/Rules/Order_Items.php create mode 100644 includes/Rules/Order_Items_Text_Match.php create mode 100644 includes/Rules/Order_Line_Count.php create mode 100644 includes/Rules/Order_Meta.php create mode 100644 includes/Rules/Order_Paid_Date.php create mode 100644 includes/Rules/Order_Payment_Gateway.php create mode 100644 includes/Rules/Order_Shipping_Method.php create mode 100644 includes/Rules/Order_Status.php create mode 100644 includes/Rules/Order_Subscription_Failed_Automatic_Payment_Retry_Count.php create mode 100644 includes/Rules/Order_Subscription_Order_Type.php create mode 100644 includes/Rules/Points_Rewards_Customer_Points.php create mode 100644 includes/Rules/Preloaded_Select_Rule_Abstract.php create mode 100644 includes/Rules/Product.php create mode 100644 includes/Rules/Product_Categories.php create mode 100644 includes/Rules/Product_Select_Rule_Abstract.php create mode 100644 includes/Rules/Review_Rating.php create mode 100644 includes/Rules/Rule.php create mode 100644 includes/Rules/Searchable_Select_Rule_Abstract.php create mode 100644 includes/Rules/Select_Rule_Abstract.php create mode 100644 includes/Rules/Sensei_Have_Failed_Quiz.php create mode 100644 includes/Rules/Sensei_Have_Not_Completed_Course.php create mode 100644 includes/Rules/Sensei_Have_Not_Completed_Lesson.php create mode 100644 includes/Rules/Sensei_Have_Not_Started_First_Lesson.php create mode 100644 includes/Rules/Sensei_Have_Not_Yet_Taken_Quiz.php create mode 100644 includes/Rules/Sensei_Have_Passed_Quiz.php create mode 100644 includes/Rules/ShopCurrentDateTime.php create mode 100644 includes/Rules/SubscriptionPaymentCount.php create mode 100644 includes/Rules/Subscription_Can_Renew_Early.php create mode 100644 includes/Rules/Subscription_Coupon_Count.php create mode 100644 includes/Rules/Subscription_Coupons.php create mode 100644 includes/Rules/Subscription_Coupons_Text_Match.php create mode 100644 includes/Rules/Subscription_Created_Date.php create mode 100644 includes/Rules/Subscription_End_Date.php create mode 100644 includes/Rules/Subscription_Has_Payment_Method.php create mode 100644 includes/Rules/Subscription_Item_Categories.php create mode 100644 includes/Rules/Subscription_Items.php create mode 100644 includes/Rules/Subscription_Last_Payment_Date.php create mode 100644 includes/Rules/Subscription_Meta.php create mode 100644 includes/Rules/Subscription_Next_Payment_Date.php create mode 100644 includes/Rules/Subscription_Payment_Method.php create mode 100644 includes/Rules/Subscription_Requires_Manual_Renewal.php create mode 100644 includes/Rules/Subscription_Run_Count.php create mode 100644 includes/Rules/Subscription_Status.php create mode 100644 includes/Rules/Subscription_Trial_End_Date.php create mode 100644 includes/Rules/Utilities/ArrayQuickFilter.php create mode 100644 includes/Rules/Utilities/DataTypeConditions.php create mode 100644 includes/Rules/Utilities/DateQuickFilter.php create mode 100644 includes/Rules/Utilities/NumericQuickFilter.php create mode 100644 includes/Rules/Utilities/StringQuickFilter.php create mode 100644 includes/Rules/Workflow_Last_Customer_Run_Date.php create mode 100644 includes/Sensei_Workflow_Helper.php create mode 100644 includes/Session_Tracker.php create mode 100644 includes/Shipment_Tracking_Integration.php create mode 100644 includes/ShopDataItem.php create mode 100644 includes/Subscription_Workflow_Helper.php create mode 100644 includes/SystemChecks/AbstractSystemCheck.php create mode 100644 includes/SystemChecks/ActionSchedulerJobsRunning.php create mode 100644 includes/SystemChecks/DatabaseTablesExist.php create mode 100644 includes/System_Checks.php create mode 100644 includes/Temporary_Data.php create mode 100644 includes/Time_Helper.php create mode 100644 includes/Tools/Abstract.php create mode 100644 includes/Tools/Background_Processed_Abstract.php create mode 100644 includes/Tools/Guest_Eraser.php create mode 100644 includes/Tools/Optin_Importer.php create mode 100644 includes/Tools/Optout_Importer.php create mode 100644 includes/Tools/Reset_Workflow_Records.php create mode 100644 includes/Tools/ToolsService.php create mode 100644 includes/Tracking.php create mode 100644 includes/Traits/ArrayValidator.php create mode 100644 includes/Traits/IntegerValidator.php create mode 100644 includes/Traits/IntegrationValidator.php create mode 100644 includes/Traits/MailServiceAction.php create mode 100644 includes/Traits/NamedEntity.php create mode 100644 includes/Traits/OptionsEntity.php create mode 100644 includes/Traits/StringValidator.php create mode 100644 includes/Traits/TagField.php create mode 100644 includes/Trigger.php create mode 100644 includes/Triggers.php create mode 100644 includes/Triggers/Abandoned_Cart_Customer.php create mode 100644 includes/Triggers/Abandoned_Cart_Guest.php create mode 100644 includes/Triggers/Abandoned_Cart_User.php create mode 100644 includes/Triggers/AbstractBatchedDailyTrigger.php create mode 100644 includes/Triggers/AbstractManual.php create mode 100644 includes/Triggers/Abstract_Abandoned_Cart.php create mode 100644 includes/Triggers/Abstract_Downloadable_Content.php create mode 100644 includes/Triggers/Abstract_Memberships.php create mode 100644 includes/Triggers/Abstract_Order_Base.php create mode 100644 includes/Triggers/Abstract_Order_Status_Base.php create mode 100644 includes/Triggers/Abstract_Subscriptions.php create mode 100644 includes/Triggers/BatchedWorkflowInterface.php create mode 100644 includes/Triggers/BookingCreated.php create mode 100644 includes/Triggers/BookingStatusChanged.php create mode 100644 includes/Triggers/Customer_Before_Saved_Card_Expiry.php create mode 100644 includes/Triggers/Customer_New_Account.php create mode 100644 includes/Triggers/Customer_Opted_In.php create mode 100644 includes/Triggers/Customer_Opted_Out.php create mode 100644 includes/Triggers/Customer_Order_Count_Reaches.php create mode 100644 includes/Triggers/Customer_Total_Spend_Reaches.php create mode 100644 includes/Triggers/Customer_Win_Back.php create mode 100644 includes/Triggers/Downloadable_Product_Purchased.php create mode 100644 includes/Triggers/File_Downloaded.php create mode 100644 includes/Triggers/File_Not_Yet_Downloaded.php create mode 100644 includes/Triggers/Guest_Created.php create mode 100644 includes/Triggers/MC4WP_Form_Submission.php create mode 100644 includes/Triggers/ManualInterface.php create mode 100644 includes/Triggers/Membership_Created.php create mode 100644 includes/Triggers/Membership_Status_Changed.php create mode 100644 includes/Triggers/OrderManual.php create mode 100644 includes/Triggers/OrderNoteAddedEachLineItem.php create mode 100644 includes/Triggers/Order_Cancelled.php create mode 100644 includes/Triggers/Order_Completed.php create mode 100644 includes/Triggers/Order_Created.php create mode 100644 includes/Triggers/Order_Created_Each_Line_Item.php create mode 100644 includes/Triggers/Order_Note_Added.php create mode 100644 includes/Triggers/Order_On_Hold.php create mode 100644 includes/Triggers/Order_Paid.php create mode 100644 includes/Triggers/Order_Paid_Each_Line_Item.php create mode 100644 includes/Triggers/Order_Pending.php create mode 100644 includes/Triggers/Order_Processing.php create mode 100644 includes/Triggers/Order_Refunded.php create mode 100644 includes/Triggers/Order_Refunded_Manual.php create mode 100644 includes/Triggers/Order_Status_Changes.php create mode 100644 includes/Triggers/Order_Status_Changes_Each_Line_Item.php create mode 100644 includes/Triggers/Review_Posted.php create mode 100644 includes/Triggers/Sensei_Course_Completed.php create mode 100644 includes/Triggers/Sensei_Course_Completed_By_All_Students.php create mode 100644 includes/Triggers/Sensei_Course_Not_Yet_Completed.php create mode 100644 includes/Triggers/Sensei_Course_Signed_Up.php create mode 100644 includes/Triggers/Sensei_Lesson_Completed.php create mode 100644 includes/Triggers/Sensei_Lesson_Started.php create mode 100644 includes/Triggers/Sensei_Quiz_Completed.php create mode 100644 includes/Triggers/Sensei_Quiz_Failed.php create mode 100644 includes/Triggers/Sensei_Quiz_Passed.php create mode 100644 includes/Triggers/Sensei_Specific_Answer_Selected.php create mode 100644 includes/Triggers/Sensei_Student_Added_To_Group.php create mode 100644 includes/Triggers/Sensei_Student_Removed_From_Group.php create mode 100644 includes/Triggers/SubscriptionManual.php create mode 100644 includes/Triggers/Subscription_Before_End.php create mode 100644 includes/Triggers/Subscription_Before_Renewal.php create mode 100644 includes/Triggers/Subscription_Created.php create mode 100644 includes/Triggers/Subscription_Created_Each_Line_Item.php create mode 100644 includes/Triggers/Subscription_Note_Added.php create mode 100644 includes/Triggers/Subscription_Order_Created.php create mode 100644 includes/Triggers/Subscription_Order_Paid.php create mode 100644 includes/Triggers/Subscription_Order_Status_Changes.php create mode 100644 includes/Triggers/Subscription_Payment_Complete.php create mode 100644 includes/Triggers/Subscription_Payment_Failed.php create mode 100644 includes/Triggers/Subscription_Status_Changed.php create mode 100644 includes/Triggers/Subscription_Status_Changed_Each_Line_Item.php create mode 100644 includes/Triggers/Subscription_Trial_End.php create mode 100644 includes/Triggers/User_Purchases_From_Taxonomy_Term.php create mode 100644 includes/Triggers/User_Purchases_Product_Variation_With_Attribute.php create mode 100644 includes/Triggers/Utilities/BookingDataLayer.php create mode 100644 includes/Triggers/Utilities/BookingsGroup.php create mode 100644 includes/Triggers/Utilities/CustomTimeOfDay.php create mode 100644 includes/Triggers/Utilities/HandleOrderNoteAdded.php create mode 100644 includes/Triggers/Utilities/OrderGroup.php create mode 100644 includes/Triggers/Utilities/SubscriptionGroup.php create mode 100644 includes/Triggers/Wishlist_Item_Added.php create mode 100644 includes/Triggers/Wishlist_Item_Goes_On_Sale.php create mode 100644 includes/Triggers/Wishlist_Reminder.php create mode 100644 includes/Triggers/Workflow_Times_Run_Reaches.php create mode 100644 includes/Usage_Tracking/Conversions.php create mode 100644 includes/Usage_Tracking/Event_Helper.php create mode 100644 includes/Usage_Tracking/Event_Tracker_Interface.php create mode 100644 includes/Usage_Tracking/Initializer.php create mode 100644 includes/Usage_Tracking/Install.php create mode 100644 includes/Usage_Tracking/Tracker.php create mode 100644 includes/Usage_Tracking/Tracks.php create mode 100644 includes/Usage_Tracking/Tracks_Interface.php create mode 100644 includes/Usage_Tracking/WorkflowTracksData.php create mode 100644 includes/Usage_Tracking/Workflows.php create mode 100644 includes/Usage_Tracking/readme.md create mode 100644 includes/User_Tags.php create mode 100644 includes/Variable.php create mode 100644 includes/Variables.php create mode 100644 includes/Variables/AbstractBookingTime.php create mode 100644 includes/Variables/AbstractTime.php create mode 100644 includes/Variables/Abstract_Datetime.php create mode 100644 includes/Variables/Abstract_Generate_Coupon.php create mode 100644 includes/Variables/Abstract_Meta.php create mode 100644 includes/Variables/Abstract_Price.php create mode 100644 includes/Variables/Abstract_Product_Display.php create mode 100644 includes/Variables/Abstract_Shipment_Tracking.php create mode 100644 includes/Variables/BookingCost.php create mode 100644 includes/Variables/BookingEndDate.php create mode 100644 includes/Variables/BookingEndTime.php create mode 100644 includes/Variables/BookingId.php create mode 100644 includes/Variables/BookingPersons.php create mode 100644 includes/Variables/BookingResource.php create mode 100644 includes/Variables/BookingStartDate.php create mode 100644 includes/Variables/BookingStartTime.php create mode 100644 includes/Variables/BookingStatus.php create mode 100644 includes/Variables/Card_Expiry_Month.php create mode 100644 includes/Variables/Card_Expiry_Year.php create mode 100644 includes/Variables/Card_Last4.php create mode 100644 includes/Variables/Card_Type.php create mode 100644 includes/Variables/CartId.php create mode 100644 includes/Variables/Cart_Item_Count.php create mode 100644 includes/Variables/Cart_Items.php create mode 100644 includes/Variables/Cart_Link.php create mode 100644 includes/Variables/Cart_Total.php create mode 100644 includes/Variables/Category_ID.php create mode 100644 includes/Variables/Category_Permalink.php create mode 100644 includes/Variables/Category_Title.php create mode 100644 includes/Variables/CommentAuthorName.php create mode 100644 includes/Variables/Comment_Author_IP.php create mode 100644 includes/Variables/Comment_Content.php create mode 100644 includes/Variables/Comment_ID.php create mode 100644 includes/Variables/Customer_Address_Line_1.php create mode 100644 includes/Variables/Customer_Address_Line_2.php create mode 100644 includes/Variables/Customer_City.php create mode 100644 includes/Variables/Customer_Company.php create mode 100644 includes/Variables/Customer_Country.php create mode 100644 includes/Variables/Customer_Email.php create mode 100644 includes/Variables/Customer_First_Name.php create mode 100644 includes/Variables/Customer_Full_Name.php create mode 100644 includes/Variables/Customer_Generate_Coupon.php create mode 100644 includes/Variables/Customer_Last_Name.php create mode 100644 includes/Variables/Customer_Meta.php create mode 100644 includes/Variables/Customer_Order_Count.php create mode 100644 includes/Variables/Customer_Phone.php create mode 100644 includes/Variables/Customer_Points.php create mode 100644 includes/Variables/Customer_Postcode.php create mode 100644 includes/Variables/Customer_State.php create mode 100644 includes/Variables/Customer_Tags.php create mode 100644 includes/Variables/Customer_Total_Spent.php create mode 100644 includes/Variables/Customer_Unsubscribe_URL.php create mode 100644 includes/Variables/Customer_User_ID.php create mode 100644 includes/Variables/Customer_Username.php create mode 100644 includes/Variables/Download_File_Name.php create mode 100644 includes/Variables/Download_URL.php create mode 100644 includes/Variables/Guest_Email.php create mode 100644 includes/Variables/Guest_First_Name.php create mode 100644 includes/Variables/Guest_Generate_Coupon.php create mode 100644 includes/Variables/Guest_Last_Name.php create mode 100644 includes/Variables/Membership_Date_Expires.php create mode 100644 includes/Variables/Membership_Date_Started.php create mode 100644 includes/Variables/Membership_ID.php create mode 100644 includes/Variables/Membership_Meta.php create mode 100644 includes/Variables/Membership_Plan_ID.php create mode 100644 includes/Variables/Membership_Plan_Name.php create mode 100644 includes/Variables/Membership_Renewal_URL.php create mode 100644 includes/Variables/Membership_Status.php create mode 100644 includes/Variables/Order_Admin_Url.php create mode 100644 includes/Variables/Order_Billing_Address.php create mode 100644 includes/Variables/Order_Billing_Phone.php create mode 100644 includes/Variables/Order_Cross_Sells.php create mode 100644 includes/Variables/Order_Customer_Details.php create mode 100644 includes/Variables/Order_Customer_Note.php create mode 100644 includes/Variables/Order_Date.php create mode 100644 includes/Variables/Order_Date_Completed.php create mode 100644 includes/Variables/Order_Date_Paid.php create mode 100644 includes/Variables/Order_Date_Shipped.php create mode 100644 includes/Variables/Order_ID.php create mode 100644 includes/Variables/Order_Item_Attribute.php create mode 100644 includes/Variables/Order_Item_Meta.php create mode 100644 includes/Variables/Order_Item_Quantity.php create mode 100644 includes/Variables/Order_Items.php create mode 100644 includes/Variables/Order_Itemscount.php create mode 100644 includes/Variables/Order_Meta.php create mode 100644 includes/Variables/Order_Meta_Date.php create mode 100644 includes/Variables/Order_Note_Content.php create mode 100644 includes/Variables/Order_Number.php create mode 100644 includes/Variables/Order_Payment_Method.php create mode 100644 includes/Variables/Order_Payment_Url.php create mode 100644 includes/Variables/Order_Related_Products.php create mode 100644 includes/Variables/Order_Reorder_Url.php create mode 100644 includes/Variables/Order_Shipping_Address.php create mode 100644 includes/Variables/Order_Shipping_Address_Line_1.php create mode 100644 includes/Variables/Order_Shipping_Address_Line_2.php create mode 100644 includes/Variables/Order_Shipping_City.php create mode 100644 includes/Variables/Order_Shipping_Company_Name.php create mode 100644 includes/Variables/Order_Shipping_Country.php create mode 100644 includes/Variables/Order_Shipping_First_Name.php create mode 100644 includes/Variables/Order_Shipping_Last_Name.php create mode 100644 includes/Variables/Order_Shipping_Method.php create mode 100644 includes/Variables/Order_Shipping_Postcode.php create mode 100644 includes/Variables/Order_Shipping_Provider.php create mode 100644 includes/Variables/Order_Shipping_State.php create mode 100644 includes/Variables/Order_Status.php create mode 100644 includes/Variables/Order_Subtotal.php create mode 100644 includes/Variables/Order_Total.php create mode 100644 includes/Variables/Order_Tracking_Number.php create mode 100644 includes/Variables/Order_Tracking_Url.php create mode 100644 includes/Variables/Order_View_Url.php create mode 100644 includes/Variables/Product_Add_To_Cart_Url.php create mode 100644 includes/Variables/Product_Current_Price.php create mode 100644 includes/Variables/Product_Description.php create mode 100644 includes/Variables/Product_Featured_Image.php create mode 100644 includes/Variables/Product_ID.php create mode 100644 includes/Variables/Product_Meta.php create mode 100644 includes/Variables/Product_Meta_Date.php create mode 100644 includes/Variables/Product_Parent_Sku.php create mode 100644 includes/Variables/Product_Permalink.php create mode 100644 includes/Variables/Product_Regular_Price.php create mode 100644 includes/Variables/Product_Short_Description.php create mode 100644 includes/Variables/Product_Sku.php create mode 100644 includes/Variables/Product_Title.php create mode 100644 includes/Variables/Refund_Amount.php create mode 100644 includes/Variables/Refund_Reason.php create mode 100644 includes/Variables/Review_Content.php create mode 100644 includes/Variables/Review_Rating.php create mode 100644 includes/Variables/Sensei_Course_Certificate_URL.php create mode 100644 includes/Variables/Sensei_Course_ID.php create mode 100644 includes/Variables/Sensei_Course_Results_URL.php create mode 100644 includes/Variables/Sensei_Course_Start_Date.php create mode 100644 includes/Variables/Sensei_Course_Students.php create mode 100644 includes/Variables/Sensei_Course_Students_Admin_URL.php create mode 100644 includes/Variables/Sensei_Course_Title.php create mode 100644 includes/Variables/Sensei_Course_URL.php create mode 100644 includes/Variables/Sensei_Group_ID.php create mode 100644 includes/Variables/Sensei_Group_Title.php create mode 100644 includes/Variables/Sensei_Lesson_ID.php create mode 100644 includes/Variables/Sensei_Lesson_Title.php create mode 100644 includes/Variables/Sensei_Lesson_URL.php create mode 100644 includes/Variables/Sensei_Quiz_Grade.php create mode 100644 includes/Variables/Sensei_Quiz_ID.php create mode 100644 includes/Variables/Sensei_Quiz_Passmark.php create mode 100644 includes/Variables/Sensei_Quiz_Title.php create mode 100644 includes/Variables/Sensei_Quiz_URL.php create mode 100644 includes/Variables/Sensei_Teacher_Email.php create mode 100644 includes/Variables/Sensei_Teacher_First_Name.php create mode 100644 includes/Variables/Sensei_Teacher_Full_Name.php create mode 100644 includes/Variables/Sensei_Teacher_Last_Name.php create mode 100644 includes/Variables/Sensei_Teacher_User_ID.php create mode 100644 includes/Variables/Sensei_Teacher_Username.php create mode 100644 includes/Variables/Shop/ShopUrl.php create mode 100644 includes/Variables/Shop_Admin_Email.php create mode 100644 includes/Variables/Shop_Current_Datetime.php create mode 100644 includes/Variables/Shop_Products.php create mode 100644 includes/Variables/Shop_Tagline.php create mode 100644 includes/Variables/Shop_Title.php create mode 100644 includes/Variables/Shop_Url.php create mode 100644 includes/Variables/Subscription_Admin_Url.php create mode 100644 includes/Variables/Subscription_Billing_Address.php create mode 100644 includes/Variables/Subscription_Change_Payment_Method_Url.php create mode 100644 includes/Variables/Subscription_Early_Renewal_Url.php create mode 100644 includes/Variables/Subscription_End_Date.php create mode 100644 includes/Variables/Subscription_ID.php create mode 100644 includes/Variables/Subscription_Item_Attribute.php create mode 100644 includes/Variables/Subscription_Item_Meta.php create mode 100644 includes/Variables/Subscription_Item_Quantity.php create mode 100644 includes/Variables/Subscription_Items.php create mode 100644 includes/Variables/Subscription_Last_Payment_Date.php create mode 100644 includes/Variables/Subscription_Meta.php create mode 100644 includes/Variables/Subscription_Next_Payment_Date.php create mode 100644 includes/Variables/Subscription_Payment_Count.php create mode 100644 includes/Variables/Subscription_Payment_Method.php create mode 100644 includes/Variables/Subscription_Retry_Payment_Date.php create mode 100644 includes/Variables/Subscription_Shipping_Address.php create mode 100644 includes/Variables/Subscription_Start_Date.php create mode 100644 includes/Variables/Subscription_Status.php create mode 100644 includes/Variables/Subscription_Total.php create mode 100644 includes/Variables/Subscription_Trial_End_Date.php create mode 100644 includes/Variables/Subscription_View_Order_Url.php create mode 100644 includes/Variables/Wishlist_Items.php create mode 100644 includes/Variables/Wishlist_Itemscount.php create mode 100644 includes/Variables/Wishlist_View_Link.php create mode 100644 includes/Variables_Processor.php create mode 100644 includes/WC_Emails.php create mode 100644 includes/Wishlist.php create mode 100644 includes/Wishlists.php create mode 100644 includes/WooCommerce_Blocks_Integration.php create mode 100644 includes/WooCommerce_Payments_Integration.php create mode 100644 includes/Workflow.php create mode 100644 includes/Workflow_Email.php create mode 100644 includes/Workflow_Fatal_Error_Monitor.php create mode 100644 includes/Workflow_Location.php create mode 100644 includes/Workflow_Query.php create mode 100644 includes/Workflows.php create mode 100644 includes/Workflows/Factory.php create mode 100644 includes/Workflows/Presets/ArrayPreset.php create mode 100644 includes/Workflows/Presets/Parser/ParserException.php create mode 100644 includes/Workflows/Presets/Parser/PresetParser.php create mode 100644 includes/Workflows/Presets/Parser/PresetParserInterface.php create mode 100644 includes/Workflows/Presets/PresetInterface.php create mode 100644 includes/Workflows/Presets/PresetService.php create mode 100644 includes/Workflows/Presets/Storage/FileStorage.php create mode 100644 includes/Workflows/Presets/Storage/PHPFileStorage.php create mode 100644 includes/Workflows/Presets/Storage/PresetStorageInterface.php create mode 100644 includes/Workflows/Presets/Storage/StorageException.php create mode 100644 includes/Workflows/Status.php create mode 100644 includes/Workflows/TimingDescriptionGenerator.php create mode 100644 includes/Workflows/VariableParsing/ExcludedParsedVariable.php create mode 100644 includes/Workflows/VariableParsing/ParsedVariable.php create mode 100644 includes/Workflows/VariableParsing/VariableParser.php create mode 100644 includes/abstracts/addon.php create mode 100644 includes/compatibility-functions.php create mode 100644 includes/customer-functions.php create mode 100644 includes/deprecated.php create mode 100644 includes/helpers.php create mode 100644 includes/mailer-api.php create mode 100644 includes/product-functions.php create mode 100644 languages/automatewoo.pot create mode 100644 license.txt create mode 100644 presets/abandoned-cart-12-hours.php create mode 100644 presets/abandoned-cart-4-hours.php create mode 100644 presets/credit-cards-expiry-no-coupon.php create mode 100644 presets/credit-cards-expiry-with-coupon.php create mode 100644 presets/cross-sell-first-time-customers-no-coupon.php create mode 100644 presets/cross-sell-first-time-customers-with-coupon.php create mode 100644 presets/cross-sell-related-products-no-coupon.php create mode 100644 presets/cross-sell-related-products-with-coupon.php create mode 100644 presets/cross-sell-repeat-customers-no-coupon.php create mode 100644 presets/cross-sell-repeat-customers-with-coupon.php create mode 100644 presets/loyalty-birthday-with-coupon.php create mode 100644 presets/loyalty-reward-high-spending-customers-with-coupon.php create mode 100644 presets/loyalty-reward-repeat-customers-with-coupon.php create mode 100644 presets/loyalty-reward-repeat-customers-with-custom-offer.php create mode 100644 presets/new-customers-welcome-no-coupon.php create mode 100644 presets/new-customers-welcome-with-coupon.php create mode 100644 presets/reviews-remind-customers-to-leave-a-review.php create mode 100644 presets/reviews-thank-you-for-5-star-review.php create mode 100644 presets/reviews-thank-you-multiple-reviews.php create mode 100644 presets/reviews-thank-you-with-coupon.php create mode 100644 presets/win-back-customers-recent-products-no-coupon.php create mode 100644 presets/win-back-customers-recent-products-with-coupon.php create mode 100644 presets/wishlist-remind-customers.php create mode 100644 templates/communication-preferences/communication-form-no-customer.php create mode 100644 templates/communication-preferences/communication-form.php create mode 100644 templates/communication-preferences/communication-preferences-list.php create mode 100644 templates/communication-preferences/communication-terms-text.php create mode 100644 templates/communication-preferences/signup-form.php create mode 100644 templates/email/cart-table.php create mode 100644 templates/email/list-comma-separated.php create mode 100644 templates/email/order-table.php create mode 100644 templates/email/plain/email-footer.php create mode 100644 templates/email/plain/email-header.php create mode 100644 templates/email/product-grid-2-col.php create mode 100644 templates/email/product-grid-3-col.php create mode 100644 templates/email/product-rows.php create mode 100644 templates/email/review-grid-2-col.php create mode 100644 templates/email/review-grid-3-col.php create mode 100644 templates/email/review-rows.php create mode 100644 templates/email/styles.php create mode 100644 templates/honeypot-field.php create mode 100644 templates/optin-checkbox.php create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/composer/installed.php create mode 100644 vendor/composer/platform_check.php create mode 100644 wpml-config.xml diff --git a/admin/Analytics.php b/admin/Analytics.php new file mode 100644 index 0000000..e74c01e --- /dev/null +++ b/admin/Analytics.php @@ -0,0 +1,118 @@ + Reports. + * + * @since 5.6.1 + */ +class Analytics { + + /** + * Init. + */ + public static function init() { + add_action( 'init', array( __CLASS__, 'setup' ) ); + } + + /** + * Setup Analytics. + * Add report items and register scripts. + */ + public static function setup() { + if ( self::is_enabled() ) { + // Analytics init. + add_filter( 'woocommerce_analytics_report_menu_items', array( __CLASS__, 'add_report_menu_item' ) ); + add_action( 'admin_enqueue_scripts', array( __CLASS__, 'register_script' ) ); + add_action( 'admin_enqueue_scripts', array( __CLASS__, 'register_style' ) ); + } + } + + /** + * Add "Bundles" as a Analytics submenu item. + * + * @param array $report_pages Report page menu items. + * @return array + */ + public static function add_report_menu_item( $report_pages ) { + + $report_pages[] = array( + 'id' => 'automatewoo-analytics-runs-by-date', + 'title' => '' . __( 'Workflows', 'automatewoo' ), + 'parent' => 'woocommerce-analytics', + 'path' => '/analytics/automatewoo-runs-by-date', + ); + $report_pages[] = array( + 'id' => 'automatewoo-analytics-email-tracking', + 'title' => '' . __( 'Email & SMS Tracking', 'automatewoo' ), + 'parent' => 'woocommerce-analytics', + 'path' => '/analytics/automatewoo-email-tracking', + ); + $report_pages[] = array( + 'id' => 'automatewoo-analytics-conversions', + 'title' => '' . __( 'Conversions', 'automatewoo' ), + 'parent' => 'woocommerce-analytics', + 'path' => '/analytics/automatewoo-conversions', + ); + return $report_pages; + } + + /** + * Register analytics JS. + */ + public static function register_script() { + if ( ! PageController::is_admin_page() ) { + return; + } + + $script_asset = require AW()->admin_path( '/assets/build/analytics.asset.php' ); + + wp_register_script( + 'automatewoo-analytics', + AW()->admin_assets_url( '/build/analytics.js' ), + $script_asset['dependencies'], + $script_asset['version'], + true + ); + + // Load JS translations. + wp_set_script_translations( 'automatewoo-analytics', 'automatewoo', AW()->path( '/languages' ) ); + + // Enqueue script. + wp_enqueue_script( 'automatewoo-analytics' ); + } + + /** + * Register analytics CSS. + */ + public static function register_style() { + if ( PageController::is_admin_page() ) { + wp_enqueue_style( + 'automatewoo-analytics', + AW()->admin_assets_url( '/build/analytics.css' ), + [ 'wc-admin-app' ], + AW()->version + ); + } + } + + /** + * Whether or not the new Analytics reports are enabled. + * + * @return bool + */ + public static function is_enabled() { + $is_enabled = WC()->is_wc_admin_active(); + + /** + * Whether AutomateWoo's analytics reports should be added to the WooCommerce Analytics menu. + * + * @filter automatewoo/admin/analytics_enabled + */ + return (bool) apply_filters( 'automatewoo/admin/analytics_enabled', $is_enabled ); + } +} diff --git a/admin/Analytics/Rest_API.php b/admin/Analytics/Rest_API.php new file mode 100644 index 0000000..ee2e377 --- /dev/null +++ b/admin/Analytics/Rest_API.php @@ -0,0 +1,80 @@ + Reports. + * + * @since 5.6.3 + */ +class Rest_API { + + /** + * Init. + */ + public static function init() { + add_action( 'init', array( __CLASS__, 'setup' ) ); + } + + /** + * Setup Analytics. + * Register controllers and data stores. + */ + public static function setup() { + if ( self::is_enabled() ) { + + // REST API Controllers. + add_filter( 'woocommerce_admin_rest_controllers', array( __CLASS__, 'add_rest_api_controllers' ) ); + + // Register data stores. + add_filter( 'woocommerce_data_stores', array( __CLASS__, 'register_data_stores' ) ); + + } + } + + /** + * Whether or not the Rest APIs for Analytic reports are enabled. + * + * @return bool + */ + public static function is_enabled() { + return Analytics::is_enabled(); + } + + /** + * Adds Analytics REST contollers. + * To be used with `woocommerce_admin_rest_controllers` filter. + * + * @param array $controllers + * @return array Extended with AW Analytics controllers. + */ + public static function add_rest_api_controllers( $controllers ) { + $controllers[] = 'AutomateWoo\Admin\Analytics\Rest_API\Conversions\Controller'; + $controllers[] = 'AutomateWoo\Admin\Analytics\Rest_API\Conversions\Stats\Controller'; + $controllers[] = 'AutomateWoo\Admin\Analytics\Rest_API\Email_Tracking\Stats_Controller'; + $controllers[] = 'AutomateWoo\Admin\Analytics\Rest_API\Unsubscribers\Stats_Controller'; + $controllers[] = 'AutomateWoo\Admin\Analytics\Rest_API\Workflow_Runs\Stats_Controller'; + + return $controllers; + } + + /** + * Register Analytics data stores. + * To be used with `woocommerce_data_stores` filter. + * + * @param array $stores + * @return array Extended with AW Analytics stores. + */ + public static function register_data_stores( $stores ) { + $stores['report-conversions-list'] = 'AutomateWoo\Admin\Analytics\Rest_API\Conversions\Store'; + $stores['report-conversions-stats'] = 'AutomateWoo\Admin\Analytics\Rest_API\Conversions\Stats\Store'; + $stores['report-email-tracking-stats'] = 'AutomateWoo\Admin\Analytics\Rest_API\Email_Tracking\Data_Store'; + $stores['report-unsubscribers-stats'] = 'AutomateWoo\Admin\Analytics\Rest_API\Unsubscribers\Data_Store'; + $stores['report-workflow-runs-stats'] = 'AutomateWoo\Admin\Analytics\Rest_API\Workflow_Runs\Data_Store'; + + return $stores; + } +} diff --git a/admin/Analytics/Rest_API/Conversions/Controller.php b/admin/Analytics/Rest_API/Conversions/Controller.php new file mode 100644 index 0000000..c275f29 --- /dev/null +++ b/admin/Analytics/Rest_API/Conversions/Controller.php @@ -0,0 +1,226 @@ +get_type() ) { + $order = wc_get_order( $order->get_parent_id() ); + } + + if ( ! has_filter( 'woocommerce_order_number' ) ) { + return (string) $order->get_id(); + } + + return $order->get_order_number(); + } + + /** + * Get the order total with the related currency formatting. + * Returns the parent order total if the order is actually a refund. + * + * @param int $order_id Order ID. + * @return string|null + */ + protected function get_total_formatted( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order instanceof \WC_Order && ! $order instanceof \WC_Order_Refund ) { + return null; + } + + if ( 'shop_order_refund' === $order->get_type() ) { + $order = wc_get_order( $order->get_parent_id() ); + } + + return wp_strip_all_tags( html_entity_decode( $order->get_formatted_order_total() ), true ); + } + + + /** + * Get all reports. + * + * @param \WP_REST_Request $request Request data. + * @return \WP_REST_Response|\WP_Error + */ + public function get_items( $request ) { + $query_args = $this->prepare_reports_query( $request ); + $query = $this->construct_query( $query_args ); + try { + $report_data = $query->get_data(); + } catch ( ParameterException $e ) { + return new \WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + $data = array(); + + foreach ( $report_data->data as $orders_data ) { + $orders_data['order_number'] = $this->get_order_number( $orders_data['order_id'] ); + $orders_data['total_formatted'] = $this->get_total_formatted( $orders_data['order_id'] ); + $item = $this->prepare_item_for_response( (object) $orders_data, $request ); + $data[] = $this->prepare_response_for_collection( $item ); + } + + return $this->add_pagination_headers( + $request, + $data, + (int) $report_data->total, + (int) $report_data->page_no, + (int) $report_data->pages + ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_conversions_list', + 'type' => 'object', + 'properties' => array( + 'order_id' => array( + 'description' => __( 'Order ID.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'order_number' => array( + 'description' => __( 'Order Number.', 'automatewoo' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created' => array( + 'description' => __( "Date the order was created, in the site's timezone.", 'automatewoo' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_created_gmt' => array( + 'description' => __( 'Date the order was created, as GMT.', 'automatewoo' ), + 'type' => 'string', + 'format' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'customer_id' => array( + 'description' => __( 'Customer ID.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_sales' => array( + 'description' => __( 'Order total.', 'automatewoo' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'total_formatted' => array( + 'description' => __( 'Order total (formatted).', 'automatewoo' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'workflow_id' => array( + 'description' => __( 'Workflow ID which triggered the conversion.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'conversion_id' => array( + 'description' => __( 'Conversion log ID.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'extended_info' => array( + 'customer' => array( + 'type' => 'object', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Order customer information.', 'automatewoo' ), + ), + 'workflow' => array( + 'type' => 'object', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Workflow information.', 'automatewoo' ), + ), + 'conversion' => array( + 'type' => 'object', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Conversion information.', 'automatewoo' ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['extended_info'] = array( + 'description' => __( 'Add additional info about each conversion to the report.', 'automatewoo' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/admin/Analytics/Rest_API/Conversions/Stats/Controller.php b/admin/Analytics/Rest_API/Conversions/Stats/Controller.php new file mode 100644 index 0000000..9b4c863 --- /dev/null +++ b/admin/Analytics/Rest_API/Conversions/Stats/Controller.php @@ -0,0 +1,76 @@ + array( + 'description' => __( 'Converted order value.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'net_revenue' => array( + 'description' => __( 'Converted net sales.', 'automatewoo' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'orders_count' => array( + 'title' => __( 'Orders', 'automatewoo' ), + 'description' => __( 'Number of orders', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'indicator' => true, + ), + ); + } + /** + * Get the Conversions Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + $schema['title'] = 'report_conversions_stats'; + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/admin/Analytics/Rest_API/Conversions/Stats/Store.php b/admin/Analytics/Rest_API/Conversions/Stats/Store.php new file mode 100644 index 0000000..d08323e --- /dev/null +++ b/admin/Analytics/Rest_API/Conversions/Stats/Store.php @@ -0,0 +1,213 @@ + 'strval', + 'date_end' => 'strval', + 'orders_count' => 'intval', + 'total_sales' => 'floatval', + 'net_revenue' => 'floatval', + ); + + /** + * Data store context used to pass to filters. + * + * @var string + */ + protected $context = 'conversions_stats'; + + /** + * Sets `meta_table` details according to the HPOS being enabled or not. + */ + public function __construct() { + global $wpdb; + parent::__construct(); + + // Set meta table details according to the HPOS being enabled or not. + if ( HPOS_Helper::is_HPOS_enabled() ) { + $this->meta_table = (object) array( + 'name' => $wpdb->prefix . 'wc_orders_meta', + 'id_column' => 'order_id', + ); + } else { + $this->meta_table = (object) array( + 'name' => $wpdb->prefix . 'postmeta', + 'id_column' => 'post_id', + ); + } + } + + /** + * Assign report columns. + */ + protected function assign_report_columns() { + $table_name = self::get_db_table_name(); + + $this->report_columns = array( + 'orders_count' => "SUM( CASE WHEN {$table_name}.parent_id = 0 THEN 1 ELSE 0 END ) as orders_count", + 'total_sales' => "SUM({$table_name}.total_sales) AS total_sales", + 'net_revenue' => "SUM({$table_name}.net_total) AS net_revenue", + ); + } + + /** + * Updates the totals and intervals database queries with `workflows` parameter. + * + * @param array $query_args Query arguments supplied by the user. + */ + protected function update_sql_query_params( $query_args ) { + parent::update_sql_query_params( $query_args ); + + // Filter selected workflows. + if ( ! empty( $query_args['workflows'] ) ) { + $included_workflows = implode( ',', wp_parse_id_list( $query_args['workflows'] ) ); + $workflows_where_clause = " AND {$this->meta_table->name}.meta_value IN ({$included_workflows})"; + + $this->total_query->add_sql_clause( 'where', $workflows_where_clause ); + $this->interval_query->add_sql_clause( 'where', $workflows_where_clause ); + } + } + + + /** + * Returns the report data based on normalized parameters. + * Will be called by `get_data` if there is no data in cache. + * + * @see get_data + * @param array $query_args Query parameters. + * @param array $params Query limit parameters. + * @param stdClass $data Reference to the data object to fill. + * @param int $expected_interval_count Number of expected intervals. + * @return stdClass|WP_Error Data object `{ totals: *, intervals: array, total: int, pages: int, page_no: int }`, or error. + */ + public function get_noncached_stats_data( $query_args, $params, &$data, $expected_interval_count ) { + global $wpdb; + $table_name = self::get_db_table_name(); + + $this->initialize_queries(); + // Set up where, and where_time clauses. + $this->update_sql_query_params( $query_args ); + + $selections = $this->selected_columns( $query_args ); + $where_time = $this->get_sql_clause( 'where_time' ); + $params = $this->get_limit_sql_params( $query_args ); + + $this->total_query->add_sql_clause( 'select', $selections ); + $this->total_query->add_sql_clause( 'where_time', $where_time ); + $totals = $wpdb->get_results( + $this->total_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); + if ( null === $totals ) { + return new WP_Error( 'automatewoo_conversions_result_failed', __( 'Sorry, fetching conversions data failed.', 'automatewoo' ) ); + } + + $totals = (object) $this->cast_numbers( $totals[0] ); + + $this->interval_query->add_sql_clause( 'where_time', $where_time ); + $db_intervals = $wpdb->get_col( + $this->interval_query->get_query_statement() // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ); + + $db_interval_count = count( $db_intervals ); + + $this->update_intervals_sql_params( $query_args, $db_interval_count, $expected_interval_count, $table_name ); + $this->interval_query->add_sql_clause( 'order_by', $this->get_sql_clause( 'order_by' ) ); + $this->interval_query->add_sql_clause( 'limit', $this->get_sql_clause( 'limit' ) ); + $this->interval_query->add_sql_clause( 'select', ", MAX({$table_name}.date_created) AS datetime_anchor" ); + if ( '' !== $selections ) { + $this->interval_query->add_sql_clause( 'select', ', ' . $selections ); + } + $intervals = $wpdb->get_results( + $this->interval_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); // phpcs:ignore cache ok, DB call ok, unprepared SQL ok. + + if ( null === $intervals ) { + return new WP_Error( 'automatewoo_conversions_result_failed', __( 'Sorry, fetching conversions data failed.', 'automatewoo' ) ); + } + + $data->totals = $totals; + $data->intervals = $intervals; + + if ( TimeInterval::intervals_missing( $expected_interval_count, $db_interval_count, $params['per_page'], $query_args['page'], $query_args['order'], $query_args['orderby'], count( $intervals ) ) ) { + $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data ); + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + $this->remove_extra_records( $data, $query_args['page'], $params['per_page'], $db_interval_count, $expected_interval_count, $query_args['orderby'], $query_args['order'] ); + } else { + $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $data->intervals ); + } + + $this->create_interval_subtotals( $data->intervals ); + + return $data; + } + + /** + * Initialize query objects. + */ + protected function initialize_queries() { + parent::initialize_queries(); + + $order_stats_table_name = self::get_db_table_name(); + $join_clause = "JOIN {$this->meta_table->name} ON ( {$order_stats_table_name}.order_id = {$this->meta_table->name}.{$this->meta_table->id_column} AND {$this->meta_table->name}.meta_key = '_aw_conversion' )"; + + // We hardcode paid statuses only. + // This is to match the legacy Reports behavior, + // but is inconsistent with set of statuses used by WC Core analytics. + // https://github.com/woocommerce/automatewoo/issues/1266 + $allowed_statuses = array_map( 'aw_add_order_status_prefix', wc_get_is_paid_statuses() ); + $status_where_clause = " AND {$order_stats_table_name}.status IN ( '" . implode( "','", $allowed_statuses ) . "' )"; + + $this->total_query->add_sql_clause( 'join', $join_clause ); + $this->total_query->add_sql_clause( 'where', $status_where_clause ); + + $this->interval_query->add_sql_clause( 'join', $join_clause ); + $this->interval_query->add_sql_clause( 'where', $status_where_clause ); + } +} diff --git a/admin/Analytics/Rest_API/Conversions/Store.php b/admin/Analytics/Rest_API/Conversions/Store.php new file mode 100644 index 0000000..d7be33a --- /dev/null +++ b/admin/Analytics/Rest_API/Conversions/Store.php @@ -0,0 +1,378 @@ + 'intval', + 'parent_id' => 'intval', + 'date_created' => 'strval', + 'date_created_gmt' => 'strval', + 'customer_id' => 'intval', + 'total_sales' => 'floatval', + 'workflow_id' => 'intval', + 'conversion_id' => 'intval', + ); + + /** + * Constructor to intialize the table and date column. + */ + public function __construct() { + global $wpdb; + + // Set meta table details according to HPOS being enabled or not. + if ( HPOS_Helper::is_HPOS_enabled() ) { + $this->meta_table = (object) array( + 'name' => "{$wpdb->prefix}wc_orders_meta", + 'id_column' => 'order_id', + ); + } else { + $this->meta_table = (object) array( + 'name' => "{$wpdb->prefix}postmeta", + 'id_column' => 'post_id', + ); + } + + // Dynamically sets the date column name based on configuration. + $this->date_column_name = get_option( 'woocommerce_date_type', 'date_created' ); + parent::__construct(); + } + + /** + * Assign report columns once full table name has been assigned. + */ + protected function assign_report_columns() { + $table_name = self::get_db_table_name(); + // Avoid ambigious columns in SQL query. + $this->report_columns = array( + 'order_id' => "DISTINCT {$table_name}.order_id", + // Add 'date' field based on date type setting. + 'date' => "{$table_name}.{$this->date_column_name} AS date", + 'date_created' => "{$table_name}.date_created", + 'date_created_gmt' => "{$table_name}.date_created_gmt", + 'customer_id' => "{$table_name}.customer_id", + 'total_sales' => "{$table_name}.total_sales", + 'workflow_id' => 'aw_workflow.meta_value AS workflow_id', + 'conversion_id' => 'aw_conversion.meta_value AS conversion_id', + ); + } + + /** + * Updates the database query with parameters used for the conversion list. + * + * @param array $query_args Query arguments supplied by the user. + */ + protected function add_sql_query_params( $query_args ) { + global $wpdb; + $order_stats_table_name = self::get_db_table_name(); + + $this->add_time_period_sql_params( $query_args, $order_stats_table_name ); + $this->get_limit_sql_params( $query_args ); + $this->add_order_by_sql_params( $query_args ); + + $this->subquery->add_sql_clause( 'join', "JOIN {$this->meta_table->name} aw_workflow ON ( {$order_stats_table_name}.order_id = aw_workflow.{$this->meta_table->id_column} AND aw_workflow.meta_key = '_aw_conversion' )" ); + $this->subquery->add_sql_clause( 'join', "JOIN {$this->meta_table->name} aw_conversion ON ( {$order_stats_table_name}.order_id = aw_conversion.{$this->meta_table->id_column} AND aw_conversion.meta_key = '_aw_conversion_log' )" ); + + // We hardcode paid statuses only. + // This is to match the legacy Reports behavior, + // but is inconsistent with set of statuses used by WC Core analytics. + // https://github.com/woocommerce/automatewoo/issues/1266 + $query_args['status_is'] = wc_get_is_paid_statuses(); + $this->subquery->add_sql_clause( 'where', 'AND ' . $this->get_status_subquery( $query_args ) ); + } + + /** + * Returns the report data based on parameters supplied by the user. + * + * @param array $query_args Query parameters. + * @return stdClass|WP_Error Data. + */ + public function get_data( $query_args ) { + global $wpdb; + + // These defaults are only partially applied when used via REST API, as that has its own defaults. + $defaults = array( + 'per_page' => get_option( 'posts_per_page' ), + 'page' => 1, + 'order' => 'DESC', + 'orderby' => $this->date_column_name, + 'before' => TimeInterval::default_before(), + 'after' => TimeInterval::default_after(), + 'fields' => '*', + 'extended_info' => false, + ); + $query_args = wp_parse_args( $query_args, $defaults ); + $this->normalize_timezones( $query_args, $defaults ); + + /* + * We need to get the cache key here because + * parent::update_intervals_sql_params() modifies $query_args. + */ + $cache_key = $this->get_cache_key( $query_args ); + $data = $this->get_cached_data( $cache_key ); + + if ( false === $data ) { + $this->initialize_queries(); + + $data = (object) array( + 'data' => array(), + 'total' => 0, + 'pages' => 0, + 'page_no' => 0, + ); + + $selections = $this->selected_columns( $query_args ); + $params = $this->get_limit_params( $query_args ); + $this->add_sql_query_params( $query_args ); + /* phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared */ + $db_records_count = (int) $wpdb->get_var( + "SELECT COUNT( DISTINCT tt.order_id ) FROM ( + {$this->subquery->get_query_statement()} + ) AS tt" + ); + /* phpcs:enable */ + + if ( 0 === $params['per_page'] ) { + $total_pages = 0; + } else { + $total_pages = (int) ceil( $db_records_count / $params['per_page'] ); + } + if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) { + $data = (object) array( + 'data' => array(), + 'total' => $db_records_count, + 'pages' => $total_pages, + 'page_no' => 0, + ); + return $data; + } + + $this->subquery->clear_sql_clause( 'select' ); + $this->subquery->add_sql_clause( 'select', $selections ); + $this->subquery->add_sql_clause( 'order_by', $this->get_sql_clause( 'order_by' ) ); + $this->subquery->add_sql_clause( 'limit', $this->get_sql_clause( 'limit' ) ); + /* phpcs:disable WordPress.DB.PreparedSQL.NotPrepared */ + $orders_data = $wpdb->get_results( + $this->subquery->get_query_statement(), + ARRAY_A + ); + /* phpcs:enable */ + + if ( null === $orders_data ) { + return $data; + } + + if ( $query_args['extended_info'] ) { + $this->include_extended_info( $orders_data, $query_args ); + } + + $orders_data = array_map( array( $this, 'cast_numbers' ), $orders_data ); + $data = (object) array( + 'data' => $orders_data, + 'total' => $db_records_count, + 'pages' => $total_pages, + 'page_no' => (int) $query_args['page'], + ); + + $this->set_cached_data( $cache_key, $data ); + } + return $data; + } + + /** + * Enriches the order data. + * + * @param array $orders_data Orders data. + * @param array $query_args Query parameters. + */ + protected function include_extended_info( &$orders_data, $query_args ) { + $customers = $this->get_customers_by_orders( $orders_data ); + $workflows = $this->get_workflows_by_orders( $orders_data ); + $conversions = $this->get_conversions_by_orders( $orders_data ); + $defaults = array( + 'customer' => array(), + 'workflow' => array(), + 'conversion' => array(), + ); + + foreach ( $orders_data as $key => $order_data ) { + $orders_data[ $key ]['extended_info'] = $defaults; + if ( $order_data['customer_id'] && isset( $customers[ $order_data['customer_id'] ] ) ) { + $orders_data[ $key ]['extended_info']['customer'] = $customers[ $order_data['customer_id'] ]; + } + if ( $order_data['workflow_id'] && isset( $workflows[ $order_data['workflow_id'] ] ) ) { + $orders_data[ $key ]['extended_info']['workflow'] = $workflows[ $order_data['workflow_id'] ]; + } + if ( $order_data['conversion_id'] && isset( $conversions[ $order_data['conversion_id'] ] ) ) { + $orders_data[ $key ]['extended_info']['conversion'] = $conversions[ $order_data['conversion_id'] ]; + } + } + } + + /** + * Get customer data from Order data. + * + * @param array $orders Array of orders data. + * @return array + */ + protected function get_customers_by_orders( $orders ) { + global $wpdb; + + $customer_lookup_table = "{$wpdb->prefix}wc_customer_lookup"; + $customer_ids = array_unique( array_column( $orders, 'customer_id' ) ); + + if ( empty( $customer_ids ) ) { + return array(); + } + + /* phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared */ + $customer_ids = implode( ',', $customer_ids ); + $customers = $wpdb->get_results( + "SELECT * FROM {$customer_lookup_table} WHERE customer_id IN ({$customer_ids})", + ARRAY_A + ); + /* phpcs:enable */ + + // Return customer array reindexed by customer_id. + return array_column( $customers, null, 'customer_id' ); + } + + /** + * Get workflow data from Order data. + * + * @param array $orders Array of orders data. + * @return array + */ + protected function get_workflows_by_orders( $orders ) { + $workflow_ids = array_unique( array_column( $orders, 'workflow_id' ) ); + + if ( empty( $workflow_ids ) ) { + return array(); + } + + $workflows = array(); + foreach ( $workflow_ids as $workflow_id ) { + $workflow = WorkflowFactory::get( $workflow_id ); + + if ( ! $workflow || ! $workflow->exists ) { + continue; + } + + $workflows[ $workflow_id ] = array( + 'name' => $workflow->get_title(), + ); + } + + return $workflows; + } + + /** + * Get conversion data from Order data. + * + * @param array $orders Array of orders data. + * @return array + */ + protected function get_conversions_by_orders( $orders ) { + $conversion_ids = array_unique( array_column( $orders, 'conversion_id' ) ); + + if ( empty( $conversion_ids ) ) { + return array(); + } + + $conversions = array(); + foreach ( $conversion_ids as $conversion_id ) { + $conversion = Log_Factory::get( $conversion_id ); + $date_opened = $conversion ? $conversion->get_date_opened() : false; + + if ( ! $conversion || ! $date_opened ) { + continue; + } + + $conversions[ $conversion_id ] = array( + 'date_opened' => $date_opened->format( TimeInterval::$sql_datetime_format ), + ); + } + + return $conversions; + } + + /** + * Normalizes order_by clause to match to SQL query. + * + * @param string $order_by Order by option requeste by user. + * @return string + */ + protected function normalize_order_by( $order_by ) { + if ( 'date' === $order_by ) { + return $this->date_column_name; + } + + return $order_by; + } + + /** + * Initialize query objects. + */ + protected function initialize_queries() { + $this->clear_all_clauses(); + $this->subquery = new SqlQuery( $this->context . '_subquery' ); + $this->subquery->add_sql_clause( 'select', self::get_db_table_name() . '.order_id' ); + $this->subquery->add_sql_clause( 'from', self::get_db_table_name() ); + } +} diff --git a/admin/Analytics/Rest_API/Email_Tracking/Stats_Controller.php b/admin/Analytics/Rest_API/Email_Tracking/Stats_Controller.php new file mode 100644 index 0000000..bfb7784 --- /dev/null +++ b/admin/Analytics/Rest_API/Email_Tracking/Stats_Controller.php @@ -0,0 +1,78 @@ + array( + 'description' => __( 'Number of sent messages.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'opens' => array( + 'description' => __( 'Number of opened messages.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'unique-clicks' => array( + 'description' => __( 'Number of messages clicked at least ones.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'clicks' => array( + 'description' => __( 'Number of total clicks.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + } + /** + * Get the Email & SMS Tracking Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + $schema['title'] = 'report_email_tracking_stats'; + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/admin/Analytics/Rest_API/Email_Tracking/Stats_Store.php b/admin/Analytics/Rest_API/Email_Tracking/Stats_Store.php new file mode 100644 index 0000000..60c4dd2 --- /dev/null +++ b/admin/Analytics/Rest_API/Email_Tracking/Stats_Store.php @@ -0,0 +1,337 @@ + 'strval', + 'date_end' => 'strval', + 'sent' => 'intval', + 'opens' => 'intval', + 'unique-clicks' => 'intval', + 'clicks' => 'intval', + ); + + /** + * Data store context used to pass to filters. + * + * @var string + */ + protected $context = 'email_tracking_stats'; + + /** + * Assign report columns. + */ + protected function assign_report_columns() { + global $wpdb; + $meta_table_name = $wpdb->prefix . static::$meta_table_name; + // API fields mapped to sql SELECT statements. + // For intervals we need a non-aggregated query to access interval dates from `meta_value`. + $this->report_columns = array( + 'sent' => 'id as sent', + 'opens' => "LOCATE( 's:4:\"type\";s:4:\"open\";', {$meta_table_name}.meta_value ) > 0 as opens", + 'unique-clicks' => "LOCATE( 's:4:\"type\";s:5:\"click\";', {$meta_table_name}.meta_value ) > 0 as 'unique-clicks'", + 'clicks' => 'null as clicks', + ); + } + + /** + * Returns a list of totals selected by the query_args. + * + * This is almost a copy of `selected_columns`, but for a given array instead of `$this->report_columns`, + * and without `implode`. + * Due to the fact we need access to `meta_value`s to select interval dates, + * we use an SQL query for individual intervals, but calculate totals as a PHP array. + * + * @param array $query_args User-supplied options. + * @param array $totals Array of totals to be filtered. + * @return string + */ + protected function selected_totals( $query_args, $totals ) { + if ( ! isset( $query_args['fields'] ) || ! is_array( $query_args['fields'] ) ) { + return $totals; + } + + return array_intersect_key( $totals, array_flip( $query_args['fields'] ) ); + } + + /** + * Returns the report data based on normalized parameters. + * Will be called by `get_data` if there is no data in cache. + * + * @overwrites Log_Stats_Store::get_noncached_stats_data + * @see get_data + * @param array $query_args Query parameters. + * @param array $params Query limit parameters. + * @param stdClass $data Reference to the data object to fill. + * @param int $expected_interval_count Number of expected intervals. + * @return stdClass|WP_Error Data object `{ totals: *, intervals: array, total: int, pages: int, page_no: int }`, or error. + */ + public function get_noncached_stats_data( $query_args, $params, &$data, $expected_interval_count ) { + global $wpdb; + + $table_name = self::get_db_table_name(); + $this->initialize_queries(); + + $selections = $this->selected_columns( $query_args ); + + $this->update_sql_query_params( $query_args ); + $this->interval_query->add_sql_clause( 'where_time', $this->get_sql_clause( 'where_time' ) ); + + // Get the total available log entries => "intervals", without `LIMIT` set. + // Group them in SQL, not in PHP as we do below, as there is no individual meta values we need to fetch at this point. + $this->interval_query->add_sql_clause( 'group_by', 'time_interval' ); + $db_intervals = $wpdb->get_col( + $this->interval_query->get_query_statement() // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ); + $this->interval_query->clear_sql_clause( 'group_by' ); + + $db_interval_count = count( $db_intervals ); + + $intervals = array(); + $this->update_intervals_sql_params( $query_args, $db_interval_count, $expected_interval_count, $table_name ); + + $date_column_name = $this->date_column_name; + $this->interval_query->add_sql_clause( 'order_by', $this->get_sql_clause( 'order_by' ) ); + $this->interval_query->add_sql_clause( 'select', ", {$table_name}.{$date_column_name} AS datetime_anchor" ); + + // Add meta property to manualy count non-unique clicks, and assign tracked event event dates. + $meta_table_name = $wpdb->prefix . static::$meta_table_name; + $this->interval_query->add_sql_clause( 'select', ", {$meta_table_name}.meta_value as meta_value" ); + if ( '' !== $selections ) { + $this->interval_query->add_sql_clause( 'select', ', ' . $selections ); + } + + $logs = $wpdb->get_results( + $this->interval_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); + + $chosen_interval = $query_args['interval']; + // Manually iterate over tracked events. Logic copied from legacy reports. + $all_events = array(); + $totals = array( + 'sent' => 0, + 'opens' => 0, + 'unique-clicks' => 0, + 'clicks' => 0, + ); + $timezone = $query_args['before']->getTimezone(); + $last_recorded_date = new DateTime( '0-0-0 0:0:0', $timezone ); + foreach ( $logs as $log ) { + + $click_recorded = false; + $log_tracked_events = maybe_unserialize( $log['meta_value'] ); + + // Record the trackable workflow run => message sent. + $event_date = new DateTime( $log['datetime_anchor'], $timezone ); + $last_recorded_date = max( $last_recorded_date, $event_date ); + $time_interval = TimeInterval::time_interval_id( $chosen_interval, $event_date ); + $all_events[] = array( + 'time_interval' => $time_interval, + 'type' => 'sent', + ); + ++$totals['sent']; + + // If there is no data, or data is in unexpected format ignore the entry and continue. + if ( ! is_array( $log_tracked_events ) ) { + continue; + } + + // Record granular events. + foreach ( $log_tracked_events as $event ) { + + if ( ! isset( $event['type'] ) ) { + continue; + } + + $event_date = new DateTime( $event['date'], $timezone ); + $last_recorded_date = max( $last_recorded_date, $event_date ); + $time_interval = TimeInterval::time_interval_id( $chosen_interval, $event_date ); + switch ( $event['type'] ) { + case 'click': + if ( ! $click_recorded ) { + + $all_events[] = array( + 'time_interval' => $time_interval, + 'type' => 'unique-clicks', + ); + $click_recorded = true; + ++$totals['unique-clicks']; + } + $all_events[] = array( + 'time_interval' => $time_interval, + 'type' => 'clicks', + ); + ++$totals['clicks']; + break; + + case 'open': + $all_events[] = array( + 'time_interval' => $time_interval, + 'type' => 'opens', + ); + ++$totals['opens']; + + break; + + } + } + } + + // Group by interval. + $grouped_intervals = array(); + foreach ( $all_events as $entry ) { + $interval = $entry['time_interval']; + if ( ! isset( $grouped_intervals[ $interval ] ) ) { + $group = array( + 'time_interval' => $interval, + 'sent' => 0, + 'opens' => 0, + 'unique-clicks' => 0, + 'clicks' => 0, + 'datetime_anchor' => $interval, + ); + } else { + $group = $grouped_intervals[ $interval ]; + } + ++$group[ $entry['type'] ]; + $group['datetime_anchor'] = max( $group['datetime_anchor'], $interval ); + + $grouped_intervals[ $interval ] = $group; + } + // This is the result of what we would get for something like + // `SELECT DATE_FORMAT(wp_automatewoo_log_meta.date, …) AS time_interval, SUM(…), … GROUP BY time_interval;` + // If the tracked event date would be exposed in a separate column. + $intervals = array_values( $grouped_intervals ); + + if ( null === $intervals ) { + return new WP_Error( 'automatewoo_email_tracking_stats_result_failed', __( 'Sorry, fetching email & SMS tracking data failed.', 'automatewoo' ) ); + } + + // `fill_in_missing_intervals` expect it to be an object. + $data->totals = (object) $this->selected_totals( $query_args, $totals ); + $data->intervals = $intervals; + // We need to sort intervals, as we constructed them manually from not sorted tracked event dates. + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + + // Update end dates, as tracked events, may happened after the queried log.date range. + $end_datetime = $query_args['before']; + if ( $query_args['before'] < $last_recorded_date ) { + $end_datetime = TimeInterval::iterate( $last_recorded_date, $query_args['interval'] )->modify( '-1 ms' ); + } + + if ( $this->intervals_missing( $expected_interval_count, $db_interval_count, null, null, null, null, count( $intervals ) ) ) { + $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data ); + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + } else { + $this->update_interval_boundary_dates( $query_args['after'], $end_datetime, $query_args['interval'], $data->intervals ); + + } + + $this->create_interval_subtotals( $data->intervals ); + + return $data; + } + + /** + * Simplified versions of `TimeInterval::intervals_missing` as here we always have one page. + * + * @see get_limit_params + * @overwrites Automattic\WooCommerce\Admin\API\Reports\DataStore::intervals_missing + * @param int $expected_interval_count Expected number of intervals in total. + * @param int $db_interval_count Total number of records for given period in the database. + * @param any $items_per_page Number of items per page. + * @param any $page_no Page number. + * @param any $order asc or desc. + * @param any $order_by Column by which the result will be sorted. + * @param int $intervals_count Number of records for given (possibly shortened) time interval. + * + * @return bool + */ + public function intervals_missing( $expected_interval_count, $db_interval_count, $items_per_page, $page_no, $order, $order_by, $intervals_count ) { + if ( $expected_interval_count <= $db_interval_count ) { + return false; + } + return $intervals_count < $expected_interval_count; + } + + /** + * Initialize query objects. + */ + protected function initialize_queries() { + parent::initialize_queries(); + + global $wpdb; + $logs_table_name = self::get_db_table_name(); + $meta_table_name = $wpdb->prefix . static::$meta_table_name; + $join_clause = "LEFT JOIN {$meta_table_name} ON ( {$logs_table_name}.id = {$meta_table_name}.log_id AND {$meta_table_name}.meta_key = 'tracking_data' )"; + // Consider only tracked runs with no blocked emails, + // to match the legacy PHP reports. + $tracking_where_clause = " AND {$logs_table_name}.tracking_enabled = 1 AND {$logs_table_name}.has_blocked_emails = 0"; + + $this->interval_query->add_sql_clause( 'join', $join_clause ); + $this->interval_query->add_sql_clause( 'where', $tracking_where_clause ); + // We will have to group manually in PHP, as we need to access `date`s from `meta_value`s. + $this->interval_query->clear_sql_clause( 'group_by' ); + } + + /** + * Overwrite limit properties. + * Always expect all results on a single page. + * + * Due to the event date being unrelated to log date, setting LIMITs in SQL does not make much sense. + * That's why we need to query everything in PHP anyway, so there is no point in paginating it, + * and paking the frontent request the full query n times. + * + * @overwrite Generic_Stats_Store::get_limit_params + * @param array $query_args Parameters supplied by the user. + * @return array + */ + protected function get_limit_params( $query_args = array() ) { + return [ + 'offset' => 0, + // This is expected number of intervals. + // However we can get more, as tracking events may happen after the requested dates. + 'per_page' => TimeInterval::intervals_between( $query_args['after'], $query_args['before'], $query_args['interval'] ), + ]; + } +} diff --git a/admin/Analytics/Rest_API/Log_Stats_Controller.php b/admin/Analytics/Rest_API/Log_Stats_Controller.php new file mode 100644 index 0000000..585f02b --- /dev/null +++ b/admin/Analytics/Rest_API/Log_Stats_Controller.php @@ -0,0 +1,57 @@ + __( 'Limit result set to workflows assigned specific workflow IDs.', 'automatewoo' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_id_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'integer', + ), + ); + $params['segmentby'] = array( + 'description' => __( 'Segment the response by additional constraint.', 'automatewoo' ), + 'type' => 'string', + 'enum' => array( + 'workflow_id', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } + + /** + * Get the report's item properties schema. + * Will be used by `get_item_schema` as `totals` and `subtotals`. + * + * @return array + */ + public function get_item_properties_schema() { + return array(); + } +} diff --git a/admin/Analytics/Rest_API/Log_Stats_Store.php b/admin/Analytics/Rest_API/Log_Stats_Store.php new file mode 100644 index 0000000..f0e28d9 --- /dev/null +++ b/admin/Analytics/Rest_API/Log_Stats_Store.php @@ -0,0 +1,52 @@ +total_query->add_sql_clause( 'where', $workflows_where_clause ); + $this->interval_query->add_sql_clause( 'where', $workflows_where_clause ); + } + } +} diff --git a/admin/Analytics/Rest_API/Unsubscribers/Stats_Controller.php b/admin/Analytics/Rest_API/Unsubscribers/Stats_Controller.php new file mode 100644 index 0000000..de6aa48 --- /dev/null +++ b/admin/Analytics/Rest_API/Unsubscribers/Stats_Controller.php @@ -0,0 +1,60 @@ + array( + 'description' => __( 'Number of unsubscribers.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + } + /** + * Get the Unsubscribers Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + $schema['title'] = 'report_unsubscribers_stats'; + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/admin/Analytics/Rest_API/Unsubscribers/Stats_Store.php b/admin/Analytics/Rest_API/Unsubscribers/Stats_Store.php new file mode 100644 index 0000000..88fea02 --- /dev/null +++ b/admin/Analytics/Rest_API/Unsubscribers/Stats_Store.php @@ -0,0 +1,149 @@ + 'strval', + 'date_end' => 'strval', + 'unsubscribers' => 'intval', + ); + + /** + * Data store context used to pass to filters. + * + * @var string + */ + protected $context = 'unsubscribers_stats'; + + /** + * Assign report columns. + */ + protected function assign_report_columns() { + // API fields mapped to sql SELECT statements. + $this->report_columns = array( + 'unsubscribers' => 'COUNT(DISTINCT id) as unsubscribers', + ); + } + + /** + * Returns the report data based on normalized parameters. + * Will be called by `get_data` if there is no data in cache. + * + * @see get_data + * @param array $query_args Query parameters. + * @param array $params Query limit parameters. + * @param stdClass $data Reference to the data object to fill. + * @param int $expected_interval_count Number of expected intervals. + * @return stdClass|WP_Error Data object `{ totals: *, intervals: array, total: int, pages: int, page_no: int }`, or error. + */ + public function get_noncached_stats_data( $query_args, $params, &$data, $expected_interval_count ) { + global $wpdb; + $table_name = self::get_db_table_name(); + + $this->initialize_queries(); + + $selections = $this->selected_columns( $query_args ); + $params = $this->get_limit_params( $query_args ); + + $this->update_sql_query_params( $query_args ); + $this->get_limit_sql_params( $query_args ); + $this->interval_query->add_sql_clause( 'where_time', $this->get_sql_clause( 'where_time' ) ); + + $db_intervals = $wpdb->get_col( + $this->interval_query->get_query_statement() // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ); + + $db_interval_count = count( $db_intervals ); + + $intervals = array(); + $this->update_intervals_sql_params( $query_args, $db_interval_count, $expected_interval_count, $table_name ); + $this->total_query->add_sql_clause( 'select', $selections ); + $this->total_query->add_sql_clause( 'where_time', $this->get_sql_clause( 'where_time' ) ); + + $totals = $wpdb->get_results( + $this->total_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); + + if ( null === $totals ) { + return new WP_Error( 'automatewoo_unsubscribers_stats_result_failed', __( 'Sorry, fetching unsubscribers data failed.', 'automatewoo' ) ); + } + + $date_column_name = $this->date_column_name; + $this->interval_query->add_sql_clause( 'order_by', $this->get_sql_clause( 'order_by' ) ); + $this->interval_query->add_sql_clause( 'limit', $this->get_sql_clause( 'limit' ) ); + $this->interval_query->add_sql_clause( 'select', ", MAX({$table_name}.{$date_column_name}) AS datetime_anchor" ); + if ( '' !== $selections ) { + $this->interval_query->add_sql_clause( 'select', ', ' . $selections ); + } + + $intervals = $wpdb->get_results( + $this->interval_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); + + if ( null === $intervals ) { + return new WP_Error( 'automatewoo_unsubscribers_stats_result_failed', __( 'Sorry, fetching unsubscribers data failed.', 'automatewoo' ) ); + } + + $totals = (object) $this->cast_numbers( $totals[0] ); + + $data->totals = $totals; + $data->intervals = $intervals; + + if ( TimeInterval::intervals_missing( $expected_interval_count, $db_interval_count, $params['per_page'], $query_args['page'], $query_args['order'], $query_args['orderby'], count( $intervals ) ) ) { + $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data ); + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + $this->remove_extra_records( $data, $query_args['page'], $params['per_page'], $db_interval_count, $expected_interval_count, $query_args['orderby'], $query_args['order'] ); + } else { + $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $data->intervals ); + } + + $this->create_interval_subtotals( $data->intervals ); + + return $data; + } +} diff --git a/admin/Analytics/Rest_API/Upstream/Generic_Controller.php b/admin/Analytics/Rest_API/Upstream/Generic_Controller.php new file mode 100644 index 0000000..448dc38 --- /dev/null +++ b/admin/Analytics/Rest_API/Upstream/Generic_Controller.php @@ -0,0 +1,90 @@ +rest_base ); + } + + /** + * Maps query arguments from the REST request. + * + * `WP_REST_Request` does not expose a method to return all params covering defaults, + * as it does for `$request['param']` accessor. + * Therefore, we re-implement defaults resolution. + * + * @param WP_REST_Request $request Full request object. + * @return array Simplified array of params. + */ + public function prepare_reports_query( $request ) { + $args = wp_parse_args( + array_intersect_key( + $request->get_query_params(), + $this->get_collection_params() + ), + $request->get_default_params() + ); + + return $args; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $report, $request ) { + $data = get_object_vars( $report ); + + return parent::prepare_item_for_response( $data, $request ); + } + + /** + * Get the Report's item properties schema. + * Will be used by `get_item_schema` as `totals` and `subtotals`. + * + * To be extended by specific report properites. + * + * @return array + */ + public function get_item_properties_schema() { + return array(); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * To be extended for each report. + * + * @return array + */ + public function get_item_schema() { + return $this->add_additional_fields_schema( array() ); + } +} diff --git a/admin/Analytics/Rest_API/Upstream/Generic_Query.php b/admin/Analytics/Rest_API/Upstream/Generic_Query.php new file mode 100644 index 0000000..8978bba --- /dev/null +++ b/admin/Analytics/Rest_API/Upstream/Generic_Query.php @@ -0,0 +1,68 @@ + '2018-07-19 00:00:00', + * 'after' => '2018-07-05 00:00:00', + * 'page' => 2, + * 'workflows' => array(5, 120), + * ); + * $report = new \AutomateWoo\Admin\Analytics\Rest_API\Email_Tracking\Query( $args ); + * $mydata = $report->get_data(); + */ + +namespace AutomateWoo\Admin\Analytics\Rest_API\Upstream; + +defined( 'ABSPATH' ) || exit; + +use Automattic\WooCommerce\Admin\API\Reports\Query as WooReportsQuery; +use WC_Data_Store; + +/** + * Workflow runs specific Woo Report Query. + * + * @see Automattic\WooCommerce\Admin\API\Reports\Query + * @since 5.6.9 + */ +class Generic_Query extends \WC_Object_Query { + + /** + * Store name + * + * @var string + */ + public $store_name; + + /** + * Create a new query. + * + * @param array $args Criteria to query on in a format similar to WP_Query. + * @param string $store_name `WC_Data_Store`'s store name to eventually load and get data from. + * @extends WooReportsQuery::_construct + */ + public function __construct( $args, $store_name ) { + $this->store_name = $store_name; + + parent::__construct( $args ); + } + /** + * Valid fields for Products report. + * + * @return array + */ + protected function get_default_query_vars() { + return array(); + } + + /** + * Get emails tracking data based on the current query vars. + * + * @return array + */ + public function get_data() { + $data_store = WC_Data_Store::load( $this->store_name ); + return $data_store->get_data( $this->get_query_vars() ); + } +} diff --git a/admin/Analytics/Rest_API/Upstream/Generic_Stats_Controller.php b/admin/Analytics/Rest_API/Upstream/Generic_Stats_Controller.php new file mode 100644 index 0000000..88925a1 --- /dev/null +++ b/admin/Analytics/Rest_API/Upstream/Generic_Stats_Controller.php @@ -0,0 +1,135 @@ +prepare_reports_query( $request ); + $query = $this->construct_query( $query_args ); + try { + $report_data = $query->get_data(); + } catch ( ParameterException $e ) { + return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); + } + + $out_data = array( + 'totals' => $report_data->totals ? get_object_vars( $report_data->totals ) : null, + 'intervals' => array(), + ); + + foreach ( $report_data->intervals as $interval_data ) { + $item = $this->prepare_item_for_response( (object) $interval_data, $request ); + $out_data['intervals'][] = $this->prepare_response_for_collection( $item ); + } + + return $this->add_pagination_headers( + $request, + $out_data, + (int) $report_data->total, + (int) $report_data->page_no, + (int) $report_data->pages + ); + } + + /** + * Get the query params for collections. + * + * You may consider extending it with `segmentby`, with: + * ``` + * $params = parent::get_collection_params(); + * $params['segmentby'] = array( + * 'description' => __( 'Segment the response by additional constraint.', 'my-extension' ), + * 'type' => 'string', + * 'enum' => array( + * 'property_name', + * ), + * 'validate_callback' => 'rest_validate_request_arg', + * ); + * ``` + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + + $params['fields'] = array( + 'description' => __( 'Limit stats fields to the specified items.', 'automatewoo' ), + 'type' => 'array', + 'sanitize_callback' => 'wp_parse_slug_list', + 'validate_callback' => 'rest_validate_request_arg', + 'items' => array( + 'type' => 'string', + ), + ); + + return $params; + } + + /** + * Forwards a Query constructor, + * to be able to customize Query class for a specific report. + * + * @param array $query_args Set of args to be forwarded to the constructor. + * @return Generic_Query + */ + protected function construct_query( $query_args ) { + return new Generic_Query( $query_args, $this->rest_base ); + } + + /** + * Maps query arguments from the REST request. + * + * `WP_REST_Request` does not expose a method to return all params covering defaults, + * as it does for `$request['param']` accessor. + * Therefore, we re-implement defaults resolution. + * + * @param WP_REST_Request $request Full request object. + * @return array Simplified array of params. + */ + public function prepare_reports_query( $request ) { + $args = wp_parse_args( + array_intersect_key( + $request->get_query_params(), + $this->get_collection_params() + ), + $request->get_default_params() + ); + + return $args; + } + + /** + * Prepare a report object for serialization. + * + * @param stdClass $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $report, $request ) { + $data = get_object_vars( $report ); + + return parent::prepare_item_for_response( $data, $request ); + } +} diff --git a/admin/Analytics/Rest_API/Upstream/Generic_Stats_Store.php b/admin/Analytics/Rest_API/Upstream/Generic_Stats_Store.php new file mode 100644 index 0000000..1cc68c0 --- /dev/null +++ b/admin/Analytics/Rest_API/Upstream/Generic_Stats_Store.php @@ -0,0 +1,137 @@ +add_time_period_sql_params( $query_args, $table_name ); + $this->add_intervals_sql_params( $query_args, $table_name ); + $this->add_order_by_sql_params( $query_args ); + $this->interval_query->add_sql_clause( 'select', $this->get_sql_clause( 'select' ) . ' AS time_interval' ); + } + + /** + * Returns the report data based on parameters supplied by the user. + * Fetches it from cache or returns `get_noncached_stats_data` result. + * + * @see get_noncached_stats_data + * @param array $query_args Query parameters. + * @return stdClass|WP_Error Data object `{ totals: *, intervals: array, total: int, pages: int, page_no: int }`, or error. + */ + public function get_data( $query_args ) { + // These defaults are only partially applied when used via REST API, as that has its own defaults. + $defaults = array( + 'per_page' => get_option( 'posts_per_page' ), + 'page' => 1, + 'order' => 'ASC', + 'orderby' => 'date', + 'before' => TimeInterval::default_before(), + 'after' => TimeInterval::default_after(), + 'fields' => '*', + 'interval' => 'week', + ); + $query_args = wp_parse_args( $query_args, $defaults ); + $this->normalize_timezones( $query_args, $defaults ); + + /* + * We need to get the cache key here because + * parent::update_intervals_sql_params() modifies $query_args. + */ + $cache_key = $this->get_cache_key( $query_args ); + $data = $this->get_cached_data( $cache_key ); + + if ( false === $data ) { + $params = $this->get_limit_params( $query_args ); + $expected_interval_count = TimeInterval::intervals_between( $query_args['after'], $query_args['before'], $query_args['interval'] ); + $total_pages = (int) ceil( $expected_interval_count / $params['per_page'] ); + + // Default, empty data object. + $data = (object) array( + 'totals' => null, + 'intervals' => [], + 'total' => $expected_interval_count, + 'pages' => $total_pages, + 'page_no' => (int) $query_args['page'], + ); + // If the requested page is out off range, return the deault empty object. + if ( $query_args['page'] >= 1 && $query_args['page'] <= $total_pages ) { + // Fetch the actual data. + $data = $this->get_noncached_stats_data( $query_args, $params, $data, $expected_interval_count ); + } + $this->set_cached_data( $cache_key, $data ); + } + + return $data; + } + + /** + * Returns the report data based on normalized parameters. + * Will be called by `get_data` if there is no data in cache. + * + * @see get_data + * @param array $query_args Query parameters. + * @param array $params Query limit parameters. + * @param stdClass $data Reference to the data object to fill. + * @param int $expected_interval_count Number of expected intervals. + * @return stdClass|WP_Error Data object `{ totals: *, intervals: array, total: int, pages: int, page_no: int }`, or error. + */ + public function get_noncached_stats_data( $query_args, $params, &$data, $expected_interval_count ) { + /* translators: %s: Method name */ + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not implemented. Must be overridden in subclass.", 'automatewoo' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + + /** + * Initialize query objects. + */ + protected function initialize_queries() { + $this->clear_all_clauses(); + unset( $this->subquery ); + $table_name = self::get_db_table_name(); + + $this->total_query = new SqlQuery( $this->context . '_total' ); + $this->total_query->add_sql_clause( 'from', $table_name ); + + $this->interval_query = new SqlQuery( $this->context . '_interval' ); + $this->interval_query->add_sql_clause( 'from', $table_name ); + $this->interval_query->add_sql_clause( 'group_by', 'time_interval' ); + } +} diff --git a/admin/Analytics/Rest_API/Workflow_Runs/Stats_Controller.php b/admin/Analytics/Rest_API/Workflow_Runs/Stats_Controller.php new file mode 100644 index 0000000..f48aade --- /dev/null +++ b/admin/Analytics/Rest_API/Workflow_Runs/Stats_Controller.php @@ -0,0 +1,62 @@ + array( + 'description' => __( 'Number of workflow runs.', 'automatewoo' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + ); + } + /** + * Get the Workflow Runs Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + $schema['title'] = 'report_workflow_runs_stats'; + + return $this->add_additional_fields_schema( $schema ); + } +} diff --git a/admin/Analytics/Rest_API/Workflow_Runs/Stats_Store.php b/admin/Analytics/Rest_API/Workflow_Runs/Stats_Store.php new file mode 100644 index 0000000..c1a195a --- /dev/null +++ b/admin/Analytics/Rest_API/Workflow_Runs/Stats_Store.php @@ -0,0 +1,136 @@ + 'strval', + 'date_end' => 'strval', + 'runs' => 'intval', + ); + + /** + * Data store context used to pass to filters. + * + * @var string + */ + protected $context = 'workflow_runs_stats'; + + /** + * Assign report columns. + */ + protected function assign_report_columns() { + // API fields mapped to sql SELECT statements. + $this->report_columns = array( + 'runs' => 'COUNT(DISTINCT id) as runs', + ); + } + + /** + * Returns the report data based on normalized parameters. + * Will be called by `get_data` if there is no data in cache. + * + * @see get_data + * @param array $query_args Query parameters. + * @param array $params Query limit parameters. + * @param stdClass $data Reference to the data object to fill. + * @param int $expected_interval_count Number of expected intervals. + * @return stdClass|WP_Error Data object `{ totals: *, intervals: array, total: int, pages: int, page_no: int }`, or error. + */ + public function get_noncached_stats_data( $query_args, $params, &$data, $expected_interval_count ) { + global $wpdb; + $table_name = self::get_db_table_name(); + + $this->initialize_queries(); + + $selections = $this->selected_columns( $query_args ); + $params = $this->get_limit_params( $query_args ); + + $this->update_sql_query_params( $query_args ); + $this->get_limit_sql_params( $query_args ); + $this->interval_query->add_sql_clause( 'where_time', $this->get_sql_clause( 'where_time' ) ); + + $db_intervals = $wpdb->get_col( + $this->interval_query->get_query_statement() // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ); + + $db_interval_count = count( $db_intervals ); + + $intervals = array(); + $this->update_intervals_sql_params( $query_args, $db_interval_count, $expected_interval_count, $table_name ); + $this->total_query->add_sql_clause( 'select', $selections ); + $this->total_query->add_sql_clause( 'where_time', $this->get_sql_clause( 'where_time' ) ); + + $totals = $wpdb->get_results( + $this->total_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); + + if ( null === $totals ) { + return new WP_Error( 'automatewoo_workflow_runs_stats_result_failed', __( 'Sorry, fetching workflow runs data failed.', 'automatewoo' ) ); + } + + $date_column_name = $this->date_column_name; + $this->interval_query->add_sql_clause( 'order_by', $this->get_sql_clause( 'order_by' ) ); + $this->interval_query->add_sql_clause( 'limit', $this->get_sql_clause( 'limit' ) ); + $this->interval_query->add_sql_clause( 'select', ", MAX({$table_name}.{$date_column_name}) AS datetime_anchor" ); + if ( '' !== $selections ) { + $this->interval_query->add_sql_clause( 'select', ', ' . $selections ); + } + + $intervals = $wpdb->get_results( + $this->interval_query->get_query_statement(), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + ARRAY_A + ); + + if ( null === $intervals ) { + return new WP_Error( 'automatewoo_workflow_runs_stats_result_failed', __( 'Sorry, fetching workflow runs data failed.', 'automatewoo' ) ); + } + + $totals = (object) $this->cast_numbers( $totals[0] ); + + $data->totals = $totals; + $data->intervals = $intervals; + + if ( TimeInterval::intervals_missing( $expected_interval_count, $db_interval_count, $params['per_page'], $query_args['page'], $query_args['order'], $query_args['orderby'], count( $intervals ) ) ) { + $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data ); + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + $this->remove_extra_records( $data, $query_args['page'], $params['per_page'], $db_interval_count, $expected_interval_count, $query_args['orderby'], $query_args['order'] ); + } else { + $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $data->intervals ); + } + + $this->create_interval_subtotals( $data->intervals ); + + return $data; + } +} diff --git a/admin/AssetData.php b/admin/AssetData.php new file mode 100644 index 0000000..b064a3f --- /dev/null +++ b/admin/AssetData.php @@ -0,0 +1,50 @@ +registry = $registry; + } + + /** + * Add data to WC asset data registry. + * + * @throws InvalidArgumentException Only throws when site is in debug mode. + */ + public function add_data() { + $data = [ + 'manualRunner' => [ + 'batchSize' => 10, + 'highVolumeThreshold' => 500, + ], + ]; + + $this->registry->add( + 'automatewoo', + apply_filters( 'automatewoo/admin/asset_data', $data ) + ); + } +} diff --git a/admin/WCAdminConnectPages.php b/admin/WCAdminConnectPages.php new file mode 100644 index 0000000..e322560 --- /dev/null +++ b/admin/WCAdminConnectPages.php @@ -0,0 +1,206 @@ +is_wc_admin_active() ) { + return; + } + + add_action( 'admin_menu', [ $this, 'register_automatewoo_admin_pages' ] ); + add_action( 'admin_menu', [ $this, 'register_automatewoo_tabbed_pages' ] ); + add_action( 'current_screen', [ $this, 'register_automatewoo_tools_pages' ] ); + } + + /** + * Connects basic Automatewoo admin pages to WooCommerce Admin. + */ + public function register_automatewoo_admin_pages() { + + // Remove the WooCommerce base node from the breadcrumbs for AutomateWoo pages. + add_filter( + 'woocommerce_navigation_get_breadcrumbs', + function ( $breadcrumbs ) { + if ( Admin::is_automatewoo_screen() ) { + array_shift( $breadcrumbs ); + } + return $breadcrumbs; + } + ); + + // AutomateWoo AND AutomateWoo > Dashboard. + wc_admin_connect_page( + [ + 'id' => self::BREADCRUMB_ROOT, + 'screen_id' => 'automatewoo_page_automatewoo-dashboard', + 'title' => [ + __( 'AutomateWoo', 'automatewoo' ), + __( 'Dashboard', 'automatewoo' ), + ], + 'path' => add_query_arg( 'page', 'automatewoo-dashboard', 'admin.php' ), + ] + ); + + // AutomateWoo > Workflows. + wc_admin_connect_page( + [ + 'id' => 'automatewoo-workflows', + 'parent' => self::BREADCRUMB_ROOT, + 'screen_id' => 'edit-aw_workflow', + 'title' => __( 'Workflows', 'automatewoo' ), + 'path' => add_query_arg( 'post_type', 'aw_workflow', 'edit.php' ), + ] + ); + + // AutomateWoo > Workflows > Add New Workflow. + wc_admin_connect_page( + [ + 'id' => 'automatewoo-add-workflow', + 'parent' => 'automatewoo-workflows', + 'screen_id' => 'aw_workflow-add', + 'title' => __( 'Add New Workflow', 'automatewoo' ), + ] + ); + + // AutomateWoo > Workflows > Edit Workflow. + wc_admin_connect_page( + [ + 'id' => 'automatewoo-edit-workflow', + 'parent' => 'automatewoo-workflows', + 'screen_id' => 'aw_workflow', + 'title' => __( 'Edit Workflow', 'automatewoo' ), + ] + ); + + // Simple pages: AutomateWoo > [Page]. + $simple_pages = [ + 'logs' => __( 'Logs', 'automatewoo' ), + 'queue' => __( 'Queue', 'automatewoo' ), + 'carts' => __( 'Carts', 'automatewoo' ), + 'guests' => __( 'Guests', 'automatewoo' ), + 'opt-ins' => Options::optin_enabled() ? __( 'Opt-ins', 'automatewoo' ) : __( 'Opt-outs', 'automatewoo' ), + ]; + foreach ( $simple_pages as $screen_id => $title ) { + wc_admin_connect_page( + [ + 'id' => 'automatewoo-' . $screen_id, + 'parent' => self::BREADCRUMB_ROOT, + 'screen_id' => 'automatewoo_page_automatewoo-' . $screen_id, + 'title' => $title, + ] + ); + } + } + + /** + * Tabbed pages can be handled by WooCommerce Admin if registered with WC first. + * AW Settings and Reports pages can use the tab values directly. + * https://github.com/woocommerce/woocommerce-admin/blob/v1.2.3/docs/page-controller.md#determining-screen-id + */ + public function register_automatewoo_tabbed_pages() { + add_filter( + 'woocommerce_navigation_pages_with_tabs', + function ( $navigation_pages ) { + return array_merge( + $navigation_pages, + [ + 'automatewoo-settings' => 'general', + 'automatewoo-reports' => 'runs-by-date', + ] + ); + } + ); + + // AutomateWoo > Settings > [Tab]. + /** @var Admin\Controllers\Settings $settings */ + $settings = Admin\Controllers::get( 'settings' ); + $settings_path = add_query_arg( [ 'page' => 'automatewoo-settings' ], 'admin.php' ); + foreach ( $settings->get_settings_tabs() as $screen_id => $setting_object ) { + wc_admin_connect_page( + [ + 'id' => 'automatewoo-settings-' . $setting_object->id, + 'parent' => self::BREADCRUMB_ROOT, + 'screen_id' => 'automatewoo_page_automatewoo-settings-' . $setting_object->id, + 'title' => [ + __( 'Settings', 'automatewoo' ), + $setting_object->name, + ], + 'path' => $settings_path, + ] + ); + } + + // AutomateWoo > Reports > [Tab]. + /** @var Admin\Controllers\Reports $reports */ + $reports = Admin\Controllers::get( 'reports' ); + $reports_path = add_query_arg( [ 'page' => 'automatewoo-reports' ], 'admin.php' ); + foreach ( $reports->get_reports_tabs() as $screen_id => $report_object ) { + wc_admin_connect_page( + [ + 'id' => 'automatewoo-reports-' . $report_object->id, + 'parent' => self::BREADCRUMB_ROOT, + 'screen_id' => 'automatewoo_page_automatewoo-reports-' . $report_object->id, + 'title' => [ + __( 'Reports', 'automatewoo' ), + $report_object->name, + ], + 'path' => $reports_path, + ] + ); + } + } + + /** + * Enable "Tools" WC Admin breadcrumbs on the fly. + * All the tools share a screen_id and don't use the "tab" query parameter. + */ + public function register_automatewoo_tools_pages() { + if ( Admin::get_screen_id() === 'tools' ) { + // Basic info for root "Tools" page. + $page_info = [ + 'id' => 'automatewoo-tools', + 'parent' => self::BREADCRUMB_ROOT, + 'screen_id' => 'automatewoo_page_automatewoo-tools', + 'title' => __( 'Tools', 'automatewoo' ), + ]; + + $tool_id = Clean::string( aw_request( 'tool_id' ) ); + if ( $tool_id ) { + $tool = AW()->tools_service()->get_tool( $tool_id ); + if ( $tool ) { + $page_info['title'] = [ + $page_info['title'], + $tool->title, + ]; + $page_info['path'] = add_query_arg( + [ 'page' => 'automatewoo-tools' ], + 'admin.php' + ); + } + } + wc_admin_connect_page( $page_info ); + } + } +} diff --git a/admin/admin.php b/admin/admin.php new file mode 100644 index 0000000..594fdec --- /dev/null +++ b/admin/admin.php @@ -0,0 +1,1079 @@ +init(); + Analytics::init(); + + add_action( 'current_screen', [ $self, 'includes' ] ); + add_action( 'admin_enqueue_scripts', [ $self, 'register_scripts' ] ); + add_action( 'admin_enqueue_scripts', [ $self, 'register_styles' ] ); + add_action( 'admin_enqueue_scripts', [ $self, 'enqueue_scripts_and_styles' ], 20 ); + add_action( 'admin_enqueue_scripts', [ $self, 'load_react_ui_scripts' ] ); + add_action( 'admin_menu', [ $self, 'admin_menu' ] ); + add_action( 'admin_footer', [ $self, 'replace_top_level_menu' ] ); + add_action( 'admin_head', [ $self, 'menu_highlight' ] ); + add_filter( 'submenu_file', [ $self, 'submenu_highlight' ], 10, 2 ); + add_filter( 'admin_menu', [ $self, 'alter_menu' ] ); + + add_filter( 'woocommerce_screen_ids', [ $self, 'filter_woocommerce_screen_ids' ] ); + add_filter( 'woocommerce_display_admin_footer_text', [ $self, 'filter_woocommerce_display_footer_text' ] ); + add_action( 'current_screen', [ $self, 'remove_woocommerce_help_tab' ], 100 ); + + add_filter( 'woocommerce_reports_screen_ids', [ $self, 'inject_woocommerce_reports_screen_ids' ] ); + add_filter( 'editor_stylesheets', [ $self, 'add_editor_styles' ] ); + + add_action( 'current_screen', [ $self, 'screen_options' ] ); + add_filter( 'set-screen-option', [ $self, 'handle_save_screen_option' ], 10, 3 ); + + if ( aw_request( 'action' ) === 'automatewoo-settings' ) { + add_action( 'wp_loaded', [ $self, 'save_settings' ] ); + } + + if ( aw_request( 'page' ) === 'automatewoo-preview' && aw_request( 'action' ) === 'loading' ) { + add_action( 'admin_init', [ $self, 'cache_preview_loader' ] ); + } + + if ( aw_request( 'page' ) === 'automatewoo-preview' ) { + add_action( 'admin_notices', [ $self, 'remove_admin_notices' ], 0 ); + } + + $registry = BlocksPackage::container()->get( AssetDataRegistry::class ); + ( new AssetData( $registry ) )->add_data(); + } + + /** + * Initialize classes based on current screen. + */ + public static function includes() { + + switch ( self::get_screen_id() ) { + case 'aw_workflow': + new Admin_Workflow_Edit(); + break; + + case 'edit-aw_workflow': + new Admin_Workflow_List(); + break; + + case 'edit-shop_coupon': + new \AW_Admin_Coupons_List(); + break; + } + } + + /** + * Add screen options based on current screen. + */ + public static function screen_options() { + $screen_id = self::get_screen_id(); + + switch ( $screen_id ) { + case 'opt-ins': + $screen_id = 'optins'; // Screen option with dash is not supported. + case 'logs': + case 'carts': + case 'guests': + case 'queue': + add_screen_option( + 'per_page', + [ + 'option' => "automatewoo_{$screen_id}_per_page", + 'default' => 20, + ] + ); + break; + } + } + + + /** + * Handle saving screen option. + * + * @param bool $keep + * @param string $option + * @param int $value + * + * @return bool|int + */ + public static function handle_save_screen_option( $keep, $option, $value ) { + $options = [ + 'automatewoo_logs_per_page', + 'automatewoo_carts_per_page', + 'automatewoo_queue_per_page', + 'automatewoo_guests_per_page', + 'automatewoo_optins_per_page', + ]; + + if ( in_array( $option, $options, true ) ) { + return $value; + } + + return $keep; + } + + /** + * Add menu entries. + */ + public static function admin_menu() { + $sub_menu = []; + $position = '55.6324'; // fix for rare position clash bug + $icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBvbHlnb24gZmlsbD0iIzlFQTNBOCIgcG9pbnRzPSIxMTcuNiwyNzIuNyAxNjYuOSwyNzIuNyAxNDIuMywyMDUuNCAiLz48cGF0aCBmaWxsPSIjOUVBM0E4IiBkPSJNNDY0LDU0LjRINDhDMjUuMSw1NC40LDYuNCw3My4xLDYuNCw5NnYzMjBjMCwyMi45LDE4LjcsNDEuNiw0MS42LDQxLjZoNDE2YzIyLjksMCw0MS42LTE4LjcsNDEuNi00MS42Vjk2QzUwNS42LDczLjEsNDg2LjksNTQuNCw0NjQsNTQuNHogTTE5My4zLDM0NS4xbC0xNC45LTQwLjdIMTA2bC0xNC44LDQwLjdINTQuNkwxMjMsMTY2LjloNDAuMkwyMzEsMzQ1LjFIMTkzLjN6IE00MDguMSwzNDUuMWgtMzUuN2wtNDAuNy0xMjYuOUwyOTEsMzQ1LjFoLTM2LjJsLTQ5LjUtMTc4LjJIMjQybDMyLjcsMTIyLjZsMzkuNS0xMjIuNmgzNS45TDM4OS45LDI5MEw0MjIsMTY2LjloMzUuNEw0MDguMSwzNDUuMXoiLz48L2c+PC9zdmc+'; + + add_menu_page( + __( 'AutomateWoo', 'automatewoo' ), + __( 'AutomateWoo', 'automatewoo' ), + 'manage_woocommerce', + 'automatewoo', + [ 'AutomateWoo\Admin', 'load_controller' ], + $icon, + $position + ); + + $sub_menu['dashboard'] = [ + 'title' => __( 'Dashboard', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + // Workflows menu group + $sub_menu['workflows'] = [ + 'title' => __( 'Workflows', 'automatewoo' ), + 'slug' => 'edit.php?post_type=aw_workflow', + ]; + + $sub_menu['logs'] = [ + 'title' => __( 'Logs', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + $sub_menu['queue'] = [ + 'title' => __( 'Queue', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + if ( Options::abandoned_cart_enabled() ) { + $sub_menu['carts'] = [ + 'title' => __( 'Carts', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + } + + $sub_menu['guests'] = [ + 'title' => __( 'Guests', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + $sub_menu['opt-ins'] = [ + 'title' => Options::optin_enabled() ? __( 'Opt-ins', 'automatewoo' ) : __( 'Opt-outs', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + $sub_menu['reports'] = [ + 'title' => __( 'Reports', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + 'enabled' => ! HPOS_Helper::is_HPOS_enabled(), + ]; + + $sub_menu['tools'] = [ + 'title' => __( 'Tools', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + $sub_menu['settings'] = [ + 'title' => __( 'Settings', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + $sub_menu['preview'] = [ + 'title' => __( 'Preview', 'automatewoo' ), + 'function' => [ __CLASS__, 'load_controller' ], + ]; + + $sub_menu['data-upgrade'] = [ + 'title' => __( 'AutomateWoo Data Update', 'automatewoo' ), + 'function' => [ __CLASS__, 'page_data_upgrade' ], + ]; + + foreach ( $sub_menu as $key => $item ) { + if ( empty( $item['function'] ) ) { + $item['function'] = ''; + } + if ( empty( $item['capability'] ) ) { + $item['capability'] = 'manage_woocommerce'; + } + if ( empty( $item['slug'] ) ) { + $item['slug'] = 'automatewoo-' . $key; + } + if ( empty( $item['page_title'] ) ) { + $item['page_title'] = $item['title']; + } + + $is_enabled = $item['enabled'] ?? true; + + add_submenu_page( $is_enabled ? 'automatewoo' : 'automatewoo_disabled', $item['page_title'], $item['title'], $item['capability'], $item['slug'], $item['function'] ); + + if ( $key === 'workflows' ) { + do_action( 'automatewoo/admin/submenu_pages', 'automatewoo' ); + } + } + + if ( WC()->is_wc_admin_active() ) { + wc_admin_register_page( + [ + 'id' => 'automatewoo-manual-workflow-runner', + 'title' => __( 'Manual Workflow Runner', 'automatewoo' ), + 'parent' => 'automatewoo', + 'path' => '/automatewoo/manual-workflow-runner', + ] + ); + } + } + + /** + * This function alters some items in AutomateWoo submenu + * This is because we need to add .hide-if-js classname in the submenu for hide them in Calypso for wp.com + * The classes are usually loaded in position 4 in the submenu. + * + * @see Menu::migrate_menu_items for a reference of how WC Admin loads this class. (https://github.com/woocommerce/woocommerce/blob/47e4d918c91ea980c41f4567e823256acbac4317/plugins/woocommerce/src/Admin/Features/Navigation/Menu.php#L636) + * @param array $menu Menu items + * @return array Menu items + */ + public static function alter_menu( $menu ) { + global $submenu; + + if ( isset( $submenu['automatewoo'] ) ) { + foreach ( $submenu['automatewoo'] as $index => $submenu_item ) { + if ( + $submenu_item[0] === 'AutomateWoo' || + $submenu_item[0] === 'AutomateWoo Data Update' || + $submenu_item[0] === 'Manual Workflow Runner' || + $submenu_item[0] === 'Preview' + ) { + if ( isset( $submenu_item[4] ) ) { + $submenu_item[4] .= ' hide-if-js'; // if there are some classes already, concat the new one + } else { + $submenu_item[] = 'hide-if-js'; // Otherwise, add the new class + } + + // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $submenu['automatewoo'][ $index ] = $submenu_item; + } + } + } + + return $menu; + } + + /** + * Highlight the correct top level admin menu item + */ + public static function menu_highlight() { + global $parent_file, $post_type; + + switch ( $post_type ) { + case 'aw_workflow': + // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited + $parent_file = 'automatewoo'; + break; + } + } + + /** + * Filter to highlight submenu that cannot be handled well in WordPress core. + * + * @param string|null $submenu_file + * @param string $parent_file + * + * @return string|null + */ + public static function submenu_highlight( $submenu_file, $parent_file ) { + // To highlight the "Workflows" submenu for the "Add New Workflow" page, + // it makes the `$submenu_file` match the "Workflows" submenu's slug registered + // in the `self::admin_menu`. + // + // Ref: + // - https://github.com/WordPress/wordpress-develop/blob/5.9.0/src/wp-admin/menu-header.php#L40-L48 + // - https://github.com/WordPress/wordpress-develop/blob/5.9.0/src/wp-admin/menu-header.php#L223-L227 + if ( + $parent_file === 'automatewoo' && + PageController::get_instance()->get_current_screen_id() === 'aw_workflow-add' + ) { + return 'edit.php?post_type=aw_workflow'; + } + + return $submenu_file; + } + + /** + * Register admin scripts. + */ + public static function register_scripts() { + + if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { + $url = AW()->admin_assets_url( '/js' ); + $suffix = ''; + } else { + $url = AW()->admin_assets_url( '/js/min' ); + $suffix = '.min'; + } + + wp_register_script( 'js-cookie', WC()->plugin_url() . "/assets/js/js-cookie/js.cookie{$suffix}.js", [], '2.1.4', true ); + + wp_register_script( 'automatewoo', "{$url}/automatewoo{$suffix}.js", [ 'jquery', 'jquery-ui-datepicker', 'jquery-tiptip', 'backbone', 'underscore' ], AW()->version, false ); + wp_register_script( 'automatewoo-validate', "{$url}/validate{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + wp_register_script( 'automatewoo-tracks', "{$url}/tracks{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + wp_register_script( 'automatewoo-workflows', "{$url}/workflows{$suffix}.js", [ 'automatewoo', 'automatewoo-validate', 'automatewoo-modal', 'automatewoo-tracks', 'wp-util' ], AW()->version, false ); + wp_register_script( 'automatewoo-variables', "{$url}/variables{$suffix}.js", [ 'automatewoo-modal', 'clipboard' ], AW()->version, false ); + wp_register_script( 'automatewoo-tools', "{$url}/tools{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + wp_register_script( 'automatewoo-sms-test', "{$url}/sms-test{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + wp_register_script( 'automatewoo-modal', "{$url}/modal{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + wp_register_script( 'automatewoo-rules', "{$url}/rules{$suffix}.js", [ 'automatewoo', 'automatewoo-workflows' ], AW()->version, false ); + wp_register_script( 'automatewoo-dashboard', "{$url}/dashboard{$suffix}.js", [ 'automatewoo', 'automatewoo-modal', 'jquery-masonry', 'flot', 'flot-resize', 'flot-time', 'flot-pie', 'flot-stack' ], AW()->version, false ); + wp_register_script( 'automatewoo-preview', "{$url}/preview{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + wp_register_script( 'automatewoo-settings', "{$url}/settings{$suffix}.js", [ 'automatewoo' ], AW()->version, false ); + + global $wp_locale; + + wp_localize_script( 'automatewoo-dashboard', 'automatewooDashboardLocalizeScript', [] ); + + wp_localize_script( + 'automatewoo-validate', + 'automatewooValidateLocalizedErrorMessages', + [ + 'noVariablesSupport' => __( 'This field does not support variables.', 'automatewoo' ), + /* translators: Variable name. */ + 'invalidDataType' => __( "Variable '%s' is not available with the selected trigger. Please only use variables listed in the the variables box.", 'automatewoo' ), + /* translators: Variable name. */ + 'invalidVariable' => __( "Variable '%s' is not valid. Please only use variables listed in the variables box.", 'automatewoo' ), + 'noTrigger' => __( 'Choose a trigger before selecting a variable.', 'automatewoo' ), + ] + ); + + $settings = [ + 'url' => [ + 'admin' => admin_url(), + 'ajax' => admin_url( 'admin-ajax.php' ), + ], + 'locale' => [ + 'month_abbrev' => array_values( $wp_locale->month_abbrev ), + 'currency_symbol' => get_woocommerce_currency_symbol(), + 'currency_decimal_separator' => wc_get_price_decimal_separator(), + 'currency_thousand_separator' => wc_get_price_thousand_separator(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + ], + 'nonces' => [ + 'remove_notice' => wp_create_nonce( 'aw-remove-notice' ), + 'aw_dismiss_system_error_notice' => wp_create_nonce( 'aw_dismiss_system_error_notice' ), + 'aw_toggle_workflow_status' => wp_create_nonce( 'aw_toggle_workflow_status' ), + ], + ]; + + wp_localize_script( + 'automatewoo', + 'automatewooLocalizeScript', + apply_filters( 'automatewoo/admin/js_settings', $settings ) + ); + + wp_localize_script( + 'automatewoo-preview', + 'automatewooPreviewLocalizeScript', + [ + 'nonce' => wp_create_nonce( 'aw_send_test_email' ), + ] + ); + + wp_localize_script( + 'automatewoo-sms-test', + 'automatewooSmsTestLocalizeScript', + [ + 'nonce' => wp_create_nonce( 'aw_test_sms' ), + ] + ); + } + + /** + * Register admin styles. + */ + public static function register_styles() { + wp_register_style( + 'automatewoo-main', + AW()->admin_assets_url( '/css/aw-main.css' ), + [], + AW()->version + ); + wp_register_style( 'automatewoo-preview', AW()->admin_assets_url( '/css/preview.css' ), [], AW()->version ); + } + + /** + * Enqueue scripts based on screen id + */ + public static function enqueue_scripts_and_styles() { + $screen_id = self::get_current_screen_id(); + $is_aw_screen = self::is_automatewoo_screen(); + + // Load WC Admin styles for AW pages before our own styles + if ( defined( 'WC_ADMIN_APP' ) && $is_aw_screen ) { + wp_enqueue_style( WC_ADMIN_APP ); + } + + wp_enqueue_script( 'automatewoo' ); + wp_enqueue_style( 'automatewoo-main' ); + + if ( self::should_react_ui_be_loaded() ) { + wp_enqueue_style( + 'automatewoo-webpack', + AW()->admin_assets_url( '/build/index.css' ), + [ 'wc-admin-app' ], + AW()->version + ); + } + + if ( $is_aw_screen ) { + wp_enqueue_script( 'woocommerce_admin' ); + wp_enqueue_script( 'wc-enhanced-select' ); + wp_enqueue_script( 'jquery-tiptip' ); + wp_enqueue_script( 'jquery-ui-sortable' ); + wp_enqueue_script( 'jquery-ui-autocomplete' ); + wp_enqueue_script( 'js-cookie' ); + + wp_enqueue_style( 'woocommerce_admin_styles' ); + wp_enqueue_style( 'jquery-ui-style' ); + } + + if ( $screen_id === 'automatewoo_page_automatewoo-preview' ) { + wp_enqueue_script( 'automatewoo-preview' ); + wp_enqueue_style( 'automatewoo-preview' ); + } + } + + /** + * Should the react UI load? + * + * If the current page is an AW php page or a WC Admin JS-powered page, then yes. + * + * @since 5.1.2 + * + * @return bool + */ + protected static function should_react_ui_be_loaded() { + return WC()->is_wc_admin_active() && ( self::is_automatewoo_screen() || wc_admin_is_registered_page() ); + } + + /** + * Load react powered admin JS. + * + * @since 5.0.0 + */ + public static function load_react_ui_scripts() { + if ( ! self::should_react_ui_be_loaded() ) { + return; + } + + $asset_file_path = AW()->admin_path() . '/assets/build/index.asset.php'; + + if ( ! file_exists( $asset_file_path ) ) { + return; + } + + $asset_file = (array) include $asset_file_path; + $dependencies = isset( $asset_file['dependencies'] ) ? $asset_file['dependencies'] : []; + // Depend on main admin script for plugin settings + $dependencies = array_merge( $dependencies, [ 'jquery', 'automatewoo', 'wc-settings' ] ); + $version = isset( $asset_file['version'] ) ? $asset_file['version'] : false; + $handle = 'automatewoo-react-ui'; + + wp_enqueue_script( + $handle, + AW()->admin_assets_url() . '/build/index.js', + $dependencies, + $version, + true + ); + wp_set_script_translations( $handle, 'automatewoo', AW()->path( '/languages' ) ); + } + + /** + * Return filtered screen ids. + * + * @return array List of screen ids. + */ + public static function screen_ids() { + $ids = []; + $prefix = 'automatewoo_page_automatewoo'; + + $ids[] = "$prefix-dashboard"; + $ids[] = "$prefix-logs"; + $ids[] = "$prefix-reports"; + $ids[] = "$prefix-settings"; + $ids[] = "$prefix-tools"; + $ids[] = "$prefix-carts"; + $ids[] = "$prefix-queue"; + $ids[] = "$prefix-guests"; + $ids[] = "$prefix-opt-ins"; + $ids[] = "$prefix-preview"; + $ids[] = 'aw_workflow'; + $ids[] = 'edit-aw_workflow'; + + return apply_filters( 'automatewoo/admin/screen_ids', $ids ); + } + + + /** + * Add AW screens to the woocommerce screen IDs list. + * Important for admin script loading. + * + * @since 4.4.2 + * + * @param array $screen_ids + * + * @return array + */ + public static function filter_woocommerce_screen_ids( $screen_ids ) { + $screen_ids = array_merge( $screen_ids, self::screen_ids() ); + return $screen_ids; + } + + + /** + * Hide the WC footer message on AW screens. + * + * @since 4.4.2 + * + * @param bool $display + * + * @return bool + */ + public static function filter_woocommerce_display_footer_text( $display ) { + if ( self::is_automatewoo_screen() ) { + $display = false; + } + + return $display; + } + + /** + * Remove the WC help tab on AW screens + * + * @since 4.4.2 + */ + public static function remove_woocommerce_help_tab() { + if ( self::is_automatewoo_screen() ) { + $screen = get_current_screen(); + $screen->remove_help_tabs(); + } + } + + /** + * Dynamic replace top level menu + */ + public static function replace_top_level_menu() { + ?> + + admin_path( '/views/' ); + } + + include "{$path}{$view}.php"; // nosemgrep No user input reached. This is for loading our views. + } + + /** + * Load controller. + */ + public static function load_controller() { + $screen_id = self::get_screen_id(); + + if ( ! $screen_id ) { + return; + } + + if ( $screen_id === 'toplevel_page_automatewoo' ) { + $screen_id = 'dashboard'; + } + + $controller = Admin\Controllers::get( $screen_id ); + if ( $controller ) { + $controller->handle(); + } + } + + /** + * Get the current screen ID. + * + * @return string|bool + */ + public static function get_screen_id() { + $screen_id = self::get_current_screen_id(); + + // Replace hidden screen ID's without AutomateWoo as parent. + $screen_id = str_replace( 'admin_page_automatewoo-', '', $screen_id ); + + if ( ! $screen_id ) { + return false; + } + + $base_screen = sanitize_title( __( 'AutomateWoo', 'automatewoo' ) ); // required if plugin name was translated + + return str_replace( $base_screen . '_page_automatewoo-', '', $screen_id ); + } + + /** + * Save settings on wp_loaded + */ + public static function save_settings() { + $controller = Admin\Controllers::get( 'settings' ); + if ( $controller ) { + $controller->save(); + } + } + + /** + * Check if we are on a specific page. + * + * @param string $page + * @return bool + */ + public static function is_page( $page ) { + + $current_page = Clean::string( aw_request( 'page' ) ); + $current_tab = Clean::string( aw_request( 'tab' ) ); + + switch ( $page ) { + case 'dashboard': + return $current_page === 'automatewoo-dashboard'; + case 'settings': + return $current_page === 'automatewoo-settings'; + case 'reports': + return $current_page === 'automatewoo-reports'; + case 'status': + return $current_page === 'automatewoo-settings' && $current_tab === 'status'; + } + + return false; + } + + /** + * Display an admin notice. + * + * @param string $type (warning,error,success) + * @param string $strong highlighted notice content (text or html) + * @param string $more notice content (text or html) + * @param string $classes extra classes to add to the notice (eg., is-dismissible) + * @param string $button_text text to display on the primary button (not displayed if empty) + * @param string $button_link link for the button (not displayed if empty) + * @param string $button_class extra classes to add to the button + */ + public static function notice( $type, $strong, $more = '', $classes = '', $button_text = '', $button_link = '', $button_class = '' ) { + self::get_view( + 'simple-notice', + [ + 'type' => $type, + 'class' => $classes, + 'strong' => $strong, + 'message' => $more, + 'button_text' => $button_text, + 'button_link' => $button_link, + 'button_class' => $button_class, + ] + ); + } + + /** + * Add WooCommerce Reports screen IDs. + * + * @param array $ids + * @return array + */ + public static function inject_woocommerce_reports_screen_ids( $ids ) { + $ids[] = 'automatewoo_page_automatewoo-reports'; + return $ids; + } + + /** + * Add editor styles. + * + * @param array $stylesheets + * @return array + */ + public static function add_editor_styles( $stylesheets ) { + $stylesheets[] = AW()->admin_assets_url( '/css/editor.css' ); + return $stylesheets; + } + + /** + * Add a meta box. + * + * @param string $id + * @param string $title + * @param callable $callback + * @param null $screen + * @param string $context + * @param string $priority + * @param null $callback_args + */ + public static function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) { + $id = 'aw_' . $id; + + add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args ); + + add_filter( "postbox_classes_{$screen}_{$id}", [ __CLASS__, 'inject_postbox_class' ] ); + } + + /** + * Add postbox class. + * + * @param array $classes + * + * @return array + */ + public static function inject_postbox_class( $classes ) { + $classes[] = 'automatewoo-metabox'; + $classes[] = 'no-drag'; + return $classes; + } + + /** + * Add hidden form inputs. + * + * @param array $vars + */ + public static function get_hidden_form_inputs_from_query( $vars ) { + foreach ( $vars as $var ) { + // Adding a nonce is handled by the calling functions. + // Validating of sanatized input is done when the values are read (we are copying the values here). + // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput + if ( empty( $_GET[ $var ] ) ) { + continue; + } + + echo ''; + // phpcs:enable + } + } + + + /** + * Display a help tip. + * + * @param string $tip The tip to display. Not expected to be escaped. + * @param bool $pull_right Whether the tip should include the automatewoo-help-tip--right class + */ + public static function help_tip( $tip, $pull_right = true ) { + $tip = wc_sanitize_tooltip( $tip ); + if ( empty( $tip ) ) { + return; + } + + $classes = array_filter( + [ + 'automatewoo-help-tip', + 'woocommerce-help-tip', + $pull_right ? 'automatewoo-help-tip--right' : '', + ] + ); + + printf( '', esc_attr( join( ' ', $classes ) ), esc_attr( $tip ) ); + } + + + /** + * Return an AutomateWoo badge. + * + * @param string $type + * @param string $dashicon + * @param bool $tip + * @return string + */ + public static function badge( $type, $dashicon, $tip = false ) { + $html = ''; + $html .= ''; + $html .= ''; + return $html; + } + + + /** + * Get a help link. + * + * @param string $url + * @param bool $pull_right + * @return string + */ + public static function help_link( $url, $pull_right = true ) { + return ''; + } + + + /** + * Get documentation link. + * + * @param string $page + * @param string|bool $utm_source + * @param string|bool $utm_campaign + * @return string + */ + public static function get_docs_link( $page = '', $utm_source = false, $utm_campaign = false ) { + return esc_url_raw( self::get_website_link( "docs/$page", $utm_source, $utm_campaign ) ); + } + + /** + * Get a website link. + * + * @param string $page + * @param string|bool $utm_source + * @param string|bool $utm_campaign + * @return string + */ + public static function get_website_link( $page = '', $utm_source = false, $utm_campaign = false ) { + $url = 'https://automatewoo.com/' . ( $page ? trailingslashit( $page ) : '' ); + + if ( $utm_source ) { + // SEMGREP WARNING EXPLANATION + // This is escaped in the consumer function. + $url = add_query_arg( + [ + 'utm_source' => $utm_source, + 'utm_medium' => 'plugin', + 'utm_campaign' => $utm_campaign ? $utm_campaign : 'plugin-links', + ], + $url + ); + } + + return $url; + } + + /** + * Get WooCommerce.com marketplace product link. + * + * @since 3.7.0 + * + * @param string $product + * + * @return string + */ + public static function get_marketplace_product_link( $product = 'automatewoo' ) { + return "https://woocommerce.com/products/$product/"; + } + + /** + * Output loader + */ + public static function cache_preview_loader() { + // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged + @header_remove( 'Cache-Control' ); + @header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + DAY_IN_SECONDS ) . ' GMT' ); + // phpcs:enable + } + + + /** + * Create a new page. + * + * @param string $slug + * @param string $page_title + * @param string $page_content + * @param string $option + * @return int|bool Page ID + */ + public static function create_page( $slug, $page_title, $page_content, $option ) { + + if ( get_option( $option ) ) { + return false; // page is already defined in settings + } + + $page_data = [ + 'post_status' => 'publish', + 'post_type' => 'page', + 'post_author' => 1, + 'post_name' => $slug, + 'post_title' => $page_title, + 'post_content' => $page_content, + 'comment_status' => 'closed', + ]; + + $page_id = wp_insert_post( $page_data ); + update_option( $option, $page_id, false ); + + return $page_id; + } + + /** + * Return the current WP screen ID. + * + * @since 4.4.2 + * + * @return bool|string + */ + public static function get_current_screen_id() { + $screen = get_current_screen(); + return $screen ? $screen->id : false; + } + + /** + * Is the current WP screen an AutomateWoo screen? + * + * @since 4.7.0 + * @return bool + */ + public static function is_automatewoo_screen() { + return in_array( self::get_current_screen_id(), self::screen_ids(), true ); + } + + /** + * Unhook all admin notices. + * + * @since 4.4.0 + */ + public static function remove_admin_notices() { + remove_all_actions( 'admin_notices' ); + } + + /** + * Get marketplace subscriptions tab URL. + * + * @since 4.7.0 + * + * @return string + */ + public static function get_marketplace_subscriptions_tab_url() { + return add_query_arg( + [ + 'page' => 'wc-addons', + 'section' => 'helper', + ], + admin_url( 'admin.php' ) + ); + } +} diff --git a/admin/ajax.php b/admin/ajax.php new file mode 100644 index 0000000..c61a586 --- /dev/null +++ b/admin/ajax.php @@ -0,0 +1,763 @@ + $trigger, + 'workflow' => $workflow, + ]); + + $fields = ob_get_clean(); + + wp_send_json_success([ + 'fields' => $fields, + 'trigger' => Admin_Workflow_Edit::get_trigger_data( $trigger ), + ]); + } + + + /** + * Retrieve action fields and echo JSON. + */ + public static function fill_action_fields() { + + if ( ! self::is_authorized() ) { + die; + } + + $action_name = Clean::string( aw_request( 'action_name' ) ); + $action_number = Clean::string( aw_request( 'action_number' ) ); + + if ( '' === $action_name ) { + wp_send_json_success( + [ + 'fields' => '', + 'title' => 'New Action', + 'description' => '', + ] + ); + } + + $action = Actions::get( $action_name ); + + ob_start(); + + Admin::get_view( + 'action-fields', + [ + 'action' => $action, + 'action_number' => $action_number, + ] + ); + + $fields = ob_get_clean(); + + wp_send_json_success( + [ + 'fields' => $fields, + 'title' => $action->get_title( true ), + 'description' => $action->get_description_html(), + ] + ); + } + + + /** + * Search for workflows and echo JSON. + */ + public static function json_search_workflows() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + ob_start(); + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::workflows( $term ); + } + + + /** + * Search customers, includes guests customers + */ + static function json_search_customers() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + ob_start(); + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::customers( $term ); + } + + /** + * Search for products and variations, but not variable products. + */ + static function json_search_products_and_variations_not_variable() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::products( $term, true, false ); + } + + /** + * Search for products excluding variable and variation products. + */ + static function json_search_products_not_variations_not_variable() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::products( $term, false, false ); + } + + + /** + * Search for products and echo json + */ + public static function json_search_attribute_terms() { + + if ( ! current_user_can( 'manage_woocommerce' ) ) + die; + + if ( empty( $_GET['term'] ) || empty( $_GET['sibling'] ) ) { + die; + } + + $search = Clean::string( stripslashes( $_GET['term'] ) ); + $sibling = Clean::string( stripslashes( $_GET['sibling'] ) ); + + $terms = get_terms( 'pa_' . $sibling, [ + 'hide_empty' => false, + 'search' => $search + ]); + + $found = []; + + if ( ! $terms || is_wp_error($terms) ) + die(); + + foreach ( $terms as $term ) { + $found[ $term->term_id . '|' . $term->taxonomy ] = rawurldecode( $term->name ); + } + + wp_send_json( $found ); + } + + + + /** + * Search for products and echo json + */ + public static function json_search_taxonomy_terms() { + if ( ! Permissions::can_manage() ) { + die; + } + + ob_start(); + + $search = Clean::string( stripslashes( aw_get_url_var( 'term' ) ) ); + $sibling = Clean::string( stripslashes( aw_get_url_var( 'sibling' ) ) ); + + if ( empty( $search ) || empty($sibling) ) { + die; + } + + $terms = get_terms( + $sibling, + [ + 'hide_empty' => false, + 'search' => $search + ] + ); + + + $found = []; + + if ( ! $terms || is_wp_error($terms) ) + die; + + foreach ( $terms as $term ) { + $found[ $term->term_id . '|' . $term->taxonomy ] = rawurldecode( $term->name ); + } + + wp_send_json( $found ); + } + + /** + * Search for coupons and echo JSON. + */ + public static function json_search_coupons() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::coupons( $term, true, false ); + } + + /** + * Search for recurring coupons and echo JSON. + */ + public static function json_search_coupons_recurring() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::coupons( $term, true, true ); + } + + /** + * Search for sensei courses and echo JSON. + * + * @since 5.6.10 + */ + public static function json_search_sensei_courses() { + if ( ! current_user_can( 'manage_sensei' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::sensei_data( $term, 'course' ); + } + + /** + * Search for sensei lessons and echo JSON. + * + * @since 5.6.10 + */ + public static function json_search_sensei_lessons() { + if ( ! current_user_can( 'manage_sensei' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::sensei_data( $term, 'lesson' ); + } + + /** + * Search for sensei quizzes and echo JSON. + * + * @since 5.6.10 + */ + public static function json_search_sensei_quizzes() { + if ( ! current_user_can( 'manage_sensei' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::sensei_data( $term, 'quiz' ); + } + + /** + * Search for sensei questions and echo JSON. + * + * @since 5.6.10 + */ + public static function json_search_sensei_questions() { + if ( ! current_user_can( 'manage_sensei' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::sensei_data( $term, 'question' ); + } + + /** + * Search for sensei groups and echo JSON. + * + * @since 5.6.10 + */ + public static function json_search_sensei_groups() { + if ( ! current_user_can( 'manage_sensei' ) ) { + die; + } + + $term = Clean::string( wp_unslash( aw_get_url_var( 'term' ) ) ); + JSON_Search::sensei_data( $term, 'group' ); + } + + static function email_preview_iframe() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + $type = Clean::string( aw_request('type') ); + $args = Clean::recursive( aw_request('args') ); + + switch ( $type ) { + + case 'workflow_action': + try { + $action = Preview_Data::generate_preview_action( $args['workflow_id'], $args['action_number'] ); + } catch ( InvalidPreviewData $e ) { + return wp_die( $e->getMessage() ); + } + + do_action( 'automatewoo/action/before_preview', $action ); + + $action->workflow->setup(); + + echo $action->get_preview(); + + $action->workflow->cleanup(); + + do_action( 'automatewoo/action/after_preview', $action ); + + break; + + default: + do_action( 'automatewoo/email_preview/html', $type, $args ); + } + + exit(); + } + + + /** + * Sends a test to supplied emails + */ + static function send_test_email() { + + if ( ! self::is_authorized() ) { + die; + } + + $type = Clean::string( aw_request('type') ); + $args = Clean::recursive( aw_request('args') ); + $to = Clean::string( aw_request('to_emails') ); + + // save the to field + update_user_meta( get_current_user_id(), 'automatewoo_email_preview_test_emails', $to ); + + $to = Emails::parse_multi_email_field( $to ); + + switch ( $type ) { + + case 'workflow_action': + try { + $action = Preview_Data::generate_preview_action( $args['workflow_id'], $args['action_number'], 'test' ); + } catch ( InvalidPreviewData $e ) { + return wp_die( $e->getMessage() ); + } + + $action->workflow->setup(); + $current_user = get_current_user_id(); + // Temporarily remove the current user since no current user is typically exists when running a workflow + // phpcs:ignore + wp_set_current_user( 0 ); + + $result = $action->run_test( [ 'recipients' => $to ] ); + + // Rollback to the previous user. + // phpcs:ignore + wp_set_current_user( $current_user ); + $action->workflow->cleanup(); + + break; + + default: + do_action( 'automatewoo/email_preview/send_test', $type, $to, $args ); + $result = false; + } + + if ( $result instanceof WP_Error ) { + wp_send_json_error( + [ + /* translators: %s: Error message */ + 'message' => sprintf( __( 'Error: %s', 'automatewoo' ), $result->get_error_message() ), + ] + ); + } + + wp_send_json_success([ + 'message' => sprintf( + __( 'Success! %s email%s sent.', 'automatewoo' ), + count($to), + count($to) == 1 ? '' : 's' + ) + ]); + } + + + + static function test_sms() { + if ( ! self::is_authorized() ) { + die; + } + + $from = Clean::string( aw_request('from') ); + $auth_id = Clean::string( aw_request('auth_id') ); + $auth_token = Clean::string( aw_request('auth_token') ); + $test_message = Clean::string( aw_request('test_message') ); + $test_recipient = Clean::string( aw_request('test_recipient') ); + + $twilio = new Integration_Twilio( $from, $auth_id, $auth_token ); + + $twilio->log_errors = false; // errors will be visible + + $request = $twilio->send_sms( $test_recipient, $test_message, $from ); + + if ( $request->is_successful() ) { + wp_send_json_success( [ + 'message' => __('Message sent.','automatewoo') + ] ); + } + else { + wp_send_json_error( [ + 'message' => $twilio->get_request_error_message( $request ) + ] ); + } + } + + + static function database_update() { + + $verify = wp_verify_nonce( $_REQUEST['nonce'], 'automatewoo_database_upgrade' ); + $plugin_slug = Clean::string( aw_request('plugin_slug') ); + + if ( ! $verify ) { + wp_send_json_error( __( 'Permission error.', 'automatewoo' ) ); + } + + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + if ( $plugin_slug == AW()->plugin_slug ) { + // updating the primary plugin + $complete = Installer::run_database_updates(); + + wp_send_json_success([ + 'complete' => $complete, + 'items_processed' => Installer::$db_update_items_processed + ]); + } + else { + // updating an addon + $addon = Addons::get( $plugin_slug ); + + if ( ! $addon ) { + wp_send_json_error(__( 'Add-on could not be updated', 'automatewoo' ) ); + } + + $addon->do_database_update(); + + wp_send_json_success([ + 'complete' => true + ]); + } + } + + + static function database_update_items_to_process_count() { + if ( ! self::is_authorized() ) { + die; + } + + $plugin_slug = Clean::string( aw_request('plugin_slug') ); + + if ( $plugin_slug == AW()->plugin_slug ) { + $count = Installer::get_database_update_items_to_process_count(); + } + else { + $count = 0; // batch processor not yet supported for addons + } + + wp_send_json_success([ + 'items_to_process' => $count + ]); + } + + + /** + * To preview an action save temporarily in the options table. + */ + static function save_preview_data() { + if ( ! self::is_authorized() ) { + die; + } + + $workflow = Factory::get( aw_get_post_var( 'workflow_id' ) ); + $trigger_name = Clean::string( aw_get_post_var( 'trigger_name' ) ); + $action_fields = $workflow->sanitize_action_fields( aw_get_post_var( 'action_fields' ) ); + + if ( ! $trigger_name || ! is_array( $action_fields ) || ! $workflow ) { + wp_send_json_error(); + } + + $preview_data = [ + 'trigger_name' => $trigger_name, + 'action_fields' => $action_fields, + ]; + + update_option( 'aw_wf_preview_data_' . $workflow->get_id(), $preview_data, false ); + + wp_send_json_success(); + } + + + /** + * + */ + static function dismiss_system_error_notice() { + if ( ! self::is_authorized() ) { + die; + } + + delete_transient('automatewoo_background_system_check_errors'); + + wp_send_json_success(); + } + + + static function get_rule_select_choices() { + + if ( ! current_user_can( 'manage_woocommerce' ) ) + die; + + if ( ! $rule_name = Clean::string( aw_request('rule_name') ) ) + die; + + $rule_object = Rules::get( $rule_name ); + + if ( $rule_object->type == 'select' ) { + wp_send_json_success([ + 'select_choices' => $rule_object->get_select_choices() + ]); + } + + die; + } + + + /** + * Display content for log details modal + */ + static function modal_log_info() { + + if ( ! current_user_can( 'manage_woocommerce' ) ) + die; + + if ( $log = Log_Factory::get( absint( aw_request('log_id') ) ) ) { + Admin::get_view( 'modal-log-info', [ 'log' => $log ] ); + die; + } + + die( __( 'No log found.', 'automatewoo' ) ); + } + + + static function modal_queue_info() { + + if ( ! current_user_can( 'manage_woocommerce' ) ) + die; + + if ( $event = Queued_Event_Factory::get( absint( aw_request('queued_event_id') ) ) ) { + Admin::get_view( 'modal-queued-event-info', [ 'event' => $event ] ); + die; + } + + die( __( 'No queued event found.', 'automatewoo' ) ); + } + + + static function modal_variable_info() { + if ( ! current_user_can( 'manage_woocommerce' ) ) { + die; + } + + $variable = Variables::get_variable( Clean::string( aw_request( 'variable' ) ) ); + + if ( $variable ) { + Admin::get_view( 'modal-variable-info', [ + 'variable' => $variable + ]); + die; + } + + wp_die( __( 'Variable not found.', 'automatewoo' ) ); + } + + + static function modal_cart_info() { + + if ( ! current_user_can( 'manage_woocommerce' ) ) + die; + + if ( $cart = Cart_Factory::get( absint( aw_request('cart_id') ) ) ) { + Admin::get_view( 'modal-cart-info', [ 'cart' => $cart ] ); + die; + } + + die( __( 'No cart found.', 'automatewoo' ) ); + } + + + + static function toggle_workflow_status() { + + if ( ! self::is_authorized() ) { + die; + } + + $workflow = Factory::get( aw_request( 'workflow_id' ) ); + $new_state = Clean::string( aw_request( 'new_state' ) ); + + if ( ! $workflow || ! $new_state ) + die; + + $workflow->update_status( $new_state === 'on' ? 'active' : 'disabled' ); + + wp_send_json_success(); + } + + + static function update_dynamic_action_select() { + + if ( ! self::is_authorized() ) { + die; + } + + $action_name = Clean::string( aw_request( 'action_name' ) ); + $target_field_name = Clean::string( aw_request( 'target_field_name' ) ); + $reference_field_value = Clean::string( aw_request( 'reference_field_value' ) ); + + $options = []; + + if ( $reference_field_value ) { + $action = Actions::get( $action_name ); + $options = $action->get_dynamic_field_options( $target_field_name, $reference_field_value ); + } + + wp_send_json_success( $options ); + } + + /** + * Respond dynamic field options for a given trigger field. + * + * @since 5.6.6 + */ + static function update_dynamic_trigger_options_select() { + if ( ! self::is_authorized() ) { + die; + } + + $trigger_name = Clean::string( aw_request( 'trigger_name' ) ); + $target_field_name = Clean::string( aw_request( 'target_field_name' ) ); + $reference_field_value = Clean::string( aw_request( 'reference_field_value' ) ); + + $options = []; + + if ( $reference_field_value ) { + $trigger = Triggers::get( $trigger_name ); + $options = $trigger->get_dynamic_field_options( $target_field_name, $reference_field_value ); + } + + wp_send_json_success( $options ); + } + + /** + * Verifies if user is authorized to perform an ajax request. + * We do so by checking if is able to manage WooCommerce and also checking the nonce. + * + * @since 5.7.6 + * + * @return bool True if is authorized, false otherwise + */ + static function is_authorized() { + $nonce = Clean::string( aw_request( 'nonce' ) ); + + if ( ! current_user_can( 'manage_woocommerce' ) || ! wp_verify_nonce( $nonce, aw_request( 'action' ) ) ) { + return false; + } + + return true; + } +} diff --git a/admin/assets/.externalized-admin.json b/admin/assets/.externalized-admin.json new file mode 100644 index 0000000..c219852 --- /dev/null +++ b/admin/assets/.externalized-admin.json @@ -0,0 +1 @@ +["#external/automatewoo/modal.js","@babel/runtime/regenerator","@woocommerce/components","@woocommerce/csv-export","@woocommerce/currency","@woocommerce/data","@woocommerce/date","@woocommerce/navigation","@woocommerce/number","@woocommerce/settings","@woocommerce/tracks","@wordpress/api-fetch","@wordpress/components","@wordpress/compose","@wordpress/data","@wordpress/data-controls","@wordpress/date","@wordpress/dom","@wordpress/element","@wordpress/hooks","@wordpress/i18n","@wordpress/url","@wordpress/warning","lodash","react"] \ No newline at end of file diff --git a/admin/assets/build/analytics-rtl.css b/admin/assets/build/analytics-rtl.css new file mode 100644 index 0000000..4da3dba --- /dev/null +++ b/admin/assets/build/analytics-rtl.css @@ -0,0 +1,2 @@ +.automatewoo-clone.woocommerce-report-table__scroll-point{position:relative;top:-48px}@media(max-width:782px){.automatewoo-clone.woocommerce-report-table__scroll-point{top:-62px}}.woocommerce-feature-enabled-activity-panels .automatewoo-clone.woocommerce-report-table__scroll-point{top:-108px}@media(max-width:782px){.woocommerce-feature-enabled-activity-panels .automatewoo-clone.woocommerce-report-table__scroll-point{top:-122px}}.automatewoo-clone.woocommerce-report-table .woocommerce-search{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.automatewoo-clone.woocommerce-report-table .components-card__header{display:-ms-grid;display:grid;grid-gap:12px;-ms-grid-columns:-webkit-min-content 1fr -webkit-min-content;-ms-grid-columns:min-content 1fr min-content;grid-template-columns:-webkit-min-content 1fr -webkit-min-content;grid-template-columns:min-content 1fr min-content}.automatewoo-clone.woocommerce-report-table .woocommerce-table__compare.components-button{padding:8px}.automatewoo-clone.woocommerce-report-table .woocommerce-ellipsis-menu{justify-self:flex-end}.automatewoo-clone button.woocommerce-table__download-button{color:#000;padding:6px 12px;text-decoration:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.automatewoo-clone button.woocommerce-table__download-button svg{height:24px;margin-left:8px;width:24px}@media(max-width:782px){.automatewoo-clone button.woocommerce-table__download-button svg{margin-left:0}.automatewoo-clone button.woocommerce-table__download-button .woocommerce-table__download-button__label{display:none}} +.aw-conversions-table.woocommerce-report-table .components-card__header{-ms-grid-columns:auto minmax(-webkit-min-content,1fr) auto;-ms-grid-columns:auto minmax(min-content,1fr) auto;grid-template-columns:auto minmax(-webkit-min-content,1fr) auto;grid-template-columns:auto minmax(min-content,1fr) auto} diff --git a/admin/assets/build/analytics.asset.php b/admin/assets/build/analytics.asset.php new file mode 100644 index 0000000..faca9ff --- /dev/null +++ b/admin/assets/build/analytics.asset.php @@ -0,0 +1 @@ + array('automatewoo-modal', 'lodash', 'react', 'regenerator-runtime', 'wc-components', 'wc-csv', 'wc-currency', 'wc-date', 'wc-navigation', 'wc-number', 'wc-settings', 'wc-store-data', 'wc-tracks', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill', 'wp-url'), 'version' => '2640dc095d5442f46ab9'); diff --git a/admin/assets/build/analytics.css b/admin/assets/build/analytics.css new file mode 100644 index 0000000..6b3283e --- /dev/null +++ b/admin/assets/build/analytics.css @@ -0,0 +1,2 @@ +.automatewoo-clone.woocommerce-report-table__scroll-point{position:relative;top:-48px}@media(max-width:782px){.automatewoo-clone.woocommerce-report-table__scroll-point{top:-62px}}.woocommerce-feature-enabled-activity-panels .automatewoo-clone.woocommerce-report-table__scroll-point{top:-108px}@media(max-width:782px){.woocommerce-feature-enabled-activity-panels .automatewoo-clone.woocommerce-report-table__scroll-point{top:-122px}}.automatewoo-clone.woocommerce-report-table .woocommerce-search{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.automatewoo-clone.woocommerce-report-table .components-card__header{display:-ms-grid;display:grid;grid-gap:12px;-ms-grid-columns:-webkit-min-content 1fr -webkit-min-content;-ms-grid-columns:min-content 1fr min-content;grid-template-columns:-webkit-min-content 1fr -webkit-min-content;grid-template-columns:min-content 1fr min-content}.automatewoo-clone.woocommerce-report-table .woocommerce-table__compare.components-button{padding:8px}.automatewoo-clone.woocommerce-report-table .woocommerce-ellipsis-menu{justify-self:flex-end}.automatewoo-clone button.woocommerce-table__download-button{color:#000;padding:6px 12px;text-decoration:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.automatewoo-clone button.woocommerce-table__download-button svg{height:24px;margin-right:8px;width:24px}@media(max-width:782px){.automatewoo-clone button.woocommerce-table__download-button svg{margin-right:0}.automatewoo-clone button.woocommerce-table__download-button .woocommerce-table__download-button__label{display:none}} +.aw-conversions-table.woocommerce-report-table .components-card__header{-ms-grid-columns:auto minmax(-webkit-min-content,1fr) auto;-ms-grid-columns:auto minmax(min-content,1fr) auto;grid-template-columns:auto minmax(-webkit-min-content,1fr) auto;grid-template-columns:auto minmax(min-content,1fr) auto} diff --git a/admin/assets/build/analytics.js b/admin/assets/build/analytics.js new file mode 100644 index 0000000..4cb660a --- /dev/null +++ b/admin/assets/build/analytics.js @@ -0,0 +1,3 @@ +!function(){var e={694:function(e,t,r){"use strict";var n=r(925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,r,a,o,i){if(i!==n){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var r={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return r.PropTypes=r,r}},556:function(e,t,r){e.exports=r(694)()},925:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},942:function(e,t){var r;!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e="",t=0;te.length)&&(t=e.length);for(var r=0,n=Array(t);r1&&void 0!==arguments[1]?arguments[1]:p;return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n="function"==typeof e?e(arguments.length>1?arguments[1]:void 0):e,a=(0,m.getIdsFromQuery)(r);if(a.length<1)return Promise.resolve([]);var o={include:a.join(","),per_page:a.length};return c()({path:(0,u.addQueryArgs)(n,o)}).then((function(e){return e.map(t)}))}}("/automatewoo/workflows",d),labels:{placeholder:(0,o.__)("Type to search for a workflow","automatewoo"),button:(0,o.__)("Single Workflow","automatewoo")},autocompleter:f}}]}]}];function g(e){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},g(e)}function b(e){var t=function(e){if("object"!=g(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=g(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==g(t)?t:t+""}function h(e,t,r){return(t=b(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function v(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function w(e,t){for(var r=0;r2&&void 0!==arguments[2]?arguments[2]:{};if(!e||0===e.length)return null;var n=e.slice(0),a=n.pop();if(a.showFilters(t,r)){var o=(0,m.flattenFilters)(a.filters),i=t[a.param]||a.defaultValue||"all";return(0,P.find)(o,{value:i})}return H(n,t,r)}function W(e){return function(t){return(0,T.format)(e,t)}}function Y(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function K(e){for(var t=1;t0,$=(0,m.getSearchWords)(E).map((function(e){return{key:e,label:e}})),ee=R.data,te=W(ee,G,J),re=te.headers,ne=te.rows,oe=te.summary;(_||y)&&(ne=ne.map((function(e,t){return[K(t)].concat(n(e))})),re=[(Q=e.ids,M=void 0===Q?[]:Q,V=M.length>0,H=V&&M.length===j.length,{cellClassName:"is-checkbox-column",key:"compare",label:(0,i.createElement)(ce.CheckboxControl,{onChange:function(t){var r=e.ids;F(t?r:[])},"aria-label":(0,o.__)("Select All","woocommerce"),checked:H,disabled:!V}),required:!0})].concat(n(re)));var ie=function(e,t){return t?e.map((function(e){return ke(ke({},e),{},{visible:e.required||!t.includes(e.key)})})):e.map((function(e){return ke(ke({},e),{},{visible:e.required||!e.hiddenByDefault})}))}(re,B);return(0,i.createElement)(C.Fragment,null,(0,i.createElement)("div",{className:"woocommerce-report-table__scroll-point automatewoo-clone",ref:N,"aria-hidden":!0}),(0,i.createElement)(s.TableCard,ke({className:ge()("woocommerce-report-table","automatewoo-clone",t),hasSearch:!!b,actions:[O&&O({selectedRows:j}),y&&(0,i.createElement)(s.CompareButton,{key:"compare",className:"woocommerce-table__compare",count:j.length,helpText:w.helpText||(0,o.__)("Check at least two items below to compare","woocommerce"),onClick:function(){y&&(0,m.onQueryChange)("compare")(y,g,j.join(","))},disabled:!X},w.compareButton||(0,o.__)("Compare","woocommerce")),b&&(0,i.createElement)(s.Search,{allowFreeTextSearch:!0,inlineTags:!0,key:"search",onChange:function(t){var r=e.baseSearchQuery,n=e.addCesSurveyForCustomerSearch,a=t.map((function(e){return e.label.replace(",","%2C")}));a.length?((0,m.updateQueryString)(ke(ke(h(h({filter:void 0},g,void 0),b,void 0),r),{},{search:(0,P.uniq)(a).join(",")})),n()):(0,m.updateQueryString)({search:void 0}),(0,Z.recordEvent)("analytics_table_filter",{report:f})},placeholder:w.placeholder||(0,o.__)("Search by item name","woocommerce"),selected:$,showClearButton:!0,type:b,disabled:!X}),X&&(0,i.createElement)(ce.Button,{key:"download",className:"woocommerce-table__download-button",disabled:z,onClick:function(){var t=e.createNotice,r=e.startExport,n=e.title,a=Object.assign({},E),i=R.data,s=R.totalResults,l="browser";if(delete a.extended_info,a.search&&delete a[b],i&&i.length===s){var c=W(i,s),u=c.headers,m=c.rows;(0,fe.downloadCSVFile)((0,fe.generateCSVFileName)(n,a),(0,fe.generateCSVDataFromTable)(u,m))}else l="email",r(f,T).then((function(){return t("success",(0,o.sprintf)(/* translators: %s = type of report */ /* translators: %s = type of report */ +(0,o.__)("Your %s Report will be emailed to you.","woocommerce"),n))})).catch((function(e){return t("error",e.message||(0,o.sprintf)(/* translators: %s = type of report */ /* translators: %s = type of report */ +(0,o.__)("There was a problem exporting your %s Report. Please try again.","woocommerce"),n))}));(0,Z.recordEvent)("analytics_table_download",{report:f,rows:s,download_type:l})}},(0,i.createElement)(be,null),(0,i.createElement)("span",{className:"woocommerce-table__download-button__label"},w.downloadButton||(0,o.__)("Download","woocommerce")))],headers:ie,isLoading:z,onQueryChange:m.onQueryChange,onColumnsChange:function(e,t){var r=re.map((function(e){return e.key})).filter((function(t){return!e.includes(t)}));if(S){var n=h({},S,r);I(n)}if(t){var a={report:f,column:t,status:e.includes(t)?"on":"off"};(0,Z.recordEvent)("analytics_table_header_toggle",a)}},onSort:function(e,t){(0,m.onQueryChange)("sort")(e,t);var r={report:f,column:e,direction:t};(0,Z.recordEvent)("analytics_table_sort",r)},onPageChange:function(e,t){N.current.scrollIntoView();var r=N.current.nextSibling.querySelector(".woocommerce-table__table"),n=de.focus.focusable.find(r);n.length&&n[0].focus(),t&&("goto"===t?(0,Z.recordEvent)("analytics_table_go_to_page",{report:f,page:e}):(0,Z.recordEvent)("analytics_table_page_click",{report:f,direction:t}))},rows:ne,rowsPerPage:parseInt(T.per_page,10)||x.QUERY_DEFAULTS.pageSize,summary:oe,totalRows:J},k)))};Ee.propTypes={className:j().string,baseSearchQuery:j().object,compareBy:j().string,compareParam:j().string,columnPrefsKey:j().string,endpoint:j().string,extendItemsMethodNames:j().shape({getError:j().string,isRequesting:j().string,load:j().string}),extendedItemsStoreName:j().string,getHeadersContent:j().func.isRequired,getRowsContent:j().func.isRequired,getSummary:j().func,itemIdField:j().string,labels:j().shape({compareButton:j().string,downloadButton:j().string,helpText:j().string,placeholder:j().string}),primaryData:j().object,searchBy:j().string,summaryFields:j().arrayOf(j().string),tableData:j().object.isRequired,tableQuery:j().object,title:j().string.isRequired,checkboxes:j().bool,renderActionButton:j().func},Ee.defaultProps={primaryData:{},tableData:{items:{data:[],totalResults:0},query:{}},tableQuery:{},compareParam:"filter",downloadable:!1,onSearch:P.noop,baseSearchQuery:{}};var Se=[],Ce={},Re=(0,R.compose)((0,q.withSelect)((function(e,t){var r=t.endpoint,n=t.getSummary,a=t.isRequesting,o=t.itemIdField,i=t.query,s=t.tableData,l=t.tableQuery,c=t.filters,u=t.advancedFilters,m=t.summaryFields,p=t.extendedItemsStoreName,d=e(x.REPORTS_STORE_NAME),f=p?e(p):null,y=e(x.SETTINGS_STORE_NAME).getSetting("wc_admin","wcAdminSettings").woocommerce_default_date_range,g=i.search&&!(i[r]&&i[r].length);if(a||g)return Ce;var b="categories"===r?"products":r,h=n?(0,x.getReportChartData)({endpoint:b,selector:d,dataType:"primary",query:i,filters:c,advancedFilters:u,defaultDateRange:y,fields:m}):Ce,v=s||(0,x.getReportTableData)({endpoint:r,query:i,selector:d,tableQuery:l,filters:c,advancedFilters:u,defaultDateRange:y}),w=f?function(e,t,r){var n=t.extendItemsMethodNames,a=t.itemIdField,o=r.items.data;if(!(Array.isArray(o)&&o.length&&n&&a))return r;var i=e[n.getError],s=e[n.isRequesting],l=e[n.load],c={include:o.map((function(e){return e[a]})).join(","),per_page:o.length},u=l(c),m=!!s&&s(c),p=!!i&&i(c),d=o.map((function(e){var t=(0,P.first)(u.filter((function(t){return e.id===t.id})));return ve(ve({},e),t)})),f=r.isRequesting||m,y=r.isError||p;return ve(ve({},r),{},{isRequesting:f,isError:y,items:ve(ve({},r.items),{},{data:d})})}(f,t,v):v;return{primaryData:h,ids:o&&w.items.data?w.items.data.map((function(e){return e[o]})):Se,tableData:w,query:i}})),(0,q.withDispatch)((function(e){var t=e(x.EXPORT_STORE_NAME).startExport;return{createNotice:e("core/notices").createNotice,startExport:t,addCesSurveyForCustomerSearch:e("wc/customer-effort-score").addCesSurveyForCustomerSearch}})))(Ee),Te=function(){var e=ie(le().mark((function e(t){var r,n;return le().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=(0,q.dispatch)("core/notices"),n=r.createNotice,e.prev=1,e.next=4,c()({path:"/automatewoo/conversions/batch/",method:"DELETE",body:JSON.stringify({ids:t})});case 4:e.next=10;break;case 6:return e.prev=6,e.t0=e.catch(1),n("error",(0,o.__)("There was an error unmarking conversions.","automatewoo")),e.abrupt("return");case 10:n("success",(0,o.__)("Orders successfully unmarked as conversions.","automatewoo"));case 11:case"end":return e.stop()}}),e,null,[[1,6]])})));return function(_x){return e.apply(this,arguments)}}();function qe(e){var t=e.query,r=e.filters,n=(0,q.useDispatch)(x.REPORTS_STORE_NAME).invalidateResolutionForStoreSelector,a=(0,I.getSetting)("admin",{}).dateFormat||F.defaultTableDateFormat,l=Q(t),c=l.formatAmount,u=l.getCurrencyConfig,m=ae((0,C.useState)(!1),2),p=m[0],d=m[1],f=(0,C.useCallback)(function(){var e=ie(le().mark((function e(t){return le().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(p){e.next=7;break}return d(!0),e.next=4,Te(t);case 4:d(!1),n("getReportStats"),n("getReportItems");case 7:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),[p,n]);return(0,i.createElement)(Re,{className:"aw-conversions-table",endpoint:"conversions",getHeadersContent:function(){return[{key:"order",label:(0,o.__)("Order #","automatewoo"),screenReaderLabel:(0,o.__)("Order Number","automatewoo"),required:!0},{key:"customer",label:(0,o.__)("Customer","automatewoo"),isLeftAligned:!0},{key:"Workflow",label:(0,o.__)("Workflow","automatewoo"),isLeftAligned:!0},{key:"log",label:(0,o.__)("Log","automatewoo"),isLeftAligned:!0},{key:"interacted",label:(0,o.__)("First Interacted","automatewoo")},{key:"placed",label:(0,o.__)("Order Placed","automatewoo")},{key:"total",label:(0,o.__)("Order Total","automatewoo"),isCurrency:!0,isNumeric:!0}]},getRowsContent:function(e){return e.map((function(e){var t=e.order_id,r=e.order_number,n=e.workflow_id,o=e.conversion_id,l=e.date_created,u=e.total_sales,m=e.extended_info,p=m.conversion.date_opened,d=m.customer,f=d.user_id,y=d.first_name,g=d.last_name,b=m.workflow.name,h="".concat(y," ").concat(g);return[{display:(0,i.createElement)(s.Link,{href:"post.php?post=".concat(t,"&action=edit"),type:"wp-admin"},(0,i.createElement)("strong",null,r)),value:t},{display:null===f?h:(0,i.createElement)(s.Link,{href:"user-edit.php?user_id=".concat(f,"&action=edit"),type:"wp-admin"},h),value:"".concat(h," (").concat(null===f?"guest":f,")")},{display:(0,i.createElement)(s.Link,{href:"post.php?post=".concat(n,"&action=edit"),type:"wp-admin"},(0,i.createElement)("strong",null,b)),value:n},{display:(0,i.createElement)("a",{className:me().triggerClasses.openLink,href:"admin-ajax.php?action=aw_modal_log_info&log_id=".concat(o)},o),value:o},{display:(0,i.createElement)(s.Date,{date:p,visibleFormat:a}),value:p},{display:(0,i.createElement)(s.Date,{date:l,visibleFormat:a}),value:l},{display:c(u),value:u}]}))},getSummary:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=e.total_sales,n=void 0===r?0:r,a=e.net_revenue,i=void 0===a?0:a,s=u();return[{label:(0,o._n)("Conversion","Conversions",t,"automatewoo"),value:(0,$.formatValue)(s,"number",t)},{label:(0,o.__)("Total sales","automatewoo"),value:c(n)},{label:(0,o.__)("Net sales","automatewoo"),value:c(i)}]},summaryFields:["total_sales","net_revenue","orders_count"],itemIdField:"order_id",query:t,tableQuery:{orderby:t.orderby||"date",order:t.order||"desc",extended_info:!0},title:(0,o.__)("Conversions list","automatewoo"),columnPrefsKey:"conversions_report_columns",filters:r,checkboxes:!0,renderActionButton:function(e){var t=e.selectedRows;return(0,i.createElement)(ce.Tooltip,{text:(0,o.__)("Unmark selected orders as conversions","automatewoo")},(0,i.createElement)(ce.Button,{disabled:p||0===t.length,variant:"secondary",onClick:function(){return f(t)}},(0,o.__)("Unmark","automatewoo")))}})}var Pe=[{key:"total_sales",href:"",label:(0,o.__)("Total value","automatewoo"),labelTooltipText:(0,o.__)("Converted order value","automatewoo"),type:"currency"},{key:"net_revenue",href:"",label:(0,o.__)("Net revenue","automatewoo"),type:"currency"},{key:"orders_count",href:"",label:(0,o.__)("Orders","automatewoo"),labelTooltipText:(0,o.__)("Converted orders","automatewoo"),type:"number"}];function De(e){var t=e.query,r=e.path,n=Pe.find((function(e){return e.key===t.chart}))||Pe[0];return(0,i.createElement)(i.Fragment,null,(0,i.createElement)(s.ReportFilters,{query:t,path:r,filters:y}),(0,i.createElement)(ne,{charts:Pe,endpoint:"conversions",query:t,selectedChart:n,filters:y}),(0,i.createElement)(X,{endpoint:"conversions",path:r,query:t,filters:y,selectedChart:n,charts:Pe}),(0,i.createElement)(qe,{query:t,filters:y}))}var je=[{key:"sent",href:"",label:(0,o.__)("Sent","automatewoo"),labelTooltipText:(0,o.__)("Trackable messages sent","automatewoo"),type:"number"},{key:"opens",href:"",label:(0,o.__)("Opens","automatewoo"),labelTooltipText:(0,o.__)("Unique opens","automatewoo"),type:"number"},{key:"unique-clicks",href:"",label:(0,o.__)("Unique clicks","automatewoo"),type:"number"},{key:"clicks",href:"",label:(0,o.__)("Clicks","automatewoo"),type:"number"}],xe=[{key:"unsubscribers",href:"",label:(0,o.__)("Unsubscribers","automatewoo"),type:"number"}];function Fe(e){var t=e.query,r=e.path,n=je.find((function(e){return e.key===t.chart}))||je[0];return(0,i.createElement)(i.Fragment,null,(0,i.createElement)(s.ReportFilters,{query:t,path:r,filters:y}),(0,i.createElement)(ne,{charts:je,endpoint:"email-tracking",query:t,selectedChart:n,filters:y}),(0,i.createElement)(X,{endpoint:"email-tracking",path:r,query:t,filters:y,selectedChart:n,charts:je}),(0,i.createElement)(ne,{charts:xe,endpoint:"unsubscribers",query:t,selectedChart:xe[0],filters:y}),(0,i.createElement)(X,{endpoint:"unsubscribers",path:r,query:t,filters:y,selectedChart:xe[0],charts:xe}))}var Ne=[{key:"runs",label:(0,o.__)("Runs","automatewoo"),labelTooltipText:(0,o.__)("Workflows have run for the selected period","automatewoo"),type:"number"}];function Ae(e){var t=e.query,r=e.path;return(0,i.createElement)(i.Fragment,null,(0,i.createElement)(s.ReportFilters,{query:t,path:r,filters:y}),(0,i.createElement)(ne,{charts:Ne,endpoint:"workflow-runs",query:t,selectedChart:Ne[0],filters:y}),(0,i.createElement)(X,{endpoint:"workflow-runs",path:r,query:t,filters:y,selectedChart:Ne[0],charts:Ne}))}(0,a.addFilter)("woocommerce_admin_reports_list","automatewoo",(function(e){return[].concat(n(e),[{report:"automatewoo-runs-by-date",title:(0,o._x)("Workflows","analytics report title","automatewoo"),component:Ae,navArgs:{id:"automatewoo-analytics-runs-by-date"}},{report:"automatewoo-email-tracking",title:(0,o._x)("Email & SMS Tracking","analytics report title","automatewoo"),component:Fe,navArgs:{id:"automatewoo-analytics-email-tracking"}},{report:"automatewoo-conversions",title:(0,o._x)("Conversions","analytics report title","automatewoo"),component:De,navArgs:{id:"automatewoo-analytics-conversions"}}])}))}()}(); \ No newline at end of file diff --git a/admin/assets/build/index-rtl.css b/admin/assets/build/index-rtl.css new file mode 100644 index 0000000..d0bff31 --- /dev/null +++ b/admin/assets/build/index-rtl.css @@ -0,0 +1,8 @@ +.automatewoo-progress-bar-component{background:#eee;height:5px;margin:15px 0;width:100%}.automatewoo-progress-bar-component__fill{background:var(--wp-admin-theme-color);border-radius:3px;height:100%;-webkit-transition:width .3s ease;transition:width .3s ease;width:0} +@-webkit-keyframes automatewoo-placeholder-fade{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}@keyframes automatewoo-placeholder-fade{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.automatewoo-placeholder-component{-webkit-animation:automatewoo-placeholder-fade 1.6s ease-in-out infinite;animation:automatewoo-placeholder-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.automatewoo-placeholder-component:after{content:" "}@media screen and (prefers-reduced-motion:reduce){.automatewoo-placeholder-component{-webkit-animation:none;animation:none}} +.automatewoo-manual-runner-large-text-and-icon{padding:26px 110px;text-align:center}.automatewoo-manual-runner-large-text-and-icon p{font-size:16px} +.automatewoo-manual-runner-found-items{border:1px solid #e2e4e7;margin:20px 0}.automatewoo-manual-runner-found-items__results{max-height:320px;overflow-y:scroll}.automatewoo-manual-runner-found-items__results:empty{display:none}.automatewoo-manual-runner-found-items__result{padding:12px 15px}.automatewoo-manual-runner-found-items__result:nth-child(odd){background-color:#f9f9f9}.automatewoo-manual-runner-found-items__summary{border-top:1px solid #e2e4e7;padding:12px 15px} +.automatewoo-manual-workflow-runner-stepper{margin:0 auto;max-width:760px}.automatewoo-workflow-runner-buttons{height:46px;margin-top:20px;position:relative}.automatewoo-workflow-runner-buttons .automatewoo-workflow-runner-next-button{position:absolute;left:0;top:0}.automatewoo-manual-workflow-runner-spinner-container{padding:26px 110px;text-align:center} +.automatewoo-page-tabs-component .components-tab-panel__tabs{-webkit-box-shadow:inset 0 -1px 0 #ccc;box-shadow:inset 0 -1px 0 #ccc;margin:7px -20px 18px;padding:0 20px}.automatewoo-page-tabs-component .components-tab-panel__tabs-item{font-size:14px} +.automatewoo-presets-list-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}@media(min-width:600px){.automatewoo-presets-list-item{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}}.automatewoo-presets-list-item .automatewoo-presets-list-item__left{-webkit-box-flex:2;-ms-flex-positive:2;flex-grow:2;padding:0 0 10px}@media(min-width:600px){.automatewoo-presets-list-item .automatewoo-presets-list-item__left{padding:0 0 0 30px}}.automatewoo-presets-list-item .automatewoo-presets-list-item__title{color:#1e1e1e;font-size:16px;font-weight:400;margin:0 0 4px}.automatewoo-presets-list-item .automatewoo-presets-list-item__description{color:#949494;font-size:14px;margin:0}.automatewoo-presets-list-item--placeholder .automatewoo-presets-list-item__title{height:22px;margin-bottom:8px;width:25%}.automatewoo-presets-list-item--placeholder .automatewoo-presets-list-item__description{height:15px;width:55%}.automatewoo-presets-list-item--placeholder .automatewoo-presets-list-item__button{height:30px;width:180px} + diff --git a/admin/assets/build/index.asset.php b/admin/assets/build/index.asset.php new file mode 100644 index 0000000..05e1c2b --- /dev/null +++ b/admin/assets/build/index.asset.php @@ -0,0 +1 @@ + array('lodash', 'react', 'regenerator-runtime', 'wc-components', 'wc-tracks', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-data-controls', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill', 'wp-url', 'wp-warning'), 'version' => 'e4530458cd538bf0ed30'); diff --git a/admin/assets/build/index.css b/admin/assets/build/index.css new file mode 100644 index 0000000..7673b9b --- /dev/null +++ b/admin/assets/build/index.css @@ -0,0 +1,8 @@ +.automatewoo-progress-bar-component{background:#eee;height:5px;margin:15px 0;width:100%}.automatewoo-progress-bar-component__fill{background:var(--wp-admin-theme-color);border-radius:3px;height:100%;-webkit-transition:width .3s ease;transition:width .3s ease;width:0} +@-webkit-keyframes automatewoo-placeholder-fade{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}@keyframes automatewoo-placeholder-fade{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.automatewoo-placeholder-component{-webkit-animation:automatewoo-placeholder-fade 1.6s ease-in-out infinite;animation:automatewoo-placeholder-fade 1.6s ease-in-out infinite;background-color:#f0f0f0;color:transparent}.automatewoo-placeholder-component:after{content:" "}@media screen and (prefers-reduced-motion:reduce){.automatewoo-placeholder-component{-webkit-animation:none;animation:none}} +.automatewoo-manual-runner-large-text-and-icon{padding:26px 110px;text-align:center}.automatewoo-manual-runner-large-text-and-icon p{font-size:16px} +.automatewoo-manual-runner-found-items{border:1px solid #e2e4e7;margin:20px 0}.automatewoo-manual-runner-found-items__results{max-height:320px;overflow-y:scroll}.automatewoo-manual-runner-found-items__results:empty{display:none}.automatewoo-manual-runner-found-items__result{padding:12px 15px}.automatewoo-manual-runner-found-items__result:nth-child(odd){background-color:#f9f9f9}.automatewoo-manual-runner-found-items__summary{border-top:1px solid #e2e4e7;padding:12px 15px} +.automatewoo-manual-workflow-runner-stepper{margin:0 auto;max-width:760px}.automatewoo-workflow-runner-buttons{height:46px;margin-top:20px;position:relative}.automatewoo-workflow-runner-buttons .automatewoo-workflow-runner-next-button{position:absolute;right:0;top:0}.automatewoo-manual-workflow-runner-spinner-container{padding:26px 110px;text-align:center} +.automatewoo-page-tabs-component .components-tab-panel__tabs{-webkit-box-shadow:inset 0 -1px 0 #ccc;box-shadow:inset 0 -1px 0 #ccc;margin:7px -20px 18px;padding:0 20px}.automatewoo-page-tabs-component .components-tab-panel__tabs-item{font-size:14px} +.automatewoo-presets-list-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}@media(min-width:600px){.automatewoo-presets-list-item{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}}.automatewoo-presets-list-item .automatewoo-presets-list-item__left{-webkit-box-flex:2;-ms-flex-positive:2;flex-grow:2;padding:0 0 10px}@media(min-width:600px){.automatewoo-presets-list-item .automatewoo-presets-list-item__left{padding:0 30px 0 0}}.automatewoo-presets-list-item .automatewoo-presets-list-item__title{color:#1e1e1e;font-size:16px;font-weight:400;margin:0 0 4px}.automatewoo-presets-list-item .automatewoo-presets-list-item__description{color:#949494;font-size:14px;margin:0}.automatewoo-presets-list-item--placeholder .automatewoo-presets-list-item__title{height:22px;margin-bottom:8px;width:25%}.automatewoo-presets-list-item--placeholder .automatewoo-presets-list-item__description{height:15px;width:55%}.automatewoo-presets-list-item--placeholder .automatewoo-presets-list-item__button{height:30px;width:180px} + diff --git a/admin/assets/build/index.js b/admin/assets/build/index.js new file mode 100644 index 0000000..a1d6128 --- /dev/null +++ b/admin/assets/build/index.js @@ -0,0 +1,31 @@ +!function(){var e={753:function(){var e,t;e=window.jQuery,document.body.classList.contains("post-type-aw_workflow")&&(t=function(){tinymce.remove(),Object.values(tinyMCEPreInit.mceInit).forEach((function(e){tinymce.init(e)}))},e("#normal-sortables").on("sortupdate",(function(){t()})),e(".postbox .handle-order-higher, .postbox .handle-order-lower").on("click.postboxes",(function(){setTimeout((function(){t()}),100)})))},694:function(e,t,r){"use strict";var n=r(925);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,r,o,a,i){if(i!==n){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var r={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return r.PropTypes=r,r}},556:function(e,t,r){e.exports=r(694)()},925:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},942:function(e,t){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e="",t=0;te.length)&&(t=e.length);for(var r=0,n=Array(t);r1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2?arguments[2]:void 0;return"object"===O(r)&&r.hasOwnProperty(e)?r[e]:t},N=D("batchSize",10,C.manualRunner),I=D("highVolumeThreshold",500,C.manualRunner),x=q("adminUrl",""),W="aw_",A=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return"".concat(x,"post.php?post=").concat(e,"&action=edit")+(t?"&workflow-origin=".concat(t):"")};function F(e,t){(0,(0,j.dispatch)("core/notices").createNotice)("error",e)}function M(_x){return U.apply(this,arguments)}function U(){return(U=l(w().mark((function e(t){var r;return w().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,T()({path:"/automatewoo/workflows/".concat(t)});case 2:if(!(r=e.sent)){e.next=5;break}return e.abrupt("return",r);case 5:throw new Error;case 6:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function Q(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function L(e){for(var t=1;t=r.total&&(r.complete=!0),e[t]=r,e}(e.progress),n=function(e){var t=0,r=0;for(var n in e){var o=e[n];t+=o.total,r+=o.complete?o.total:o.offset}if(0===r||0===t)return 0;var a=Math.floor(r/t*100);return a>100?100:a}(r);return fe(fe({},e),{},{status:100===n?ce.COMPLETE:ce.PENDING,items:fe(fe({},t.items),e.items),progress:r,progressPercent:n});default:return e}},ye=function(e){var t=e.items,r=Object.keys(t),n=(0,s.sprintf)( +// translators: %d: the number of items +// translators: %d: the number of items +(0,s.__)("Total: %d","automatewoo"),r.length);return(0,f.createElement)("div",{className:"automatewoo-manual-runner-found-items"},(0,f.createElement)("div",{className:"automatewoo-manual-runner-found-items__results"},r.map((function(e){var r=t[e],n=r.id,o=r.url,a=r.singularName;return(0,f.createElement)("div",{key:n,className:"automatewoo-manual-runner-found-items__result"},(0,f.createElement)("a",{href:o},"".concat(a," #").concat(n)))}))),(0,f.createElement)("div",{className:"automatewoo-manual-runner-found-items__summary"},n))};ye.propTypes={items:E().objectOf(E().shape({id:E().number.isRequired,singularName:E().string.isRequired,url:E().string.isRequired})).isRequired};var be=ye,ve=function(e){var t=e.dataType,r=e.workflowId;return(0,f.createElement)("div",{className:"automatewoo-workflow-runner-no-results"},(0,s.sprintf)( +// translators: %s: The type of data e.g. 'orders' +// translators: %s: The type of data e.g. 'orders' +(0,s.__)("There are no matching %s for the selected manual workflow.","automatewoo"),t),(0,f.createElement)("div",{className:"automatewoo-workflow-runner-buttons"},(0,f.createElement)(g.Button,{isSecondary:!0,href:A(r)},(0,s.__)("Edit workflow","automatewoo"))))};ve.propTypes={dataType:E().string.isRequired,workflowId:E().number.isRequired};var Ee=ve,ge=function(e){var t=e.onComplete,r=e.onCancel,n=e.workflowQuickFilterData,o=e.workflow,a=e.state,i=e.dispatch,u=n.primaryDataTypePluralName,c=Object.keys(a.items).length;le(a.status),(0,d.useEffect)((function(){if(a.status===ce.PENDING){var e=function(){var e=l(w().mark((function e(){var t,r,n,s;return w().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null!==(t=me(a.progress))){e.next=3;break}return e.abrupt("return");case 3:return r=a.progress[t],i({type:"FIND_ITEMS_REQUEST"}),e.prev=5,e.next=8,ae(o.id,t,r.offset);case 8:n=e.sent,s={},n.forEach((function(e){s[e.id]=e})),i({type:"FIND_ITEMS_SUCCESS",items:s}),e.next=18;break;case 14:e.prev=14,e.t0=e.catch(5),i({type:"FIND_ITEMS_ERROR"}),F("Error finding items.",e.t0);case 18:case"end":return e.stop()}}),e,null,[[5,14]])})));return function(){return e.apply(this,arguments)}}();e()}}),[i,o.id,a.status,a.progress]);var p=(0,s.sprintf)( +// translators: %(itemCount)d: number of items, %(dataType)s: type of item e.g. 'orders' +// translators: %(itemCount)d: number of items, %(dataType)s: type of item e.g. 'orders' +(0,s.__)("Run workflow for %(itemCount)d %(dataType)s","automatewoo"),{dataType:u,itemCount:c});return"COMPLETE"===a.status&&0===c?(0,f.createElement)(Ee,{dataType:u,workflowId:o.id}):(0,f.createElement)(f.Fragment,null,(0,f.createElement)("p",null,(0,s.sprintf)( +// translators: %1$s: type of item e.g. 'orders', %2$s: the workflow title +// translators: %1$s: type of item e.g. 'orders', %2$s: the workflow title +(0,s.__)('Searching for %1$s that match the rules used in the "%2$s" workflow. If you leave this page the process will stop.',"automatewoo"),u,o.title)),(0,f.createElement)(k,{progress:a.progressPercent}),(0,f.createElement)(be,{items:a.items}),(0,f.createElement)("div",{className:"automatewoo-workflow-runner-buttons"},(0,f.createElement)(g.Button,{isSecondary:!0,onClick:r},(0,s.__)("Cancel","automatewoo")),a.status===ce.COMPLETE&&(0,f.createElement)(Y,{onClick:function(){return t(a.items)}},p)))};ge.propTypes={state:E().object.isRequired,dispatch:E().func.isRequired,onComplete:E().func.isRequired,onCancel:E().func.isRequired,workflow:E().shape({id:E().number.isRequired,title:E().string.isRequired}).isRequired,workflowQuickFilterData:E().shape({possibleResultCounts:E().array.isRequired,primaryDataTypePluralName:E().string.isRequired}).isRequired};var he=ge,_e=function(e){var t,r=e.workflow,n=e.onStepCancel,o=e.onStepComplete,a=e.workflowQuickFilterData,i=e.possibleResultsCount,u=a.primaryDataTypePluralName,c=a.possibleResultCounts,l=p((0,d.useState)(!1),2),m=l[0],w=l[1],y=function(e){return(0,d.useReducer)(de,we,(function(t){return e.forEach((function(e){t.progress[e.group_number]={offset:0,total:e.count,complete:!1}})),t}))}(c),b=p(y,2),v=b[0],E=b[1],h=!1;return!m&&i>I&&(h=!0),t=0===i?(0,f.createElement)(Ee,{dataType:u,workflowId:r.id}):h?(0,f.createElement)(re,{dismissWarning:function(){return w(!0)},possibleResultsCount:i,primaryDataTypePluralName:u,workflowId:r.id}):(0,f.createElement)(he,{state:v,dispatch:E,onComplete:o,onCancel:n,workflow:r,workflowQuickFilterData:a}),(0,f.createElement)(g.Card,{title:(0,s.sprintf)( +// translators: %s: type of item e.g. 'orders' +// translators: %s: type of item e.g. 'orders' +(0,s.__)("2. Find matching %s","automatewoo"),u)},(0,f.createElement)(g.CardBody,null,t))};_e.propTypes={workflow:E().shape({id:E().number.isRequired,title:E().string.isRequired}).isRequired,workflowQuickFilterData:E().shape({possibleResultCounts:E().array.isRequired,primaryDataTypePluralName:E().string.isRequired}).isRequired,onStepComplete:E().func.isRequired,onStepCancel:E().func.isRequired,possibleResultsCount:E().number.isRequired};var ke=_e;function Oe(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Re(e){for(var t=1;t100?100:n},Se=function(e,t){switch(t.type){case"ADD_ITEMS_REQUEST":return e.status===ce.REQUESTING?e:Re(Re({},e),{},{status:ce.REQUESTING});case"ADD_ITEMS_ERROR":return e.status===ce.ERROR?e:Re(Re({},e),{},{status:ce.ERROR});case"ADD_ITEMS_SUCCESS":var r=Object.keys(t.itemsRemaining).length;return Re(Re({},e),{},{itemsRemaining:t.itemsRemaining,status:0===r?ce.COMPLETE:ce.PENDING,progress:Pe(Object.keys(e.itemsToAdd).length,r)});default:return e}},Te=function(e){var t,r=e.items,n=e.workflow,o=e.workflowQuickFilterData,a=e.onStepCancel,i=p((t=r,(0,d.useReducer)(Se,{status:ce.PENDING,progress:0,itemsToAdd:t,itemsRemaining:t})),2),u=i[0],c=i[1];le(u.status);var m=Object.keys(r).length;return(0,d.useEffect)((function(){if(u.status===ce.PENDING){var e=function(){var e=l(w().mark((function e(){var t,r;return w().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return c({type:"ADD_ITEMS_REQUEST"}),t=Object.keys(u.itemsRemaining).splice(0,N),r=(0,h.omit)(u.itemsRemaining,t),e.prev=3,e.next=6,se(n.id,t);case 6:c({type:"ADD_ITEMS_SUCCESS",itemsRemaining:r}),e.next=13;break;case 9:e.prev=9,e.t0=e.catch(3),c({type:"ADD_ITEMS_ERROR"}),F("Error adding items to queue.",e.t0);case 13:case"end":return e.stop()}}),e,null,[[3,9]])})));return function(){return e.apply(this,arguments)}}();e()}}),[u.itemsRemaining,u.status,n.id,c]),(0,d.useEffect)((function(){u.status===ce.COMPLETE&&(0,b.recordEvent)(W+"manual_run_workflow_complete",{items_count:m,conversion_tracking_enabled:n.is_conversion_tracking_enabled,tracking_enabled:n.is_tracking_enabled,title:n.title,type:n.type,trigger_name:n.trigger.name})}),[u.status,m,n]),(0,f.createElement)(g.Card,{title:(0,s.__)("3. Add to workflow queue","automatewoo")},(0,f.createElement)(g.CardBody,null,function(){if(u.status===ce.COMPLETE){var e=(0,s.sprintf)( +// translators: %(itemCount)d: number of matching items, %(dataType)s: type of item +// translators: %(itemCount)d: number of matching items, %(dataType)s: type of item +(0,s.__)("Woo! %(itemCount)d %(dataType)s were successfully added to the queue.","automatewoo"),{dataType:o.primaryDataTypePluralName,itemCount:m});return(0,f.createElement)(f.Fragment,null,(0,f.createElement)(ee,{icon:(0,f.createElement)(g.Dashicon,{icon:"yes-alt",size:"60"}),text:(0,f.createElement)("p",null,e)}),(0,f.createElement)("div",{className:"automatewoo-workflow-runner-buttons"},(0,f.createElement)(Y,{isPrimary:!0,href:"".concat(x,"admin.php?page=automatewoo-queue&_workflow=").concat(n.id)},(0,s.__)("View in queue","automatewoo"))))}return(0,f.createElement)(f.Fragment,null,(0,f.createElement)("p",null,(0,s.sprintf)( +// translators: %(itemCount)d: number of matching items, %(dataType)s: type of item, %(workflow)s: workflow title +// translators: %(itemCount)d: number of matching items, %(dataType)s: type of item, %(workflow)s: workflow title +(0,s.__)('Adding %(itemCount)d matching %(dataType)s to the queue for the "%(workflow)s" workflow. If you leave this page the process will stop.',"automatewoo"),{workflow:n.title,dataType:o.primaryDataTypePluralName,itemCount:m})),(0,f.createElement)(k,{progress:u.progress}),(0,f.createElement)("div",{className:"automatewoo-workflow-runner-buttons"},(0,f.createElement)(g.Button,{isSecondary:!0,onClick:a},(0,s.__)("Cancel","automatewoo"))))}()))};Te.propTypes={workflow:v.PropTypes.shape({id:v.PropTypes.number.isRequired,title:v.PropTypes.string.isRequired}).isRequired,workflowQuickFilterData:v.PropTypes.shape({primaryDataTypePluralName:v.PropTypes.string.isRequired}).isRequired,items:v.PropTypes.object.isRequired,onStepCancel:v.PropTypes.func.isRequired};var je=Te,qe=function(e){var t={order:(0,s.__)("orders","automatewoo"),subscription:(0,s.__)("subscriptions","automatewoo")};return t.hasOwnProperty(e)?t[e]:(0,s.__)("items","automatewoo")},Ce=function(e){var t=e.query,r=p((0,d.useState)({}),2),n=r[0],o=r[1],a=p((0,d.useState)(!1),2),i=a[0],u=a[1],c=p((0,d.useState)({}),2),m=c[0],v=c[1],E=p((0,d.useState)("select"),2),g=E[0],h=E[1],_=p((0,d.useState)(!1),2),k=_[0],O=_[1],R=p((0,d.useState)(!0),2),P=R[0],S=R[1],T=function(){var e=l(w().mark((function e(){var t,r,o;return w().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return O(!0),(0,b.recordEvent)(W+"manual_workflow_runner_select_workflow",{conversion_tracking_enabled:n.is_conversion_tracking_enabled,tracking_enabled:n.is_tracking_enabled,title:n.title,type:n.type,trigger_name:n.trigger.name}),e.prev=2,e.next=5,ne(n.id);case 5:t=e.sent,r=t.possibleResultCounts,o=t.primaryDataType,u({possibleResultCounts:r,primaryDataType:o,primaryDataTypePluralName:qe(o)}),h("find"),O(!1),e.next=16;break;case 13:e.prev=13,e.t0=e.catch(2),F((0,s.__)("Error loading the workflow data.","automatewoo"),e.t0);case 16:case"end":return e.stop()}}),e,null,[[2,13]])})));return function(){return e.apply(this,arguments)}}();(0,d.useEffect)((function(){var e=function(){var e=l(w().mark((function e(){var r,n;return w().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(S(!0),0===(r=void 0!==t.workflowId?parseInt(t.workflowId,10):0)){e.next=14;break}return e.prev=3,e.next=6,M(r);case 6:(n=e.sent).title||(n.title=(0,s.__)("(no title)","automatewoo")),o(n),e.next=14;break;case 11:e.prev=11,e.t0=e.catch(3),F((0,s.__)("The workflow couldn't be loaded from the URL.","automatewoo"),e.t0);case 14:S(!1);case 15:case"end":return e.stop()}}),e,null,[[3,11]])})));return function(){return e.apply(this,arguments)}}();e()}),[t.workflowId]);var j=function(e){(0,b.recordEvent)(W+"manual_run_workflow_button_clicked",{items_count:Object.keys(e).length}),h("queue"),v(e)},q=function(){(0,b.recordEvent)(W+"manual_find_matching_cancel_button_clicked",{}),h("select")},C=[{key:"select",label:(0,s.__)("Select","automatewoo"),content:(0,f.createElement)(X,{onStepComplete:T,isPreFillingWorkflow:P,workflow:n,setWorkflow:o})},{key:"find",label:(0,s.__)("Find","automatewoo"),content:function(){if("find"===g&&n&&i){var e=(t=i.possibleResultCounts,r=0,t.forEach((function(e){r+=e.count})),r);return(0,f.createElement)(ke,{workflow:n,workflowQuickFilterData:i,possibleResultsCount:e,onStepComplete:j,onStepCancel:q})}var t,r;return""}()},{key:"queue",label:(0,s.__)("Queue","automatewoo"),content:n&&i&&(0,f.createElement)(je,{workflow:n,workflowQuickFilterData:i,items:m,onStepCancel:function(){(0,b.recordEvent)(W+"manual_queue_items_cancel_button_clicked",{}),h("select"),v({})}})}];return(0,f.createElement)(y.Stepper,{steps:C,currentStep:g,className:"automatewoo-manual-workflow-runner-stepper",isPending:k})},De=function(e){var t=e.onSelect,r=e.tabs,n=e.initialTabName,o=e.children;return(0,f.createElement)("div",{className:"automatewoo-page-tabs-component"},(0,f.createElement)(g.TabPanel,{initialTabName:n,onSelect:t,tabs:r},o))};De.propTypes={children:E().func.isRequired,onSelect:E().func.isRequired,tabs:E().array.isRequired,initialTabName:E().string.isRequired};var Ne=De,Ie=window.wp.dataControls,xe="automatewoo/presets",We=function(e,t){return e.requesting[t]||!1},Ae=function(e,t){return e.errors[t]||!1},Fe=function(e){return e.presets},Me=function(e){return e.didCreateWorkflow},Ue={SET_IS_REQUESTING:"SET_IS_REQUESTING",SET_ERROR:"SET_ERROR"};function Qe(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Le(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:nt(nt({},tt),{},{presets:[],didCreateWorkflow:!1}),t=arguments.length>1?arguments[1]:void 0,r=t.type,n=t.presets;switch(r){case Ge.UPDATE_PRESETS:e=nt(nt(nt({},e),ot(e,"getPresets")),{},{presets:n});break;case Ge.CREATED_WORKFLOW:e=nt(nt(nt({},e),ot(e,"createWorkflow")),{},{didCreateWorkflow:!0})}return function(e,t){var r=t.type,n=t.selector,o=t.isRequesting,a=t.error;switch(r){case Ue.SET_IS_REQUESTING:e=et(et({},e),{},{requesting:et(et({},e.requesting),{},R({},n,o)),errors:et(et({},e.errors),{},R({},n,null))});break;case Ue.SET_ERROR:e=et(et({},e),{},{requesting:et(et({},e.requesting),{},R({},n,!1)),errors:et(et({},e.errors),{},R({},n,a))})}return e}(e,t)},actions:t,controls:Ie.controls,selectors:e,resolvers:n});var at=function(e){var t=e.children,r=e.number;return(0,f.createElement)(f.Fragment,null,0===r?"":(0,f.createElement)(g.CardDivider,null),(0,f.createElement)(g.CardBody,null,t))};at.propTypes={children:E().element.isRequired,number:E().number.isRequired};var it=at,st=function(e){var t=e.title,r=e.description,n=e.button;return(0,f.createElement)("div",{className:"automatewoo-presets-list-item"},(0,f.createElement)("div",{className:"automatewoo-presets-list-item__left"},(0,f.createElement)("h4",{className:"automatewoo-presets-list-item__title"},t),(0,f.createElement)("p",{className:"automatewoo-presets-list-item__description"},r)),(0,f.createElement)("div",{className:"automatewoo-presets-list-item__actions"},n))};st.propTypes={title:E().string.isRequired,description:E().string.isRequired,button:E().element.isRequired};var ut=st,ct=function(e,t){(0,b.recordEvent)(W+"preset_list_button_clicked",{action:e,preset_name:t})},lt=function(e){var t=e.name,r=e.title,n=e.description,o=e.link,a=(0,f.createElement)(g.Button,{href:o,isSecondary:!0,target:"_blank",onClick:function(){ct("view_guide",t)}},(0,s.__)("Learn more","automatewoo"));return(0,f.createElement)(ut,{title:r,description:n,button:a})};lt.propTypes={name:E().string.isRequired,title:E().string.isRequired,description:E().string.isRequired,link:E().string.isRequired};var pt=lt,ft=function(e){var t=e.name,r=e.title,n=e.description,o=e.createWorkflow,a=e.createWorkflowIsRequesting,i=(0,f.createElement)(g.Button,{isPrimary:!0,onClick:function(){o(t),ct("create_workflow",t)},disabled:a},(0,s.__)("Create workflow","automatewoo"));return(0,f.createElement)(ut,{description:n,title:r,button:i})};ft.propTypes={name:E().string.isRequired,title:E().string.isRequired,description:E().string.isRequired,createWorkflow:E().func.isRequired,createWorkflowIsRequesting:E().bool.isRequired};var mt=ft;function wt(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function dt(e){for(var t=1;t h2.screen-reader-text");return t.parentNode.insertBefore(e,t),e}(),a=function(t){var r=[document.querySelector("#wpbody-content .subsubsub"),document.querySelector("#wpbody-content #posts-filter")],n=t===e?"block":"none";r.forEach((function(e){e.style.display=n}))},i=function(e){r=e,window.location.hash=e,a(e),Ot(e)},u=function(e){var t;if((t=document.querySelector(".automatewoo-welcome-notice"))&&("presets"===kt()?t.style.display="none":t.style.display="block"),"presets"===e.name)return(0,f.createElement)(_t,null)},c=function(s){t.find((function(e){return e.name===s}))||(s=r||e),r=s;var c=(0,f.createElement)(Ne,{tabs:t,onSelect:i,initialTabName:s},u);void 0!==d.createRoot?(n=(0,d.createRoot)(o)).render(c):(0,d.render)(c,o),Ot(s),a(s)},window.addEventListener("hashchange",(function(){var e=kt();e!==r&&(void 0!==d.createRoot?n&&(n.unmount(),n=null):(0,d.unmountComponentAtNode)(o),c(e))}),!1),c(kt())}),!1),r(753),bt=window.jQuery,document.querySelector(".notice[data-automatewoo-dismissible-notice]")&&bt(".notice[data-automatewoo-dismissible-notice]").each((function(){var e=bt(this).data("automatewoo-dismissible-notice").replace("-","_");(0,b.recordEvent)(W+"notice_viewed",{notice_identifier:e}),bt(this).on("click","a[data-automatewoo-link-type]",(function(){return(0,b.queueRecordEvent)(W+"notice_link_clicked",{notice_identifier:e,link_type:bt(this).data("automatewoo-link-type")}),!0})),bt(this).on("click","button.notice-dismiss",(function(){return(0,b.recordEvent)(W+"notice_dismissed",{notice_identifier:e}),!0}))})),(0,u.addFilter)("woocommerce_admin_pages_list","automatewoo",(function(e){return[].concat(i(e),[{breadcrumbs:[(0,s.__)("AutomateWoo","automatewoo"),(0,s.__)("Workflows","automatewoo"),(0,s.__)("Manual Runner","automatewoo")],title:(0,s.__)("AutomateWoo Manual Workflow Runner","automatewoo"),container:Ce,path:"/automatewoo/manual-workflow-runner",wpOpenMenu:"toplevel_page_automatewoo"}])}))}()}(); \ No newline at end of file diff --git a/admin/assets/css/aw-main.css b/admin/assets/css/aw-main.css new file mode 100644 index 0000000..8a3695f --- /dev/null +++ b/admin/assets/css/aw-main.css @@ -0,0 +1 @@ +@keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.aw-loader::before,.automatewoo-field-row--loading .automatewoo-field-wrap::before{height:24px;width:24px;display:block;position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px;animation:spin .8s linear infinite;content:"";background:url("../img/loader.svg") center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75);z-index:10}.aw-loader--left::before{left:0;margin-left:0}.wp-core-ui .button.aw-button-icon{display:inline-block;text-indent:-9999px;text-align:left;position:relative;padding:0 !important;height:2em !important;width:2em}.wp-core-ui .button.aw-button-icon::after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.wp-core-ui .button.aw-button-icon.delete::after{content:""}.wp-core-ui .button.aw-button-icon.view::after{content:""}.wp-core-ui .button.aw-button-icon.approve::after{content:""}.wp-core-ui .button.aw-button-icon.tick::after{content:""}.wp-core-ui .button.aw-button-icon.reject::after{content:""}.wp-core-ui .button.aw-button-icon--settings::after{content:""}.wp-core-ui .button.aw-button-icon--size-md{font-size:14px}.wp-core-ui .button.aw-button-icon--size-md::after{line-height:1.95}.aw-switch{cursor:pointer;text-indent:-999em;display:block;width:38px;height:22px;border-radius:30px;border:none;position:relative;box-sizing:border-box;transition:all .3s ease;box-shadow:inset 0 0 0 0 rgba(0,0,0,0)}.aw-switch:focus{outline:none}.aw-switch::before{border-radius:50%;background:#fff;content:"";position:absolute;display:block;width:18px;height:18px;top:2px;left:2px;transition:all .15s ease;box-shadow:0 1px 3px rgba(0,0,0,.3)}.aw-switch[data-aw-switch=on]{box-shadow:inset 0 0 0 11px var(--wp-admin-theme-color)}.aw-switch[data-aw-switch=on]::before{transform:translateX(16px)}.aw-switch[data-aw-switch=off]{background:#ccc}.aw-switch.aw-loading{cursor:default;opacity:.5}.aw-actions-container{padding:10px 15px}.aw-action-template{display:none}.automatewoo-action{margin:5px 0 10px}.automatewoo-action .wp-editor-container iframe{min-height:300px}.automatewoo-action.js-open .automatewoo-action__header{background:#3595bc;background-image:linear-gradient(to bottom, #46afdb, #3199c5);border:#268fbb solid 1px;box-shadow:inset #5fc8f4 0 1px 0 0;color:#fff;text-shadow:#268fbb 0 1px 0}.automatewoo-action.js-open .automatewoo-action__header h4,.automatewoo-action.js-open .automatewoo-action__header a{color:#fff}.automatewoo-action:not([data-automatewoo-action-can-be-previewed=true]) [data-automatewoo-preview]{display:none}.automatewoo-action__header{position:relative;padding:14px 17px;border:1px solid #e1e1e1}.automatewoo-action__header h4{font-size:14px;margin:0;display:inline-block}.automatewoo-action__header .row-options{float:right;font-size:12px}.automatewoo-action__header .row-options a{text-decoration:none;margin:0 4px}.automatewoo-action__fields{border:1px solid #e1e1e1;display:none}.automatewoo-page--reports h2.nav-tab-wrapper{margin-bottom:11px}.automatewoo-page--reports #poststuff{padding-top:0}.automatewoo-page--reports .aw-before-report-output{margin-bottom:11px}.automatewoo-page table.automatewoo-list-table tr th{padding:10px 10px 11px;font-size:14px}.automatewoo-page table.automatewoo-list-table tbody tr td{padding:10px 10px 12px}.automatewoo-page table.automatewoo-list-table th.sortable,.automatewoo-page table.automatewoo-list-table th.sorted{padding:0}.automatewoo-page table.automatewoo-list-table tbody .check-column{padding-top:11px;padding-left:3px}.automatewoo-page table.automatewoo-list-table--conversions .column-order,.automatewoo-page table.automatewoo-list-table--conversions .column-log,.automatewoo-page table.automatewoo-list-table--conversions .column-total{width:9%}.automatewoo-page table.automatewoo-list-table--queue .column-queued_event_id{width:130px}.automatewoo-page table.automatewoo-list-table--queue .column-actions{width:155px}.automatewoo-page table.automatewoo-list-table--queue .column-date{width:160px}.automatewoo-page table.automatewoo-list-table--carts .column-id,.automatewoo-page table.automatewoo-list-table--logs .column-id{width:9%}.automatewoo-page table.automatewoo-list-table--carts .column-status,.automatewoo-page table.automatewoo-list-table--logs .column-status{width:12%}.automatewoo-page table.automatewoo-list-table--carts .column-time,.automatewoo-page table.automatewoo-list-table--logs .column-time{width:170px}.automatewoo-page table.automatewoo-list-table--carts .column-items,.automatewoo-page table.automatewoo-list-table--carts .column-total,.automatewoo-page table.automatewoo-list-table--logs .column-items,.automatewoo-page table.automatewoo-list-table--logs .column-total{width:9%}.automatewoo-page table.automatewoo-list-table--carts .column-actions,.automatewoo-page table.automatewoo-list-table--logs .column-actions{width:9%;text-align:right}.automatewoo-page table.automatewoo-list-table--carts .column-ip,.automatewoo-page table.automatewoo-list-table--logs .column-ip{width:220px}.automatewoo-page table.automatewoo-list-table--carts .column-created,.automatewoo-page table.automatewoo-list-table--carts .column-last_active,.automatewoo-page table.automatewoo-list-table--logs .column-created,.automatewoo-page table.automatewoo-list-table--logs .column-last_active{width:200px}.automatewoo-page table.automatewoo-list-table--guests .column-id{width:8%}.automatewoo-page table.automatewoo-list-table--guests .column-email{width:26%}.automatewoo-page table.automatewoo-list-table--guests .column-actions{width:115px}.automatewoo-page table.automatewoo-list-table--events .column-id{width:8%}.automatewoo-page table.automatewoo-list-table--events .column-status{width:12%}body.automatewoo-modal-open{overflow:hidden}.automatewoo-modal-container{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100000;display:grid;align-content:center;align-items:center;justify-content:center;justify-items:center}.automatewoo-modal{position:relative;max-height:100%;width:min(560px,93vw);display:grid;grid-template:[content-start x-start] 53px [x-end] auto [content-end]/[content-start] 1fr [x-start] 53px [x-end content-end];overflow:hidden}body.automatewoo-modal-loading .automatewoo-modal::before{height:24px;width:24px;display:block;position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px;animation:spin .8s linear infinite;content:"";background:url("../img/loader.svg") center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75);z-index:10}body.automatewoo-modal-loading .automatewoo-modal .automatewoo-modal__body{opacity:.4}.automatewoo-modal .automatewoo-icon-close{text-align:center;grid-area:x;color:#666;cursor:pointer;box-shadow:-1px 1px #e1e1e1}.automatewoo-modal .automatewoo-icon-close::before{font-size:23px;font-family:dashicons;line-height:53px;speak:none;-webkit-font-smoothing:antialiased;content:""}.automatewoo-modal .automatewoo-icon-close:hover{background:#f5f5f5;color:#000}.automatewoo-modal h2{font-size:1.4em}.automatewoo-modal h3{font-size:1.2em}.automatewoo-modal--size-lg{width:min(680px,93vw)}.automatewoo-modal__contents{background-color:#f5f5f5;display:grid;grid-template-rows:auto 1fr;grid-area:content;max-height:93vh}.automatewoo-modal-overlay{background:rgba(0,0,0,.35);position:fixed;top:0;right:0;bottom:0;left:0}.automatewoo-modal__header{display:flex;align-items:center;min-height:53px;padding-right:53px;background:#fff;border-bottom:1px solid #e1e1e1;box-shadow:0 4px 4px -4px rgba(0,0,0,.1)}.automatewoo-modal__header h1{padding:0 18px;font-size:19px;line-height:1.2;margin:0}.automatewoo-modal__footer{box-sizing:border-box;background:#fff;border-top:1px solid #e1e1e1;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1);padding:14px 18px;text-align:right}.automatewoo-modal__footer.aw-pull-right{width:100%;float:right}.automatewoo-modal__footer.aw-pull-right .button{margin-left:3px}.automatewoo-modal__body{overflow:auto;min-height:130px}.automatewoo-modal__body hr{margin:17px 0;border:none;border-bottom:1px solid #e1e1e1}.automatewoo-modal__body ul{margin:17px 0 17px}.automatewoo-modal__body-inner{margin:17px 18px 22px}.automatewoo-table{line-height:1.3;color:#515151;background:#fff;border:0;border-spacing:0;margin:0;width:100%}.automatewoo-table--bordered{border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04)}.automatewoo-table a{text-decoration:none}.automatewoo-table .automatewoo-table__col{vertical-align:top;border:0 none;border-top:1px solid #f2f2f2;padding:18px 20px 18px 20px;float:none}.automatewoo-table .automatewoo-table__col--label{border-top-color:#f0f0f0;width:31.5%;line-height:1.15;font-size:13px;font-weight:600;border-right:1px solid #e6e6e6;background:#f9f9f9}.automatewoo-table .automatewoo-table__col--label .automatewoo-help-tip{margin:0;position:relative}.automatewoo-table .automatewoo-table__col--field{padding-top:13px;padding-bottom:13px}.automatewoo-table .automatewoo-table__row:first-child .automatewoo-table__col{border-top:none}.automatewoo-cart-table{background:rgba(0,0,0,0);width:100%;text-align:left;border:1px solid #ccc;border-bottom:none;border-right:none;margin:20px 0}.automatewoo-cart-table th,.automatewoo-cart-table td{padding:11px 14px;vertical-align:top;border:none;border-bottom:1px solid #ccc;border-right:1px solid #ccc}.aw-workflow-variables-container .aw-variables-group{margin:0 0 9px}.aw-workflow-variables-container .aw-workflow-variable-outer{font-family:Consolas,Monaco,monospace;font-size:0;margin:0 2px 5px 0;display:inline-block;padding:0;line-height:1;cursor:pointer;background:#f5f5f5;border-radius:10px;border:1px solid #e1e1e1}.aw-workflow-variables-container .aw-workflow-variable-outer:hover{background:#e1e1e1}.aw-workflow-variables-container .aw-workflow-variable-outer .aw-workflow-variable{padding:2px 9px 3px;display:block;line-height:1.35;font-size:11.5px;word-break:break-all}.aw-workflow-variable-parameters-table{margin:18px 0 21px}.aw-workflow-variable-clipboard-form{padding:0 0 12px}.aw-workflow-variable-clipboard-form .aw-workflow-variable-preview-field{box-sizing:border-box;line-height:1.45;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);font-family:Consolas,Monaco,monospace;width:100%;padding:18px;font-size:12.5px;margin:0 5px 9px 0;text-align:center;background:#fff}.aw-workflow-variable-clipboard-form .aw-clipboard-btn{width:100%}.woocommerce .aw-settings-tab-container{max-width:1100px;padding:5px 0 0}.woocommerce .aw-settings-tab-container p.submit{margin-top:-5px;padding:0}.woocommerce .aw-settings-tab-container .form-table input[type=text],.woocommerce .aw-settings-tab-container .form-table input[type=password],.woocommerce .aw-settings-tab-container .form-table select,.woocommerce .aw-settings-tab-container .form-table textarea{margin:0;width:450px;padding:6px;box-sizing:border-box}.woocommerce .aw-settings-tab-container .form-table input[type=number]{width:100px}.woocommerce .aw-settings-tab-container .form-table th{width:210px;padding-right:40px !important}.woocommerce .aw-settings-tab-container .aw-settings-section:not(:first-child){border-top:1px solid #e1e1e1;padding-top:25px;margin-top:25px}.woocommerce .aw-settings-tab-container .wp-editor-wrap{margin:0 0 8px}.woocommerce .aw-settings-tab-container .forminp .description{font-size:13px;font-style:italic;color:#737373;line-height:1.4}.woocommerce .aw-settings-tab-container .forminp-checkbox fieldset{min-height:25px;position:relative}.woocommerce .aw-settings-tab-container .forminp-checkbox label{position:absolute;top:2px;left:0}.woocommerce .aw-settings-tab-container .forminp-checkbox .description{display:inline-block;padding:5px 0 3px 29px}.woocommerce .aw-settings-tab-container code{font-size:12px}.woocommerce .aw-settings-tab-container .automatewoo-settings__input-wrap{position:relative}.woocommerce .aw-settings-tab-container .automatewoo-help-tip{position:absolute;top:11px;left:-32px}.automatewoo-settings-submit{padding-top:15px}.form-table .aw-settings-row--checkbox-group td{padding-top:0}#adminmenu .toplevel_page_automatewoo .wp-first-item,#adminmenu .toplevel_page_automatewoo a[href="admin.php?page=automatewoo-data-upgrade"],#adminmenu .toplevel_page_automatewoo a[href="admin.php?page=automatewoo-preview"],#adminmenu .toplevel_page_automatewoo a[href="admin.php?page=wc-admin&path=/automatewoo/manual-workflow-runner"],#adminmenu .toplevel_page_automatewoo a[href="admin.php?page=wc-admin&path=%2Fautomatewoo%2Fmanual-workflow-runner"]{display:none}.automatewoo-field{margin:1px;width:100%}.automatewoo-field--invalid{border-color:#dc3232 !important;box-shadow:0 0 2px #f55e4f !important}.automatewoo-field--type-text,.automatewoo-field--type-number{height:28px}.automatewoo-field--monospace{font-family:Consolas,Monaco,monospace;font-size:13px;word-break:break-all}.wp-admin select.automatewoo-field{max-width:100%}.automatewoo-field-errors{margin-top:7px;color:#dc3232;font-weight:500;line-height:1.1}.automatewoo-field-errors__error{margin-top:4px}.automatewoo-table__col .wc-enhanced-select,.automatewoo-table__col .select2-container,.automatewoo-table__col .select2-search,.automatewoo-table__col .select2-search__field{width:100% !important}.automatewoo-table__col--field input[type=checkbox]{margin:6px 0}.automatewoo-field-wrap{position:relative}.automatewoo-field-row--loading .automatewoo-field-wrap::before{left:20px;margin-left:0}.automatewoo-field-row--loading .automatewoo-field-wrap>*{opacity:0}.field-gap{margin:8px 0}.field-cols .col-1,.field-cols .col-2{float:left;width:48%}.field-cols .col-2{float:right}.aw-field-description{color:#8e8e8e;font-size:13px;margin:7px 1px 0;font-style:italic}.aw-required-asterisk{color:#dc3232;font-weight:bold}.aw-required-asterisk::before{content:"*"}select.aw-field.wc-enhanced-select{display:none}.automatewoo-input-group{position:relative;display:table;border-collapse:separate}.automatewoo-input-group__input,.automatewoo-input-group__addon{vertical-align:middle;display:table-cell !important}.automatewoo-input-group__input{width:100%;float:left}.automatewoo-input-group__addon{width:1%;white-space:nowrap}.automatewoo-input-group__addon--pad-right{padding-right:10px}.automatewoo-label{display:block;font-weight:600;margin:0 0 7px;font-size:13px}.automatewoo-label--inline-checkbox{margin:3px 0}.automatewoo-label--inline-checkbox .automatewoo-field--type-checkbox{margin-left:8px}.automatewoo-label--weight-normal{font-weight:normal !important}.automatewoo-label__extra{font-weight:normal !important;font-size:12px}.automatewoo-time-field-group{*zoom:1}.automatewoo-time-field-group::before,.automatewoo-time-field-group::after{content:" ";display:table}.automatewoo-time-field-group::after{clear:both}.automatewoo-time-field-group__fields{max-width:140px}.automatewoo-time-field-group .automatewoo-field{width:44%;float:left}.automatewoo-time-field-group__sep{float:left;text-align:center;width:6%;margin-top:6px}.automatewoo-time-field-group__24hr-note{font-weight:normal !important;font-size:12px;margin-left:7px;display:inline-block;margin-top:11px}.automatewoo-before-after-day-field-group__field{margin:1px;vertical-align:top}.automatewoo-before-after-day-field-group__field--days{width:50px}.automatewoo-before-after-day-field-group__field--type{min-width:35%}.automatewoo-list-table-form .tablenav .select2-selection--single{height:30px}.automatewoo-list-table-form .tablenav .select2-selection--single .select2-selection__rendered{height:30px;line-height:2;font-size:14px}.automatewoo-list-table-form .tablenav .select2-selection--single .select2-selection__arrow{height:28px}.automatewoo-field-group--email-address-with-name{*zoom:1}.automatewoo-field-group--email-address-with-name::before,.automatewoo-field-group--email-address-with-name::after{content:" ";display:table}.automatewoo-field-group--email-address-with-name::after{clear:both}.automatewoo-field-group--email-address-with-name .automatewoo-field-group__fields{display:flex;justify-content:space-between}.automatewoo-field-group--email-address-with-name .automatewoo-field-group__fields .automatewoo-field{width:49%}.aw-rules-container{padding:14px 20px 9px}.aw-rule-group__or{margin:26px -20px 23px;border-bottom:1px solid #e1e1e1;text-align:center;position:relative}.aw-rule-group__or span{position:absolute;left:50%;transform:translateX(-50%);color:#a9a9a9;display:inline-block;background:#fff;padding:0 13px;top:-9px;letter-spacing:1px;text-transform:uppercase;font-size:13px}.aw-rule-group:last-child{margin-bottom:10px}.aw-rule-group:last-child .aw-rule-group__or{display:none}.automatewoo-rule{width:100%;box-sizing:border-box;position:relative;padding:7px 0;*zoom:1}.automatewoo-rule::before,.automatewoo-rule::after{content:" ";display:table}.automatewoo-rule::after{clear:both}@media(min-width: 1200px){.automatewoo-rule{padding-right:79px}}.automatewoo-rule__buttons{position:absolute;bottom:4px;right:-1px}@media(min-width: 783px){.automatewoo-rule__buttons{bottom:8px}}@media(min-width: 1200px){.automatewoo-rule__buttons{top:8px;bottom:auto}}.automatewoo-rule--type-select .automatewoo-rule__buttons{min-height:46px}@media(min-width: 783px){.automatewoo-rule--type-select .automatewoo-rule__buttons{min-height:34px}}.automatewoo-rule__add{float:left;padding:0 8px 1px}.automatewoo-rule__remove{display:block;float:left;position:relative;top:9px;width:23px;height:23px;margin-left:6px;border:1px solid #c5c5c5;border-radius:50%;background:rgba(0,0,0,0);cursor:pointer}.automatewoo-rule__remove::after{display:block;content:"";width:11px;height:1px;position:absolute;top:10px;left:5px;background:#c5c5c5}.automatewoo-rule__remove:hover{border-color:#dc3232;background:#f55e4f}.automatewoo-rule__remove:hover::after{background:#fff}@media(min-width: 783px){.automatewoo-rule__remove{top:4px}}.automatewoo-rule__fields{width:100%}.automatewoo-rule__fields .aw-rule-select-container{width:50%;padding-left:0}.automatewoo-rule__fields .aw-rule-select-container select{width:100%}.automatewoo-rule__fields .aw-rule-field-compare{width:50%}.automatewoo-rule__fields .aw-rule-field-value{position:relative;width:100%;padding-left:0;padding-top:8px;padding-right:94px}.automatewoo-rule__fields .aw-rule-field-value .aw-loader,.automatewoo-rule__fields .aw-rule-field-value .automatewoo-field-row--loading .automatewoo-field-wrap,.automatewoo-field-row--loading .automatewoo-rule__fields .aw-rule-field-value .automatewoo-field-wrap{position:absolute;top:14px;left:20px}.automatewoo-rule__fields .aw-rule-field-value select,.automatewoo-rule__fields .aw-rule-field-value .select2-container{width:100% !important}.automatewoo-rule__fields .aw-rule-field-value select .select2-search__field,.automatewoo-rule__fields .aw-rule-field-value .select2-container .select2-search__field{max-width:50px}@media(min-width: 783px){.automatewoo-rule__fields .aw-rule-field-value{padding-right:85px}}@media(min-width: 1200px){.automatewoo-rule__fields .aw-rule-select-container{width:35%}.automatewoo-rule__fields .aw-rule-field-compare{width:20%}.automatewoo-rule__fields .aw-rule-field-value{padding:0 6px;width:45%}}@media(min-width: 1500px){.automatewoo-rule__fields .aw-rule-select-container{width:30%}.automatewoo-rule__fields .aw-rule-field-compare{width:18%}.automatewoo-rule__fields .aw-rule-field-value{width:52%}}@media(min-width: 1760px){.automatewoo-rule__fields .aw-rule-select-container{width:26%}.automatewoo-rule__fields .aw-rule-field-compare{width:16%}.automatewoo-rule__fields .aw-rule-field-value{width:58%}}.automatewoo-rule__field-container{float:left;width:100px;box-sizing:border-box;padding:0 6px}.automatewoo-rule--type-meta .js-rule-value-field{width:48%;float:left}@media(min-width: 1500px){.automatewoo-rule--type-meta .js-rule-value-field{width:48.7%}}.automatewoo-rule--type-meta .js-rule-value-field:last-child{float:right}.automatewoo-rule--type-meta.automatewoo-rule--compare-blank .js-rule-value-field,.automatewoo-rule--type-meta.automatewoo-rule--compare-not_blank .js-rule-value-field{width:100%}.automatewoo-rule--type-meta.automatewoo-rule--compare-blank .js-rule-value-field:last-child,.automatewoo-rule--type-meta.automatewoo-rule--compare-not_blank .js-rule-value-field:last-child{display:none}.automatewoo-rule input.automatewoo-field{height:28px}.automatewoo-missing-rule{padding:8px 9px;margin:7px 0;border:1px solid #dc3232;border-radius:4px;color:#dc3232;font-weight:500;line-height:1.3}body.post-type-aw_workflow .wp-list-table .column-primary{width:48%}body.post-type-aw_workflow .wp-list-table .column-timing{width:20%}body.post-type-aw_workflow .wp-list-table .column-times_run,body.post-type-aw_workflow .wp-list-table .column-queued{width:95px}body.post-type-aw_workflow .wp-list-table .column-aw_status_toggle{width:70px}body.post-type-aw_workflow .wp-list-table .column-aw_status_toggle .aw-switch{float:right;margin:9px 10px 0 0}body.post-type-aw_workflow #pageparentdiv{display:none}body.post-type-aw_workflow #aw_trigger_box.aw-loading .inside,body.post-type-aw_workflow #aw_trigger_box.aw-loading h3.hndle,body.post-type-aw_workflow #aw_actions_box.aw-loading .inside,body.post-type-aw_workflow #aw_actions_box.aw-loading h3.hndle,body.post-type-aw_workflow #aw_options_box.aw-loading .inside,body.post-type-aw_workflow #aw_options_box.aw-loading h3.hndle,body.post-type-aw_workflow #aw_variables_box.aw-loading .inside,body.post-type-aw_workflow #aw_variables_box.aw-loading h3.hndle{opacity:.45}body.post-type-aw_workflow #aw_trigger_box.aw-loading::before,body.post-type-aw_workflow #aw_actions_box.aw-loading::before,body.post-type-aw_workflow #aw_options_box.aw-loading::before,body.post-type-aw_workflow #aw_variables_box.aw-loading::before{height:24px;width:24px;display:block;position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px;animation:spin .8s linear infinite;content:"";background:url("../img/loader.svg") center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75);z-index:10}#aw_save_box .handlediv,#aw_save_box .hndle,#aw_save_box .postbox-header,#aw_timing_box .handlediv,#aw_timing_box .hndle,#aw_timing_box .postbox-header,#aw_variables_box .handlediv,#aw_variables_box .hndle,#aw_variables_box .postbox-header{display:none}#post-body .automatewoo-metabox.postbox h3.hndle{border-bottom:1px solid #e1e1e1;padding:9px 15px}#post-body .automatewoo-metabox.postbox.no-drag .hndle{cursor:default}#post-body .automatewoo-metabox.postbox .inside{padding:0;margin:0}.automatewoo-metabox.postbox .automatewoo-metabox-footer{padding:9px 15px;background:#f5f5f5;border-top:1px solid #e1e1e1;text-align:right}.automatewoo-metabox.postbox .automatewoo-metabox-pad{padding:20px}.automatewoo-metabox.postbox h2.hndle small{font-weight:normal;padding-left:1px}.automatewoo-metabox.postbox h2.hndle .automatewoo-help-link{position:relative;top:2px;left:-11px}body.wc-wp-version-gte-55 .automatewoo-metabox.postbox h2.hndle small{font-weight:normal;padding-left:6px;flex-grow:1}body.wc-wp-version-gte-55 .automatewoo-metabox.postbox h2.hndle .automatewoo-help-link{top:1px;left:0}.aw-view-trigger-preset-activation-modal,.aw-view-trigger-compatibility-modal{display:contents}.automatewoo-dashboard-list,.automatewoo-dashboard-chart,.automatewoo-dashboard__workflows,.automatewoo-dashboard__figure{background:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04)}.automatewoo-dashboard__workflow,.automatewoo-dashboard__figure{display:block;text-decoration:none}.automatewoo-dashboard__workflow:hover,.automatewoo-dashboard__figure:hover{background:#fafafa}.automatewoo-page--dashboard{overflow:hidden}.automatewoo-dashboard-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap}.automatewoo-dashboard-date-nav__tab{position:relative;line-height:1}.automatewoo-dashboard-date-nav__tab::after{content:"";position:absolute;bottom:0;left:0;right:0;height:0;background-color:var(--wp-admin-theme-color)}.automatewoo-dashboard-date-nav__tab--current::after{height:var(--wp-admin-border-width-focus)}.automatewoo-dashboard-widgets{margin-top:20px;margin-right:-20px}.automatewoo-dashboard-widget-sizer{width:calc(100% - 20px)}@media(min-width: 800px){.automatewoo-dashboard-widget-sizer{width:calc(50% - 20px)}}@media(min-width: 1200px){.automatewoo-dashboard-widget-sizer{width:calc(33.33% - 20px)}}@media(min-width: 1750px){.automatewoo-dashboard-widget-sizer{width:calc(25% - 20px)}}.automatewoo-dashboard-widget{margin-bottom:20px;width:calc(100% - 20px)}@media(min-width: 800px){.automatewoo-dashboard-widget{width:calc(50% - 20px)}}@media(min-width: 1200px){.automatewoo-dashboard-widget{width:calc(33.33% - 20px)}}@media(min-width: 1750px){.automatewoo-dashboard-widget{width:calc(25% - 20px)}}.automatewoo-dashboard-widget--key-figures{margin-bottom:0}.automatewoo-dashboard__figures{margin:0 -10px;*zoom:1}.automatewoo-dashboard__figures::before,.automatewoo-dashboard__figures::after{content:" ";display:table}.automatewoo-dashboard__figures::after{clear:both}.automatewoo-dashboard__figure{display:block;margin:0 10px 20px;float:left;width:calc(50% - 20px);text-align:center;background-color:#fff;box-sizing:border-box;padding:17px 10px 21px}.automatewoo-dashboard__figure-name{color:#aaa;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:12.5px}.automatewoo-dashboard__figure-value{color:#464646;font-size:21px;font-weight:300;line-height:1.3}.automatewoo-dashboard__workflow{padding:17px 17px}.automatewoo-dashboard__workflow:not(:last-child){border-bottom:1px solid #e5e5e5}.automatewoo-dashboard__workflow-title{font-size:17px;text-decoration:none}.automatewoo-dashboard__workflow-description{color:#aaa}.automatewoo-dashboard-chart{display:block;position:relative}.automatewoo-dashboard-chart[aw-loading] .aw-loader,.automatewoo-dashboard-chart[aw-loading] .automatewoo-field-row--loading .automatewoo-field-wrap,.automatewoo-field-row--loading .automatewoo-dashboard-chart[aw-loading] .automatewoo-field-wrap{opacity:.4}.automatewoo-dashboard-chart__flot{display:block;height:150px;margin:12px 14px 20px}@media(min-width: 800px){.automatewoo-dashboard-chart__flot{height:190px}}@media(min-width: 1200px){.automatewoo-dashboard-chart__flot{height:200px}}@media(min-width: 1400px){.automatewoo-dashboard-chart__flot{height:220px}}.automatewoo-dashboard-chart__flot .flot-x-axis>div{margin-top:11px}.automatewoo-dashboard-chart__tooltip{z-index:10;position:absolute;display:none;background:#000;opacity:.75;color:#fff;padding:3px 5px 4px;font-weight:500;border-radius:3px;font-size:11px;line-height:1}.automatewoo-dashboard-chart__header{border-bottom:1px solid #eee;position:relative;height:73px;overflow:hidden;*zoom:1}.automatewoo-dashboard-chart__header::before,.automatewoo-dashboard-chart__header::after{content:" ";display:table}.automatewoo-dashboard-chart__header::after{clear:both}.automatewoo-dashboard-chart__header-group{padding:16px 20px;float:left}.automatewoo-dashboard-chart__header-group:not(:first-child){border-left:1px solid #eee}.automatewoo-dashboard-chart__header .automatewoo-arrow-link{position:absolute;right:20px;top:28px}.automatewoo-dashboard-chart__header-figure{color:#464646;font-size:21px;font-weight:300;line-height:1.1}.automatewoo-dashboard-chart__header-text{color:#aaa;font-size:12.5px}.automatewoo-dashboard-chart__legend{display:inline-block;width:4px;height:4px;border:2px solid #e1e1e1;margin-right:1px;border-radius:50%}.automatewoo-dashboard-chart__legend--blue{border-color:#3498db}.automatewoo-dashboard-chart__legend--purple{border-color:#d0a0e4}.automatewoo-dashboard-chart__legend--green{border-color:#72c9b2}.automatewoo-dashboard-list__header{border-bottom:1px solid #eee;padding:22px 20px}.automatewoo-dashboard-list__header .automatewoo-arrow-link{position:absolute;right:20px;top:22px}.automatewoo-dashboard-list__heading{font-weight:500;color:#464646;font-size:14px}.automatewoo-dashboard-list__item{padding:12px 20px;background:#f9f9f9}.automatewoo-dashboard-list__item:not(:last-child){border-bottom:1px solid #eee}.automatewoo-dashboard-list__item-title{text-decoration:none;font-weight:500}.automatewoo-dashboard-list__item-text{font-size:12.5px;color:#aaa}.automatewoo-dashboard-list__item-button{float:right}.automatewoo-dashboard-list__empty{text-align:center;background:#f9f9f9;padding:60px 20px;color:#aaa}.automatewoo-welcome-notice{padding:25px 305px 20px 36px !important;border-left-width:1px;position:relative}@media(max-width: 800px){.automatewoo-welcome-notice{padding:20px !important}}.automatewoo-welcome-notice__image{position:absolute;width:266px;height:138px;top:7px;right:40px;background-image:url("../img/presets.svg");background-size:266px 138px;background-repeat:no-repeat}@media(max-width: 800px){.automatewoo-welcome-notice__image{display:none}}.automatewoo-welcome-notice__heading{color:#1e1e1e;margin:0 0 .25rem 2px}.automatewoo-welcome-notice__text p{font-size:14px;line-height:1.65;margin:.5em 0 0;color:#69686e}.automatewoo-notice{position:relative;transition:opacity .2s ease}.automatewoo-notice p{transition:opacity .2s ease}.automatewoo-notice.aw-loading{opacity:.65}.automatewoo-notice.aw-loading p{opacity:.6}.automatewoo-notice.aw-loading::before{height:24px;width:24px;display:block;position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px;animation:spin .8s linear infinite;content:"";background:url("../img/loader.svg") center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75);z-index:10}.automatewoo-upgrade-loader{display:inline-block;position:relative;width:40px;height:13px;opacity:.55}.automatewoo-upgrade-loader::before{height:20px;width:20px;display:block;position:absolute;top:50%;left:50%;margin-left:-10px;margin-top:-10px;animation:spin .8s linear infinite;content:"";background:url("../img/loader.svg") center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75);z-index:10}.automatewoo-info-box{background:#e4e4e4;padding:12px 16px 14px;border:1px solid #ccc}dl.automatewoo-meta-data{margin:0;*zoom:1}dl.automatewoo-meta-data::before,dl.automatewoo-meta-data::after{content:" ";display:table}dl.automatewoo-meta-data::after{clear:both}dl.automatewoo-meta-data dt,dl.automatewoo-meta-data dd{display:inline-block;float:left;margin:0 0 .8em;padding:0}dl.automatewoo-meta-data dt{font-weight:bold;clear:left;padding-right:.5em}dl.automatewoo-meta-data dd p:last-child{margin-bottom:0}dl.automatewoo-meta-data a{text-decoration:none}body.post-type-aw_workflow #wpbody-content h1::before,.automatewoo-page h1::before{content:"";display:inline-block;width:27px;height:20px;background-image:url("../img/header-badge.svg");background-size:contain;background-repeat:no-repeat;margin-right:9px;position:relative;top:2px}body.post-type-aw_workflow #wpbody-content h1::before{margin-right:4px}automatewoo-icon{content:"";display:inline-block;height:1em;width:1.3917995444em;background-image:url("../img/header-badge.svg");background-size:contain;background-repeat:no-repeat;background-position:center;filter:invert(100%);margin-right:.5em;vertical-align:text-bottom}#wpbody-content #wp__notice-list+.automatewoo-page:not(.woocommerce){padding-top:96px}.automatewoo-content--has-sidebar{*zoom:1}.automatewoo-content--has-sidebar::before,.automatewoo-content--has-sidebar::after{content:" ";display:table}.automatewoo-content--has-sidebar::after{clear:both}@media(min-width: 1450px){.automatewoo-content--has-sidebar .automatewoo-main{float:left;width:calc(100% - 275px)}.automatewoo-content--has-sidebar .automatewoo-sidebar{float:right;margin-top:42px;width:250px;margin-left:25px}}.automatewoo-sidebar{color:#959595;border-top:1px solid #ddd;padding:18px 0 5px;margin-top:13px}.automatewoo-sidebar p{margin:0 0 9px}@media(min-width: 1450px){.automatewoo-sidebar p{margin:0 0 13px}}.automatewoo-sidebar p a{color:#959595}.automatewoo-arrow-link{display:block;width:15px;height:15px;border:2px solid;border-radius:50%;text-decoration:none;color:#d1d1d1;position:relative}.automatewoo-arrow-link::before{display:inline-block;font:400 18px/1 dashicons;content:"";speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top;position:absolute;top:1px;left:2px;font-size:13px;-webkit-font-smoothing:subpixel-antialiased}.automatewoo-plugin-table-update-message{display:block;background:#d54d21;color:#fff;padding:1em;margin:9px 0}.automatewoo-plugin-table-update-message a{color:#fff;text-decoration:underline}.automatewoo-plugin-table-update-message::before{display:inline-block;font:400 18px/1 dashicons;content:"";speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top;margin:0 8px 0 -2px}[data-automatewoo-show]{display:none}.automatewoo-help-tip{font-size:15px;color:#a9a9a9}.automatewoo-help-link--right,.automatewoo-help-tip--right{float:right;position:relative;right:-2px}.automatewoo-tiptip{cursor:help}.automatewoo-help-link{color:#8e8e8e}.automatewoo-help-link::before{display:inline-block;font:400 18px/1 dashicons;content:"";speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top;font-size:16px}.automatewoo-badge--blocked-email{display:inline-block;width:18px;height:18px;border-radius:50%;color:#fff}.automatewoo-badge--blocked-email .dashicons{font-size:12px;height:14px;width:17px;margin-top:3px}.automatewoo-badge{margin:0 6px}.automatewoo-badge--warning{color:#ca4a1f}.automatewoo-badge--warning .dashicons{font-size:21px}.automatewoo-badge--blocked-email{background:#ca4a1f}.aw_system_check_table td.help{position:relative}.aw-hidden{display:none !important}/*# sourceMappingURL=aw-main.css.map */ diff --git a/admin/assets/css/aw-main.css.map b/admin/assets/css/aw-main.css.map new file mode 100644 index 0000000..282f7c8 --- /dev/null +++ b/admin/assets/css/aw-main.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["_loader.scss","_icons.scss","_switch.scss","aw-main.scss","_actions.scss","_reports.scss","_modal.scss","_tables.scss","_variables.scss","_settings.scss","_admin-menu.scss","_fields.scss","_mixins.scss","_rules.scss","_workflow-list.scss","_workflow-edit.scss","_dashboard.scss","_welcome-notice.scss"],"names":[],"mappings":"AACA,gBAEC,KACC,iCACA,0BAMD,mFACC,OAHoB,KAIpB,MAJoB,KAKpB,cACA,kBACA,QACA,SACA,kBACA,iBACA,mCACA,WACA,kDACA,sBACA,cACA,kBACA,cACA,sBACA,WAUF,yBACC,OACA,cCxCD,mCACC,qBACA,oBACA,gBACA,kBACA,qBACA,sBACA,UAEA,0CACC,sBACA,cACA,kBACA,WACA,YACA,OACA,iBACA,SACA,kBACA,WACA,oBACA,oBACA,mCACA,MACA,gBAGD,iDACC,YAGD,+CACC,YAGD,kDACC,YAGD,+CACC,YAGD,iDACC,YAGD,oDACC,YAGD,4CACC,eAEA,mDACC,iBCvDH,WAKC,eACA,mBACA,cACA,MAPQ,KAQR,OAPS,KAQT,mBACA,YACA,kBACA,sBACA,wBACA,uCAEA,iBACC,aAGD,mBACC,kBACA,WCjBM,KDkBN,WACA,kBACA,cACA,WACA,YACA,IA1BW,IA2BX,KA3BW,IA4BX,yBACA,oCAID,8BACC,wDAEA,sCACC,2BAKF,+BACC,gBAGD,sBACC,eACA,WEnDF,sBACC,kBAGD,oBACC,aAGD,oBACC,kBAIC,gDACC,iBAOD,wDACC,mBACA,8DACA,yBACA,mCACA,WACA,4BAEA,qHAEC,WAMH,oGACC,aAMF,4BACC,kBACA,kBACA,yBAEA,+BACC,eACA,SACA,qBAGD,yCACC,YACA,eAEA,2CACC,qBACA,aAOH,4BACC,yBACA,aCpEA,8CACC,mBAGD,sCACC,cAGD,oDACC,mBASA,qDACC,uBACA,eAGD,2DACC,uBAGD,oHAEC,UAGD,mEACC,iBACA,iBAKA,4NAGC,SAOD,8EACC,YAGD,sEACC,YAGD,mEACC,YAOD,iIACC,SAGD,yIACC,UAGD,qIACC,YAGD,8QAEC,SAGD,2IACC,SACA,iBAGD,iIACC,YAGD,8RAEC,YAOD,kEACC,SAGD,qEACC,UAGD,uEACC,YAOD,kEACC,SAGD,sEACC,UCzHJ,4BACC,gBAGD,6BACC,eACA,MACA,QACA,SACA,OACA,eAEA,aACA,qBACA,mBACA,uBACA,qBAGD,mBACC,kBACA,gBACA,sBACA,aACA,cACC,+GAKD,gBNrBA,0DACC,OAHoB,KAIpB,MAJoB,KAKpB,cACA,kBACA,QACA,SACA,kBACA,iBACA,mCACA,WACA,kDACA,sBACA,cACA,kBACA,cACA,sBACA,WMUA,2EACC,WAIF,2CACC,kBAEA,YACA,WACA,eACA,4BAEA,mDACC,eACA,sBACA,YAtDmB,KAuDnB,WACA,mCACA,YAGD,iDACC,WH5De,QG6Df,MHvDK,KG4DP,sBACC,gBAGD,sBACC,gBAIF,4BACC,sBAGD,6BACC,iBHhFiB,QGkFjB,aACA,4BAEA,kBACA,gBAGD,2BACC,2BACA,eACA,MACA,QACA,SACA,OAID,2BACC,aACA,mBACA,WAvGqB,KAwGrB,cAxGqB,KAyGrB,WHnGO,KGoGP,gCACA,yCAEA,8BACC,eACA,eACA,gBACA,SAKF,2BACC,sBACA,WHlHO,KGmHP,6BACA,0CACA,kBACA,iBAEA,yCACC,WACA,YAEA,iDACC,gBAMH,yBACC,cACA,iBAEA,4BACC,cACA,YACA,gCAGD,4BACC,mBAIF,+BACC,sBCtJD,mBACC,gBACA,MJKsB,QIJtB,gBACA,SACA,iBACA,SACA,WAEA,6BACC,yBACA,qCAGD,qBACC,qBAGD,2CACC,mBACA,cACA,6BACA,4BACA,WAID,kDACC,yBACA,YACA,iBACA,eACA,gBACA,+BACA,WApCmB,QAsCnB,wEACC,SACA,kBAKF,kDACC,iBACA,oBAGD,+EACC,gBAKF,wBACC,yBACA,WACA,gBACA,sBACA,mBACA,kBACA,cAEA,sDAEC,kBACA,mBACA,YACA,6BACA,4BCtED,qDACC,eAGD,6DACC,sCACA,YACA,mBACA,qBACA,UACA,cACA,eACA,WLbgB,QKchB,mBACA,yBAEA,mEACC,WLhBiB,QKmBlB,mFACC,oBACA,cACA,iBACA,iBACA,qBAKH,uCACC,mBAGD,qCACC,iBAEA,yEACC,sBACA,iBACA,sBACA,2CACA,sCACA,WACA,aACA,iBACA,mBACA,kBACA,WL5CM,KK+CP,uDACC,WCrDF,wCACC,iBACA,gBAGA,iDACC,gBACA,UAMA,sQAIC,SACA,YACA,YACA,sBAGD,uEACC,YAIF,uDACC,YACA,8BAGD,+EACC,6BACA,iBACA,gBAID,wDACC,eAMA,8DACC,eACA,kBACA,cACA,gBAMD,mEACC,gBACA,kBAGD,gEACC,kBACA,QACA,OAGD,uEACC,qBACA,uBAKF,6CACC,eAID,0EACC,kBAGD,8DACC,kBACA,SACA,WAKF,6BACC,iBAOC,gDACC,cCpGF,scAKC,gCCCD,WACA,WAEA,4BACC,gCACA,sCAGD,8DAEC,YAGD,8BACC,sCACA,eACA,qBAKF,mCACC,eAGD,0BACC,eACA,MR3BK,QQ4BL,gBACA,gBAGD,iCACC,eAKA,8KAIC,sBAMD,oDACC,aAKF,wBACC,kBAUC,gEACC,UACA,cAIF,0DACC,UAMF,WACC,aAKA,sCAEC,WACA,UAGD,mBACC,YAKF,sBACC,MRzGiB,QQ0GjB,eACA,iBACA,kBAID,sBACC,MRzGK,QQ0GL,iBAEA,8BACC,YAKF,mCACC,aAGD,yBACC,kBACA,cACA,yBAEA,gEAEC,sBACA,8BAGD,gCACC,WACA,WAGD,gCACC,SACA,mBAGD,2CACC,mBAKF,mBACC,cACA,gBACA,eACA,eAEA,oCACC,aAEA,sEACC,gBAIF,kCACC,8BAGD,0BACC,8BACA,eAOF,8BCnLC,QAEA,2EAEC,YACA,cAGD,qCACC,WD8KD,sCACC,gBAGD,iDACC,UACA,WAGD,mCACC,WACA,kBACA,SACA,eAGD,yCACC,8BACA,eACA,gBACA,qBACA,gBAOD,iDACC,WACA,mBAEA,uDACC,WAGD,uDACC,cAOF,kEACC,YAEA,+FACC,YACA,cACA,eAGD,4FACC,YAKH,kDClPC,QAEA,mHAEC,YACA,cAGD,yDACC,WD6OD,mFACC,aACA,8BAEA,sGACC,UErPH,oBACC,sBAID,mBACC,uBACA,gCACA,kBACA,kBAEA,wBACC,kBACA,SACA,2BACA,cACA,qBACA,WVlBM,KUmBN,eACA,SACA,mBACA,yBACA,eAOD,0BACC,mBAEA,6CACC,aASH,kBAEC,WACA,sBACA,kBACA,cDrDA,QAEA,mDAEC,YACA,cAGD,yBACC,WCgDD,0BATD,kBAUE,oBAGD,2BACC,kBACA,WACA,WAEA,yBALD,2BAME,YAGD,0BATD,2BAUE,QACA,aAGD,0DACC,gBAEA,yBAHD,0DAIE,iBAMH,uBACC,WACA,kBAGD,0BACC,cACA,WACA,kBACA,QACA,WACA,YACA,gBACA,yBACA,kBACA,yBACA,eAEA,iCACC,cACA,WACA,WACA,WACA,kBACA,SACA,SACA,mBAGD,gCACC,aV5GG,QU6GH,WV5GS,QU8GT,uCACC,WVlHI,KUsHN,yBAjCD,0BAkCE,SAKF,0BACC,WAEA,oDACC,UACA,eAEA,2DACC,WAKF,iDACC,UAGD,+CACC,kBACA,WACA,eACA,gBACA,mBAEA,wQACC,kBACA,SACA,UAGD,wHAEC,sBAEA,sKACC,eAIF,yBAtBD,+CAuBE,oBAIF,0BAEC,oDACC,UAGD,iDACC,UAGD,+CACC,cACA,WAIF,0BAEC,oDACC,UAGD,iDACC,UAGD,+CACC,WAKF,0BAEC,oDACC,UAGD,iDACC,UAGD,+CACC,WAMH,mCACC,WACA,YACA,sBACA,cAMA,kDACC,UACA,WAEA,0BAJD,kDAKE,aAGD,6DACC,YAQF,wKACC,WAEA,8LACC,aAQJ,0CACC,YAGD,0BACC,gBACA,aACA,yBACA,kBACA,MVvQK,QUwQL,gBACA,gBC/QA,0DACC,UAGD,yDACC,UAGD,qHAEC,WAGD,mEACC,WAEA,8EACC,YACA,oBClBF,0CACC,aAUC,wfAEC,YfJH,0PACC,OAHoB,KAIpB,MAJoB,KAKpB,cACA,kBACA,QACA,SACA,kBACA,iBACA,mCACA,WACA,kDACA,sBACA,cACA,kBACA,cACA,sBACA,WeCD,gPAGC,aAOD,iDACC,gCACA,iBAGD,uDACC,eAGD,gDACC,UACA,SAOD,yDACC,iBACA,WZ1DgB,QY2DhB,6BACA,iBAGD,sDACC,aAKA,4CACC,mBACA,iBAGD,6DACC,kBACA,QACA,WAWA,sEACC,mBACA,iBACA,YAGD,uFACC,QACA,OAQJ,8EAEC,iBCpGD,0HACC,WbFO,KaGP,yBACA,qCAGD,gEACC,cACA,qBAEA,4EACC,WAd8B,QAmBhC,6BACC,gBAKA,8BACC,aACA,mBACA,8BACA,eAID,qCACC,kBACA,cAEA,4CACC,WACA,kBACA,SACA,OACA,QACA,SACA,6CAGD,qDACC,0CAIF,+BACC,gBACA,mBAGD,oCACC,wBAEA,yBAHD,oCAIE,wBAGD,0BAPD,oCAQE,2BAGD,0BAXD,oCAYE,wBAMF,8BACC,cAhFO,KAiFP,wBAEA,yBAJD,8BAKE,wBAGD,0BARD,8BASE,2BAGD,0BAZD,8BAaE,wBAWF,2CACC,gBAGD,gCACC,eJ3GD,QAEA,+EAEC,YACA,cAGD,uCACC,WIuGD,+BAIC,cACA,mBACA,WACA,uBACA,kBACA,sBACA,sBACA,uBAGD,oCACC,MA9HgC,KA+HhC,mBACA,uBACA,gBACA,iBAGD,qCACC,MbxHgB,QayHhB,eACA,gBACA,gBAWD,iCAGC,kBAEA,kDACC,gCAIF,uCACC,eACA,qBAGD,6CACC,MApKgC,KA0KjC,6BAGC,cACA,kBAEA,sPACC,WAIF,mCACC,cACA,aACA,sBAEA,yBALD,mCAME,cAGD,0BATD,mCAUE,cAGD,0BAbD,mCAcE,cAID,oDACC,gBAIF,sCACC,WACA,kBACA,aACA,Wb3MM,Ka4MN,YACA,Mb9MM,Ka+MN,oBACA,gBACA,kBACA,eACA,cAGD,qCACC,6BACA,kBACA,YAEA,gBJhOD,QAEA,yFAEC,YACA,cAGD,4CACC,WI4ND,2CACC,kBACA,WAEA,6DACC,2BAIF,6DACC,kBACA,WACA,SAGD,4CACC,MbtOgB,QauOhB,eACA,gBACA,gBAGD,0CACC,MA3PgC,KA4PhC,iBAGD,qCACC,qBACA,UACA,WACA,yBACA,iBACA,kBAGD,2CACC,qBAGD,6CACC,qBAGD,4CACC,qBAWD,oCACC,6BACA,kBAGD,4DACC,kBACA,WACA,SAGD,qCACC,gBACA,Mb3RgB,Qa4RhB,eAKD,kCACC,kBACA,mBAEA,mDACC,6BAIF,wCACC,qBACA,gBAGD,uCACC,iBACA,MA/TgC,KAkUjC,yCACC,YAGD,mCACC,kBACA,mBACA,kBACA,MA1UgC,KCFlC,4BACC,wCACA,sBACA,kBAEA,yBALD,4BAME,yBAGD,mCACC,kBACA,YACA,aACA,QACA,WACA,2CACA,4BACA,4BAEA,yBAVD,mCAWE,cAIF,qCACC,MdRmB,QcSnB,sBAGD,oCACC,eACA,iBACA,gBACA,MdnB2B,QA2B7B,oBACC,kBACA,4BAEA,sBACC,4BAGD,+BACC,YAEA,iCACC,WH1CF,uCACC,OAHoB,KAIpB,MAJoB,KAKpB,cACA,kBACA,QACA,SACA,kBACA,iBACA,mCACA,WACA,kDACA,sBACA,cACA,kBACA,cACA,sBACA,WGiCF,4BACC,qBACA,kBACA,WACA,YACA,YHvDA,oCACC,OGwDgB,KHvDhB,MGuDgB,KHtDhB,cACA,kBACA,QACA,SACA,kBACA,iBACA,mCACA,WACA,kDACA,sBACA,cACA,kBACA,cACA,sBACA,WG4CF,sBACC,mBACA,uBACA,sBAID,yBACC,SS/EA,QAEA,iEAEC,YACA,cAGD,gCACC,WT0ED,wDAEC,qBACA,WACA,gBACA,UAGD,4BACC,iBACA,WACA,mBAKA,yCACC,gBAIF,2BACC,qBAQD,mFACC,WACA,qBACA,WACA,YACA,gDACA,wBACA,4BAEA,iBACA,kBACA,QAIF,sDACC,iBAID,iBACC,WACA,qBAEA,WAEA,qBACA,gDACA,wBACA,4BACA,2BAEA,oBACA,kBACA,2BAGD,qEACC,iBAKD,kCS5JC,QAEA,mFAEC,YACA,cAGD,yCACC,WTuJD,0BAIC,oDACC,WACA,yBAGD,uDACC,YACA,gBACA,MAXe,MAYf,YAXQ,MAiBX,qBAGC,MAFQ,QAGR,0BACA,mBACA,gBAEA,uBACC,eAEA,0BAHD,uBAIE,iBAGD,yBACC,MAfM,QAqBT,wBACC,cACA,WACA,YACA,iBACA,kBACA,qBACA,cACA,kBAEA,gCSpMA,qBACA,0BACA,QToMoB,ISnMpB,WACA,mCACA,kCACA,mBTiMC,kBACA,QACA,SACA,eACA,4CAKF,yCACC,cACA,mBACA,MA7NO,KA8NP,YACA,aAEA,2CACC,MAlOM,KAmON,0BAGD,iDS5NA,qBACA,0BACA,QT4NoB,IS3NpB,WACA,mCACA,kCACA,mBTyNC,oBAKF,wBACC,aAID,sBACC,eACA,cAGD,2DAEC,YACA,kBACA,WAGD,oBACC,YAGD,uBACC,MA1QiB,QA4QjB,+BS5PA,qBACA,0BACA,QT4PoB,IS3PpB,WACA,mCACA,kCACA,mBTyPC,eAKF,kCACC,qBACA,WACA,YACA,kBACA,MAnRO,KAqRP,6CACC,eACA,YACA,WACA,eAKF,mBACC,aAEA,4BACC,MA5RkB,QA8RlB,uCACC,eAIF,kCAGC,WAtSkB,QA+SnB,+BACC,kBAIF,WACC","file":"aw-main.css","sourcesContent":["\n@keyframes spin {\n\n\t100% {\n\t\t-webkit-transform: rotate(360deg);\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n@mixin loader( $size: 24px ) {\n\n\t&::before {\n\t\theight: $size;\n\t\twidth: $size;\n\t\tdisplay: block;\n\t\tposition: absolute;\n\t\ttop: 50%;\n\t\tleft: 50%;\n\t\tmargin-left: calc(-1 * $size / 2);\n\t\tmargin-top: calc(-1 * $size / 2);\n\t\tanimation: spin 0.8s linear infinite;\n\t\tcontent: \"\";\n\t\tbackground: url(\"../img/loader.svg\") center center;\n\t\tbackground-size: cover;\n\t\tline-height: 1;\n\t\ttext-align: center;\n\t\tfont-size: 2em;\n\t\tcolor: rgba(#000, 0.75);\n\t\tz-index: 10;\n\t}\n}\n\n.aw-loader {\n\n\t@include loader();\n}\n\n\n.aw-loader--left::before {\n\tleft: 0;\n\tmargin-left: 0;\n}\n",".wp-core-ui .button.aw-button-icon {\n\tdisplay: inline-block;\n\ttext-indent: -9999px;\n\ttext-align: left;\n\tposition: relative;\n\tpadding: 0 !important;\n\theight: 2em !important;\n\twidth: 2em;\n\n\t&::after {\n\t\tfont-family: Dashicons;\n\t\ttext-indent: 0;\n\t\tposition: absolute;\n\t\twidth: 100%;\n\t\theight: 100%;\n\t\tleft: 0;\n\t\tline-height: 1.85;\n\t\tmargin: 0;\n\t\ttext-align: center;\n\t\tspeak: none;\n\t\tfont-variant: normal;\n\t\ttext-transform: none;\n\t\t-webkit-font-smoothing: antialiased;\n\t\ttop: 0;\n\t\tfont-weight: 400;\n\t}\n\n\t&.delete::after {\n\t\tcontent: \"\\f335\";\n\t}\n\n\t&.view::after {\n\t\tcontent: \"\\f177\";\n\t}\n\n\t&.approve::after {\n\t\tcontent: \"\\f529\";\n\t}\n\n\t&.tick::after {\n\t\tcontent: \"\\f147\";\n\t}\n\n\t&.reject::after {\n\t\tcontent: \"\\f542\";\n\t}\n\n\t&--settings::after {\n\t\tcontent: \"\\f111\";\n\t}\n\n\t&--size-md {\n\t\tfont-size: 14px;\n\n\t\t&::after {\n\t\t\tline-height: 1.95;\n\t\t}\n\t}\n\n}\n",".aw-switch {\n\t$width: 38px;\n\t$height: 22px;\n\t$inner-pad: 2px;\n\n\tcursor: pointer;\n\ttext-indent: -999em;\n\tdisplay: block;\n\twidth: $width;\n\theight: $height;\n\tborder-radius: 30px;\n\tborder: none;\n\tposition: relative;\n\tbox-sizing: border-box;\n\ttransition: all 0.3s ease;\n\tbox-shadow: inset 0 0 0 0 transparent;\n\n\t&:focus {\n\t\toutline: none;\n\t}\n\n\t&::before {\n\t\tborder-radius: 50%;\n\t\tbackground: $white;\n\t\tcontent: \"\";\n\t\tposition: absolute;\n\t\tdisplay: block;\n\t\twidth: $height - ($inner-pad*2);\n\t\theight: $height - ($inner-pad*2);\n\t\ttop: $inner-pad;\n\t\tleft: $inner-pad;\n\t\ttransition: all 0.15s ease;\n\t\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n\t}\n\n\n\t&[data-aw-switch=\"on\"] {\n\t\tbox-shadow: inset 0 0 0 calc($height / 2) var(--wp-admin-theme-color);\n\n\t\t&::before {\n\t\t\ttransform: translateX($width - $height);\n\n\t\t}\n\t}\n\n\t&[data-aw-switch=\"off\"] {\n\t\tbackground: #ccc;\n\t}\n\n\t&.aw-loading {\n\t\tcursor: default;\n\t\topacity: 0.5;\n\t}\n}\n","$grey-text-light: #8e8e8e;\n$grey-very-light: #f5f5f5;\n$grey-very-light-border: #f2f2f2;\n$grey-light-border: #e1e1e1;\n$grey-border: #ccc;\n$grey-very-light-border: #eee;\n$white: #fff;\n$black: #000;\n$red: #dc3232;\n$red-light: #f55e4f;\n$color-text-dark-grey: #515151;\n\n$warning-badge-red: #ca4a1f;\n\n$color-brand-paragraph-grey: #69686e;\n\n$color-dark-grey: #464646;\n$color-g2-dark-grey: #1e1e1e;\n\n\n$breakpoint-xlarge: 1450px;\n\n@import \"mixins\";\n@import \"loader\";\n@import \"icons\";\n@import \"switch\";\n@import \"actions\";\n@import \"reports\";\n@import \"modal\";\n@import \"tables\";\n@import \"variables\";\n@import \"settings\";\n@import \"admin-menu\";\n@import \"fields\";\n@import \"rules\";\n@import \"workflow-list\";\n@import \"workflow-edit\";\n@import \"dashboard\";\n@import \"welcome-notice\";\n\n\n.automatewoo-notice {\n\tposition: relative;\n\ttransition: opacity 0.2s ease;\n\n\tp {\n\t\ttransition: opacity 0.2s ease;\n\t}\n\n\t&.aw-loading {\n\t\topacity: 0.65;\n\n\t\tp {\n\t\t\topacity: 0.6;\n\t\t}\n\n\t\t@include loader();\n\t}\n}\n\n\n.automatewoo-upgrade-loader {\n\tdisplay: inline-block;\n\tposition: relative;\n\twidth: 40px;\n\theight: 13px;\n\topacity: 0.55;\n\n\t@include loader( 20px );\n}\n\n\n.automatewoo-info-box {\n\tbackground: #e4e4e4;\n\tpadding: 12px 16px 14px;\n\tborder: 1px solid #ccc;\n}\n\n\ndl.automatewoo-meta-data {\n\tmargin: 0;\n\n\t@include clearfix();\n\n\tdt,\n\tdd {\n\t\tdisplay: inline-block;\n\t\tfloat: left;\n\t\tmargin: 0 0 0.8em;\n\t\tpadding: 0;\n\t}\n\n\tdt {\n\t\tfont-weight: bold;\n\t\tclear: left;\n\t\tpadding-right: 0.5em;\n\t}\n\n\tdd {\n\n\t\tp:last-child {\n\t\t\tmargin-bottom: 0;\n\t\t}\n\t}\n\n\ta {\n\t\ttext-decoration: none;\n\t}\n}\n\n\nbody.post-type-aw_workflow #wpbody-content,\n.automatewoo-page {\n\n\th1::before {\n\t\tcontent: \"\";\n\t\tdisplay: inline-block;\n\t\twidth: 27px;\n\t\theight: 20px;\n\t\tbackground-image: url(\"../img/header-badge.svg\");\n\t\tbackground-size: contain;\n\t\tbackground-repeat: no-repeat;\n\t\t// Modified again in the next rule.\n\t\tmargin-right: 9px;\n\t\tposition: relative;\n\t\ttop: 2px;\n\t}\n}\n\nbody.post-type-aw_workflow #wpbody-content h1::before {\n\tmargin-right: 4px;\n}\n\n// Smaller icon for AutomateWoo's items in the WooCommerce's Analytics menu.\nautomatewoo-icon {\n\tcontent: \"\";\n\tdisplay: inline-block;\n\t// Use the font size.\n\theight: 1em;\n\t// Scale proportionally to font height.\n\twidth: calc(1em * 611 / 439);\n\tbackground-image: url(\"../img/header-badge.svg\");\n\tbackground-size: contain;\n\tbackground-repeat: no-repeat;\n\tbackground-position: center;\n\t// Invert the color to make it white.\n\tfilter: invert(100%);\n\tmargin-right: 0.5em;\n\tvertical-align: text-bottom;\n}\n\n#wpbody-content #wp__notice-list + .automatewoo-page:not(.woocommerce) {\n\tpadding-top: 96px;\n}\n\n.automatewoo-content {}\n\n.automatewoo-content--has-sidebar {\n\n\t@include clearfix;\n\n\t@media ( min-width: $breakpoint-xlarge ) {\n\t\t$sidebar-width: 250px;\n\t\t$gutter: 25px;\n\n\t\t.automatewoo-main {\n\t\t\tfloat: left;\n\t\t\twidth: calc(100% - #{$sidebar-width + $gutter});\n\t\t}\n\n\t\t.automatewoo-sidebar {\n\t\t\tfloat: right;\n\t\t\tmargin-top: 42px;\n\t\t\twidth: $sidebar-width;\n\t\t\tmargin-left: $gutter;\n\t\t}\n\t}\n}\n\n\n.automatewoo-sidebar {\n\t$color: #959595;\n\n\tcolor: $color;\n\tborder-top: 1px solid #ddd;\n\tpadding: 18px 0 5px;\n\tmargin-top: 13px;\n\n\tp {\n\t\tmargin: 0 0 9px;\n\n\t\t@media ( min-width: $breakpoint-xlarge ) {\n\t\t\tmargin: 0 0 13px;\n\t\t}\n\n\t\ta {\n\t\t\tcolor: $color;\n\t\t}\n\t}\n}\n\n\n.automatewoo-arrow-link {\n\tdisplay: block;\n\twidth: 15px;\n\theight: 15px;\n\tborder: 2px solid;\n\tborder-radius: 50%;\n\ttext-decoration: none;\n\tcolor: #d1d1d1;\n\tposition: relative;\n\n\t&::before {\n\n\t\t@include dashicon( \"\\f345\" );\n\t\tposition: absolute;\n\t\ttop: 1px;\n\t\tleft: 2px;\n\t\tfont-size: 13px;\n\t\t-webkit-font-smoothing: subpixel-antialiased;\n\t}\n}\n\n\n.automatewoo-plugin-table-update-message {\n\tdisplay: block;\n\tbackground: #d54d21;\n\tcolor: $white;\n\tpadding: 1em;\n\tmargin: 9px 0;\n\n\ta {\n\t\tcolor: $white;\n\t\ttext-decoration: underline;\n\t}\n\n\t&::before {\n\n\t\t@include dashicon( \"\\f348\" );\n\t\tmargin: 0 8px 0 -2px;\n\t}\n}\n\n\n[data-automatewoo-show] {\n\tdisplay: none;\n}\n\n\n.automatewoo-help-tip {\n\tfont-size: 15px;\n\tcolor: #a9a9a9;\n}\n\n.automatewoo-help-link--right,\n.automatewoo-help-tip--right {\n\tfloat: right;\n\tposition: relative;\n\tright: -2px;\n}\n\n.automatewoo-tiptip {\n\tcursor: help;\n}\n\n.automatewoo-help-link {\n\tcolor: $grey-text-light;\n\n\t&::before {\n\n\t\t@include dashicon( \"\\f504\" );\n\t\tfont-size: 16px;\n\t}\n}\n\n\n%automatewoo-badge-in-circle {\n\tdisplay: inline-block;\n\twidth: 18px;\n\theight: 18px;\n\tborder-radius: 50%;\n\tcolor: $white;\n\n\t.dashicons {\n\t\tfont-size: 12px;\n\t\theight: 14px;\n\t\twidth: 17px;\n\t\tmargin-top: 3px;\n\t}\n}\n\n\n.automatewoo-badge {\n\tmargin: 0 6px;\n\n\t&--warning {\n\t\tcolor: $warning-badge-red;\n\n\t\t.dashicons {\n\t\t\tfont-size: 21px;\n\t\t}\n\t}\n\n\t&--blocked-email {\n\n\t\t@extend %automatewoo-badge-in-circle;\n\t\tbackground: $warning-badge-red;\n\n\n\t}\n}\n\n\n.aw_system_check_table {\n\n\ttd.help {\n\t\tposition: relative;\n\t}\n}\n\n.aw-hidden {\n\tdisplay: none !important;\n}\n",".aw-actions-container {\n\tpadding: 10px 15px;\n}\n\n.aw-action-template {\n\tdisplay: none;\n}\n\n.automatewoo-action {\n\tmargin: 5px 0 10px;\n\n\t.wp-editor-container {\n\n\t\tiframe {\n\t\t\tmin-height: 300px;\n\t\t}\n\t}\n\n\n\t&.js-open {\n\n\t\t.automatewoo-action__header {\n\t\t\tbackground: #3595bc;\n\t\t\tbackground-image: linear-gradient(to bottom, #46afdb, #3199c5);\n\t\t\tborder: #268fbb solid 1px;\n\t\t\tbox-shadow: inset #5fc8f4 0 1px 0 0;\n\t\t\tcolor: #fff;\n\t\t\ttext-shadow: #268fbb 0 1px 0;\n\n\t\t\th4,\n\t\t\ta {\n\t\t\t\tcolor: white;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t&:not([data-automatewoo-action-can-be-previewed=\"true\"]) [data-automatewoo-preview] {\n\t\tdisplay: none;\n\t}\n\n}\n\n\n.automatewoo-action__header {\n\tposition: relative;\n\tpadding: 14px 17px;\n\tborder: 1px solid $grey-light-border;\n\n\th4 {\n\t\tfont-size: 14px;\n\t\tmargin: 0;\n\t\tdisplay: inline-block;\n\t}\n\n\t.row-options {\n\t\tfloat: right;\n\t\tfont-size: 12px;\n\n\t\ta {\n\t\t\ttext-decoration: none;\n\t\t\tmargin: 0 4px;\n\t\t}\n\t}\n\n}\n\n\n.automatewoo-action__fields {\n\tborder: 1px solid $grey-light-border;\n\tdisplay: none;\n}\n\n",".automatewoo-page--reports {\n\n\th2.nav-tab-wrapper {\n\t\tmargin-bottom: 11px;\n\t}\n\n\t#poststuff {\n\t\tpadding-top: 0;\n\t}\n\n\t.aw-before-report-output {\n\t\tmargin-bottom: 11px;\n\t}\n}\n\n\n.automatewoo-page {\n\n\ttable.automatewoo-list-table {\n\n\t\ttr th {\n\t\t\tpadding: 10px 10px 11px;\n\t\t\tfont-size: 14px;\n\t\t}\n\n\t\ttbody tr td {\n\t\t\tpadding: 10px 10px 12px;\n\t\t}\n\n\t\tth.sortable,\n\t\tth.sorted {\n\t\t\tpadding: 0;\n\t\t}\n\n\t\ttbody .check-column {\n\t\t\tpadding-top: 11px;\n\t\t\tpadding-left: 3px;\n\t\t}\n\n\t\t&--conversions {\n\n\t\t\t.column-order,\n\t\t\t.column-log,\n\t\t\t.column-total {\n\t\t\t\twidth: 9%;\n\t\t\t}\n\t\t}\n\n\n\t\t&--queue {\n\n\t\t\t.column-queued_event_id {\n\t\t\t\twidth: 130px;\n\t\t\t}\n\n\t\t\t.column-actions {\n\t\t\t\twidth: 155px;\n\t\t\t}\n\n\t\t\t.column-date {\n\t\t\t\twidth: 160px;\n\t\t\t}\n\t\t}\n\n\t\t&--carts,\n\t\t&--logs {\n\n\t\t\t.column-id {\n\t\t\t\twidth: 9%;\n\t\t\t}\n\n\t\t\t.column-status {\n\t\t\t\twidth: 12%;\n\t\t\t}\n\n\t\t\t.column-time {\n\t\t\t\twidth: 170px;\n\t\t\t}\n\n\t\t\t.column-items,\n\t\t\t.column-total {\n\t\t\t\twidth: 9%;\n\t\t\t}\n\n\t\t\t.column-actions {\n\t\t\t\twidth: 9%;\n\t\t\t\ttext-align: right;\n\t\t\t}\n\n\t\t\t.column-ip {\n\t\t\t\twidth: 220px;\n\t\t\t}\n\n\t\t\t.column-created,\n\t\t\t.column-last_active {\n\t\t\t\twidth: 200px;\n\t\t\t}\n\t\t}\n\n\n\t\t&--guests {\n\n\t\t\t.column-id {\n\t\t\t\twidth: 8%;\n\t\t\t}\n\n\t\t\t.column-email {\n\t\t\t\twidth: 26%;\n\t\t\t}\n\n\t\t\t.column-actions {\n\t\t\t\twidth: 115px;\n\t\t\t}\n\t\t}\n\n\n\t\t&--events {\n\n\t\t\t.column-id {\n\t\t\t\twidth: 8%;\n\t\t\t}\n\n\t\t\t.column-status {\n\t\t\t\twidth: 12%;\n\t\t\t}\n\n\n\t\t}\n\t}\n}\n\n\n.aw-before-report-output {\n\n}\n","$modal-header-height: 53px;\n\nbody.automatewoo-modal-open {\n\toverflow: hidden;\n}\n\n.automatewoo-modal-container {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 100000;\n\t// Center it vertically and horizontally.\n\tdisplay: grid;\n\talign-content: center;\n\talign-items: center;\n\tjustify-content: center;\n\tjustify-items: center;\n}\n\n.automatewoo-modal {\n\tposition: relative;\n\tmax-height: 100%;\n\twidth: min(560px, 93vw);\n\tdisplay: grid;\n\tgrid-template:\n\t\t[content-start x-start] #{$modal-header-height}\n\t\t[x-end] auto\n\t\t[content-end] /\n\t\t[content-start] 1fr [x-start] #{$modal-header-height} [x-end content-end];\n\t// Prevent overflowing children's box-shadow.\n\toverflow: hidden;\n\n\tbody.automatewoo-modal-loading & {\n\n\t\t@include loader();\n\n\t\t.automatewoo-modal__body {\n\t\t\topacity: 0.4;\n\t\t}\n\t}\n\n\t.automatewoo-icon-close {\n\t\ttext-align: center;\n\t\t// Place it at the top right corner within the grid.\n\t\tgrid-area: x;\n\t\tcolor: #666;\n\t\tcursor: pointer;\n\t\tbox-shadow: -1px 1px $grey-light-border;\n\n\t\t&::before {\n\t\t\tfont-size: 23px;\n\t\t\tfont-family: dashicons;\n\t\t\tline-height: $modal-header-height;\n\t\t\tspeak: none;\n\t\t\t-webkit-font-smoothing: antialiased;\n\t\t\tcontent: \"\\f335\";\n\t\t}\n\n\t\t&:hover {\n\t\t\tbackground: $grey-very-light;\n\t\t\tcolor: $black;\n\t\t}\n\t}\n\n\n\th2 {\n\t\tfont-size: 1.4em;\n\t}\n\n\th3 {\n\t\tfont-size: 1.2em;\n\t}\n}\n\n.automatewoo-modal--size-lg {\n\twidth: min(680px, 93vw);\n}\n\n.automatewoo-modal__contents {\n\tbackground-color: $grey-very-light;\n\t// Make it scroll the content except for the header.\n\tdisplay: grid;\n\tgrid-template-rows: auto 1fr;\n\t// Make the content span all grid areas.\n\tgrid-area: content;\n\tmax-height: 93vh;\n}\n\n.automatewoo-modal-overlay {\n\tbackground: rgba(#000, 0.35);\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n}\n\n\n.automatewoo-modal__header {\n\tdisplay: flex;\n\talign-items: center;\n\tmin-height: $modal-header-height;\n\tpadding-right: $modal-header-height;\n\tbackground: $white;\n\tborder-bottom: 1px solid $grey-light-border;\n\tbox-shadow: 0 4px 4px -4px rgba(0, 0, 0, 0.1);\n\n\th1 {\n\t\tpadding: 0 18px;\n\t\tfont-size: 19px;\n\t\tline-height: 1.2;\n\t\tmargin: 0;\n\t}\n}\n\n\n.automatewoo-modal__footer {\n\tbox-sizing: border-box;\n\tbackground: $white;\n\tborder-top: 1px solid $grey-light-border;\n\tbox-shadow: 0 -4px 4px -4px rgba(0, 0, 0, 0.1);\n\tpadding: 14px 18px;\n\ttext-align: right;\n\n\t&.aw-pull-right {\n\t\twidth: 100%;\n\t\tfloat: right;\n\n\t\t.button {\n\t\t\tmargin-left: 3px;\n\t\t}\n\t}\n}\n\n\n.automatewoo-modal__body {\n\toverflow: auto;\n\tmin-height: 130px;\n\n\thr {\n\t\tmargin: 17px 0;\n\t\tborder: none;\n\t\tborder-bottom: 1px solid $grey-light-border;\n\t}\n\n\tul {\n\t\tmargin: 17px 0 17px;\n\t}\n}\n\n.automatewoo-modal__body-inner {\n\tmargin: 17px 18px 22px;\n}\n\n","$color-table-border: #e5e5e5;\n$color-table-alt-bg: #f9f9f9;\n\n.automatewoo-table {\n\tline-height: 1.3;\n\tcolor: $color-text-dark-grey;\n\tbackground: #fff;\n\tborder: 0;\n\tborder-spacing: 0;\n\tmargin: 0;\n\twidth: 100%;\n\n\t&--bordered {\n\t\tborder: 1px solid $color-table-border;\n\t\tbox-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);\n\t}\n\n\ta {\n\t\ttext-decoration: none;\n\t}\n\n\t& &__col {\n\t\tvertical-align: top;\n\t\tborder: 0 none;\n\t\tborder-top: 1px solid #f2f2f2;\n\t\tpadding: 18px 20px 18px 20px;\n\t\tfloat: none;\n\t}\n\n\t// use when the only element in the cell is a field label text\n\t& &__col--label {\n\t\tborder-top-color: #f0f0f0;\n\t\twidth: 31.5%;\n\t\tline-height: 1.15;\n\t\tfont-size: 13px;\n\t\tfont-weight: 600;\n\t\tborder-right: 1px solid #e6e6e6;\n\t\tbackground: $color-table-alt-bg;\n\n\t\t.automatewoo-help-tip {\n\t\t\tmargin: 0;\n\t\t\tposition: relative;\n\t\t}\n\t}\n\n\t// use when the only element in the cell is a field\n\t& &__col--field {\n\t\tpadding-top: 13px;\n\t\tpadding-bottom: 13px;\n\t}\n\n\t& &__row:first-child &__col {\n\t\tborder-top: none;\n\t}\n}\n\n\n.automatewoo-cart-table {\n\tbackground: transparent;\n\twidth: 100%;\n\ttext-align: left;\n\tborder: 1px solid $grey-border;\n\tborder-bottom: none;\n\tborder-right: none;\n\tmargin: 20px 0;\n\n\tth,\n\ttd {\n\t\tpadding: 11px 14px;\n\t\tvertical-align: top;\n\t\tborder: none;\n\t\tborder-bottom: 1px solid $grey-border;\n\t\tborder-right: 1px solid $grey-border;\n\t}\n}\n\n\n//\n//.automatewoo-info-table {\n//\twidth: 100%;\n//\tbackground: $white;\n//\tborder-spacing: 0;\n//\tcolor: #505050;\n//\t@extend %table_border;\n//\n//\ta {\n//\t\ttext-decoration: none;\n//\t}\n//\n//\ttr th {\n//\t\twidth: 270px;\n//\t}\n//\n//\tth,\n//\ttd {\n//\t\ttext-align: left;\n//\t\tpadding: 14px 14px;\n//\t\tfont-size: 13.5px;\n//\n//\t\t&:not(:last-child) {\n//\t\t\t//border-right: 1px solid $grey-light-border;\n//\t\t}\n//\t}\n//\n//\tth {\n//\t\tfont-weight: 600;\n//\t}\n//\n//\ttr:nth-child(2n + 1) {\n//\t\tbackground: $color-table-alt-bg;\n//\t}\n//}\n",".aw-workflow-variables-container {\n\n\t.aw-variables-group {\n\t\tmargin: 0 0 9px;\n\t}\n\n\t.aw-workflow-variable-outer {\n\t\tfont-family: Consolas, Monaco, monospace;\n\t\tfont-size: 0;\n\t\tmargin: 0 2px 5px 0;\n\t\tdisplay: inline-block;\n\t\tpadding: 0;\n\t\tline-height: 1;\n\t\tcursor: pointer;\n\t\tbackground: $grey-very-light;\n\t\tborder-radius: 10px;\n\t\tborder: 1px solid $grey-light-border;\n\n\t\t&:hover {\n\t\t\tbackground: $grey-light-border;\n\t\t}\n\n\t\t.aw-workflow-variable {\n\t\t\tpadding: 2px 9px 3px;\n\t\t\tdisplay: block;\n\t\t\tline-height: 1.35;\n\t\t\tfont-size: 11.5px;\n\t\t\tword-break: break-all;\n\t\t}\n\t}\n}\n\n.aw-workflow-variable-parameters-table {\n\tmargin: 18px 0 21px;\n}\n\n.aw-workflow-variable-clipboard-form {\n\tpadding: 0 0 12px;\n\n\t.aw-workflow-variable-preview-field {\n\t\tbox-sizing: border-box;\n\t\tline-height: 1.45;\n\t\tborder: 1px solid #ddd;\n\t\tbox-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.07);\n\t\tfont-family: Consolas, Monaco, monospace;\n\t\twidth: 100%;\n\t\tpadding: 18px;\n\t\tfont-size: 12.5px;\n\t\tmargin: 0 5px 9px 0;\n\t\ttext-align: center;\n\t\tbackground: $white;\n\t}\n\n\t.aw-clipboard-btn {\n\t\twidth: 100%;\n\t}\n}\n\n","\n.woocommerce .aw-settings-tab-container {\n\tmax-width: 1100px;\n\tpadding: 5px 0 0;\n\n\n\tp.submit {\n\t\tmargin-top: -5px;\n\t\tpadding: 0;\n\t}\n\n\n\t.form-table {\n\n\t\tinput[type=\"text\"],\n\t\tinput[type=\"password\"],\n\t\tselect,\n\t\ttextarea {\n\t\t\tmargin: 0;\n\t\t\twidth: 450px;\n\t\t\tpadding: 6px;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\n\t\tinput[type=\"number\"] {\n\t\t\twidth: 100px;\n\t\t}\n\t}\n\n\t.form-table th {\n\t\twidth: 210px;\n\t\tpadding-right: 40px !important;\n\t}\n\n\t.aw-settings-section:not(:first-child) {\n\t\tborder-top: 1px solid $grey-light-border;\n\t\tpadding-top: 25px;\n\t\tmargin-top: 25px;\n\t}\n\n\n\t.wp-editor-wrap {\n\t\tmargin: 0 0 8px;\n\t}\n\n\n\t.forminp {\n\n\t\t.description {\n\t\t\tfont-size: 13px;\n\t\t\tfont-style: italic;\n\t\t\tcolor: #737373;\n\t\t\tline-height: 1.4;\n\t\t}\n\t}\n\n\t.forminp-checkbox {\n\n\t\tfieldset {\n\t\t\tmin-height: 25px;\n\t\t\tposition: relative;\n\t\t}\n\n\t\tlabel {\n\t\t\tposition: absolute;\n\t\t\ttop: 2px;\n\t\t\tleft: 0;\n\t\t}\n\n\t\t.description {\n\t\t\tdisplay: inline-block;\n\t\t\tpadding: 5px 0 3px 29px;\n\t\t}\n\t}\n\n\n\tcode {\n\t\tfont-size: 12px;\n\t}\n\n\n\t.automatewoo-settings__input-wrap {\n\t\tposition: relative;\n\t}\n\n\t.automatewoo-help-tip {\n\t\tposition: absolute;\n\t\ttop: 11px;\n\t\tleft: -32px;\n\t}\n\n}\n\n.automatewoo-settings-submit {\n\tpadding-top: 15px;\n}\n\n.form-table .aw-settings-row {\n\n\t&--checkbox-group {\n\n\t\ttd {\n\t\t\tpadding-top: 0;\n\t\t}\n\t}\n}\n","#adminmenu .toplevel_page_automatewoo {\n\n\t.wp-first-item,\n\ta[href=\"admin.php?page=automatewoo-data-upgrade\"],\n\ta[href=\"admin.php?page=automatewoo-preview\"],\n\ta[href=\"admin.php?page=wc-admin&path=/automatewoo/manual-workflow-runner\"],\n\ta[href=\"admin.php?page=wc-admin&path=%2Fautomatewoo%2Fmanual-workflow-runner\"] {\n\t\tdisplay: none;\n\t}\n}\n","$btn-background-color: #f7f7f7;\n$btn-border-color: #ccc;\n\n$field-border-color: #ddd;\n$field-border-color-active: #a1a1a1;\n\n\n.automatewoo-field {\n\tmargin: 1px;\n\twidth: 100%;\n\n\t&--invalid {\n\t\tborder-color: $red !important;\n\t\tbox-shadow: 0 0 2px $red-light !important;\n\t}\n\n\t&--type-text,\n\t&--type-number {\n\t\theight: 28px;\n\t}\n\n\t&--monospace {\n\t\tfont-family: Consolas, Monaco, monospace;\n\t\tfont-size: 13px;\n\t\tword-break: break-all;\n\t}\n\n}\n\n.wp-admin select.automatewoo-field {\n\tmax-width: 100%;\n}\n\n.automatewoo-field-errors {\n\tmargin-top: 7px;\n\tcolor: $red;\n\tfont-weight: 500;\n\tline-height: 1.1;\n}\n\n.automatewoo-field-errors__error {\n\tmargin-top: 4px;\n}\n\n.automatewoo-table__col {\n\n\t.wc-enhanced-select,\n\t.select2-container,\n\t.select2-search,\n\t.select2-search__field {\n\t\twidth: 100% !important;\n\t}\n}\n\n.automatewoo-table__col--field {\n\n\tinput[type=\"checkbox\"] {\n\t\tmargin: 6px 0;\n\t}\n}\n\n\n.automatewoo-field-wrap {\n\tposition: relative;\n}\n\n\n.automatewoo-field-row--loading {\n\n\t.automatewoo-field-wrap {\n\n\t\t@extend .aw-loader;\n\n\t\t&::before {\n\t\t\tleft: 20px;\n\t\t\tmargin-left: 0;\n\t\t}\n\t}\n\n\t.automatewoo-field-wrap > * {\n\t\topacity: 0;\n\t}\n\n}\n\n\n.field-gap {\n\tmargin: 8px 0;\n}\n\n.field-cols {\n\n\t.col-1,\n\t.col-2 {\n\t\tfloat: left;\n\t\twidth: 48%;\n\t}\n\n\t.col-2 {\n\t\tfloat: right;\n\t}\n}\n\n\n.aw-field-description {\n\tcolor: $grey-text-light;\n\tfont-size: 13px;\n\tmargin: 7px 1px 0;\n\tfont-style: italic;\n}\n\n\n.aw-required-asterisk {\n\tcolor: $red;\n\tfont-weight: bold;\n\n\t&::before {\n\t\tcontent: \"*\";\n\t}\n}\n\n\nselect.aw-field.wc-enhanced-select {\n\tdisplay: none;\n}\n\n.automatewoo-input-group {\n\tposition: relative;\n\tdisplay: table;\n\tborder-collapse: separate;\n\n\t&__input,\n\t&__addon {\n\t\tvertical-align: middle;\n\t\tdisplay: table-cell !important;\n\t}\n\n\t&__input {\n\t\twidth: 100%;\n\t\tfloat: left;\n\t}\n\n\t&__addon {\n\t\twidth: 1%;\n\t\twhite-space: nowrap;\n\t}\n\n\t&__addon--pad-right {\n\t\tpadding-right: 10px;\n\t}\n}\n\n\n.automatewoo-label {\n\tdisplay: block;\n\tfont-weight: 600;\n\tmargin: 0 0 7px;\n\tfont-size: 13px;\n\n\t&--inline-checkbox {\n\t\tmargin: 3px 0;\n\n\t\t.automatewoo-field--type-checkbox {\n\t\t\tmargin-left: 8px;\n\t\t}\n\t}\n\n\t&--weight-normal {\n\t\tfont-weight: normal !important;\n\t}\n\n\t&__extra {\n\t\tfont-weight: normal !important;\n\t\tfont-size: 12px;\n\t}\n\n\n}\n\n\n.automatewoo-time-field-group {\n\n\t@include clearfix;\n\n\t&__fields {\n\t\tmax-width: 140px;\n\t}\n\n\t.automatewoo-field {\n\t\twidth: 44%;\n\t\tfloat: left;\n\t}\n\n\t&__sep {\n\t\tfloat: left;\n\t\ttext-align: center;\n\t\twidth: 6%;\n\t\tmargin-top: 6px;\n\t}\n\n\t&__24hr-note {\n\t\tfont-weight: normal !important;\n\t\tfont-size: 12px;\n\t\tmargin-left: 7px;\n\t\tdisplay: inline-block;\n\t\tmargin-top: 11px;\n\t}\n}\n\n\n.automatewoo-before-after-day-field-group {\n\n\t&__field {\n\t\tmargin: 1px;\n\t\tvertical-align: top;\n\n\t\t&--days {\n\t\t\twidth: 50px;\n\t\t}\n\n\t\t&--type {\n\t\t\tmin-width: 35%;\n\t\t}\n\t}\n}\n\n.automatewoo-list-table-form .tablenav {\n\n\t.select2-selection--single {\n\t\theight: 30px;\n\n\t\t.select2-selection__rendered {\n\t\t\theight: 30px;\n\t\t\tline-height: 2;\n\t\t\tfont-size: 14px;\n\t\t}\n\n\t\t.select2-selection__arrow {\n\t\t\theight: 28px;\n\t\t}\n\t}\n}\n\n.automatewoo-field-group--email-address-with-name {\n\n\t@include clearfix;\n\n\t.automatewoo-field-group__fields {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\n\t\t.automatewoo-field {\n\t\t\twidth: 49%;\n\t\t}\n\t}\n}\n","@mixin clearfix() {\n\t*zoom: 1;\n\n\t&::before,\n\t&::after {\n\t\tcontent: \" \";\n\t\tdisplay: table;\n\t}\n\n\t&::after {\n\t\tclear: both;\n\t}\n}\n\n\n@mixin dashicon( $icon ) {\n\tdisplay: inline-block;\n\tfont: 400 18px/1 dashicons;\n\tcontent: $icon;\n\tspeak: none;\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n\tvertical-align: top;\n}\n","$breakpoint-sm: 782px;\n$breakpoint-md: 1000px;\n$breakpoint-lg: 1200px;\n$breakpoint-xl: 1500px;\n$breakpoint-xxl: 1760px;\n\n\n.aw-rules-container {\n\tpadding: 14px 20px 9px;\n}\n\n\n.aw-rule-group__or {\n\tmargin: 26px -20px 23px;\n\tborder-bottom: 1px solid $grey-light-border;\n\ttext-align: center;\n\tposition: relative;\n\n\tspan {\n\t\tposition: absolute;\n\t\tleft: 50%;\n\t\ttransform: translateX(-50%);\n\t\tcolor: #a9a9a9;\n\t\tdisplay: inline-block;\n\t\tbackground: $white;\n\t\tpadding: 0 13px;\n\t\ttop: -9px;\n\t\tletter-spacing: 1px;\n\t\ttext-transform: uppercase;\n\t\tfont-size: 13px;\n\t}\n}\n\n\n.aw-rule-group {\n\n\t&:last-child {\n\t\tmargin-bottom: 10px;\n\n\t\t.aw-rule-group__or {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n}\n\n\n.automatewoo-rule-container {}\n\n\n.automatewoo-rule {\n\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tposition: relative;\n\tpadding: 7px 0;\n\n\t@include clearfix();\n\n\t@media ( min-width: $breakpoint-lg) {\n\t\tpadding-right: 79px;\n\t}\n\n\t&__buttons {\n\t\tposition: absolute;\n\t\tbottom: 4px;\n\t\tright: -1px;\n\n\t\t@media ( min-width: ($breakpoint-sm + 1)) {\n\t\t\tbottom: 8px;\n\t\t}\n\n\t\t@media ( min-width: $breakpoint-lg) {\n\t\t\ttop: 8px;\n\t\t\tbottom: auto;\n\t\t}\n\n\t\t.automatewoo-rule--type-select & {\n\t\t\tmin-height: 46px;\n\n\t\t\t@media ( min-width: ($breakpoint-sm + 1)) {\n\t\t\t\tmin-height: 34px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t&__add {\n\t\tfloat: left;\n\t\tpadding: 0 8px 1px;\n\t}\n\n\t&__remove {\n\t\tdisplay: block;\n\t\tfloat: left;\n\t\tposition: relative;\n\t\ttop: 9px;\n\t\twidth: 23px;\n\t\theight: 23px;\n\t\tmargin-left: 6px;\n\t\tborder: 1px solid #c5c5c5;\n\t\tborder-radius: 50%;\n\t\tbackground: transparent;\n\t\tcursor: pointer;\n\n\t\t&::after {\n\t\t\tdisplay: block;\n\t\t\tcontent: \"\";\n\t\t\twidth: 11px;\n\t\t\theight: 1px;\n\t\t\tposition: absolute;\n\t\t\ttop: 10px;\n\t\t\tleft: 5px;\n\t\t\tbackground: #c5c5c5;\n\t\t}\n\n\t\t&:hover {\n\t\t\tborder-color: $red;\n\t\t\tbackground: $red-light;\n\n\t\t\t&::after {\n\t\t\t\tbackground: $white;\n\t\t\t}\n\t\t}\n\n\t\t@media ( min-width: ( $breakpoint-sm + 1 ) ) {\n\t\t\ttop: 4px;\n\t\t}\n\t}\n\n\n\t&__fields {\n\t\twidth: 100%;\n\n\t\t.aw-rule-select-container {\n\t\t\twidth: 50%;\n\t\t\tpadding-left: 0;\n\n\t\t\tselect {\n\t\t\t\twidth: 100%;\n\t\t\t}\n\t\t}\n\n\n\t\t.aw-rule-field-compare {\n\t\t\twidth: 50%;\n\t\t}\n\n\t\t.aw-rule-field-value {\n\t\t\tposition: relative;\n\t\t\twidth: 100%;\n\t\t\tpadding-left: 0;\n\t\t\tpadding-top: 8px;\n\t\t\tpadding-right: 94px;\n\n\t\t\t.aw-loader {\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 14px;\n\t\t\t\tleft: 20px;\n\t\t\t}\n\n\t\t\tselect,\n\t\t\t.select2-container {\n\t\t\t\twidth: 100% !important;\n\n\t\t\t\t.select2-search__field {\n\t\t\t\t\tmax-width: 50px;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t@media ( min-width: ( $breakpoint-sm + 1 ) ) {\n\t\t\t\tpadding-right: 85px;\n\t\t\t}\n\t\t}\n\n\t\t@media ( min-width: $breakpoint-lg ) {\n\n\t\t\t.aw-rule-select-container {\n\t\t\t\twidth: 35%;\n\t\t\t}\n\n\t\t\t.aw-rule-field-compare {\n\t\t\t\twidth: 20%;\n\t\t\t}\n\n\t\t\t.aw-rule-field-value {\n\t\t\t\tpadding: 0 6px;\n\t\t\t\twidth: 45%;\n\t\t\t}\n\t\t}\n\n\t\t@media ( min-width: $breakpoint-xl ) {\n\n\t\t\t.aw-rule-select-container {\n\t\t\t\twidth: 30%;\n\t\t\t}\n\n\t\t\t.aw-rule-field-compare {\n\t\t\t\twidth: 18%;\n\t\t\t}\n\n\t\t\t.aw-rule-field-value {\n\t\t\t\twidth: 52%;\n\t\t\t}\n\t\t}\n\n\n\t\t@media ( min-width: $breakpoint-xxl ) {\n\n\t\t\t.aw-rule-select-container {\n\t\t\t\twidth: 26%;\n\t\t\t}\n\n\t\t\t.aw-rule-field-compare {\n\t\t\t\twidth: 16%;\n\t\t\t}\n\n\t\t\t.aw-rule-field-value {\n\t\t\t\twidth: 58%;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t&__field-container {\n\t\tfloat: left;\n\t\twidth: 100px;\n\t\tbox-sizing: border-box;\n\t\tpadding: 0 6px;\n\t}\n\n\n\t&--type-meta {\n\n\t\t.js-rule-value-field {\n\t\t\twidth: 48%;\n\t\t\tfloat: left;\n\n\t\t\t@media ( min-width: $breakpoint-xl ) {\n\t\t\t\twidth: 48.7%;\n\t\t\t}\n\n\t\t\t&:last-child {\n\t\t\t\tfloat: right;\n\t\t\t}\n\t\t}\n\t}\n\n\t&--type-meta.automatewoo-rule--compare-blank,\n\t&--type-meta.automatewoo-rule--compare-not_blank {\n\n\t\t.js-rule-value-field {\n\t\t\twidth: 100%;\n\n\t\t\t&:last-child {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t}\n\t}\n\n}\n\n// fix height of text and number inputs\n.automatewoo-rule input.automatewoo-field {\n\theight: 28px;\n}\n\n.automatewoo-missing-rule {\n\tpadding: 8px 9px;\n\tmargin: 7px 0;\n\tborder: 1px solid $red;\n\tborder-radius: 4px;\n\tcolor: $red;\n\tfont-weight: 500;\n\tline-height: 1.3;\n}\n","body.post-type-aw_workflow .wp-list-table {\n\n\t.column-primary {\n\t\twidth: 48%;\n\t}\n\n\t.column-timing {\n\t\twidth: 20%;\n\t}\n\n\t.column-times_run,\n\t.column-queued {\n\t\twidth: 95px;\n\t}\n\n\t.column-aw_status_toggle {\n\t\twidth: 70px;\n\n\t\t.aw-switch {\n\t\t\tfloat: right;\n\t\t\tmargin: 9px 10px 0 0;\n\t\t}\n\t}\n}\n\n","body.post-type-aw_workflow {\n\n\t#pageparentdiv {\n\t\tdisplay: none;\n\t}\n\n\t#aw_trigger_box,\n\t#aw_actions_box,\n\t#aw_options_box,\n\t#aw_variables_box {\n\n\t\t&.aw-loading {\n\n\t\t\t.inside,\n\t\t\th3.hndle {\n\t\t\t\topacity: 0.45;\n\t\t\t}\n\n\t\t\t@include loader();\n\t\t}\n\t}\n}\n\n\n// Hide unwanted metabox headers\n#aw_save_box,\n#aw_timing_box,\n#aw_variables_box {\n\n\t.handlediv,\n\t.hndle,\n\t.postbox-header { // .postbox-header was added in WP 5.5\n\t\tdisplay: none;\n\t}\n}\n\n\n#post-body .automatewoo-metabox.postbox {\n\n\th3.hndle {\n\t\tborder-bottom: 1px solid $grey-light-border;\n\t\tpadding: 9px 15px;\n\t}\n\n\t&.no-drag .hndle {\n\t\tcursor: default;\n\t}\n\n\t.inside {\n\t\tpadding: 0;\n\t\tmargin: 0;\n\t}\n}\n\n\n.automatewoo-metabox.postbox {\n\n\t.automatewoo-metabox-footer {\n\t\tpadding: 9px 15px;\n\t\tbackground: $grey-very-light;\n\t\tborder-top: 1px solid $grey-light-border;\n\t\ttext-align: right;\n\t}\n\n\t.automatewoo-metabox-pad {\n\t\tpadding: 20px;\n\t}\n\n\th2.hndle {\n\n\t\tsmall {\n\t\t\tfont-weight: normal;\n\t\t\tpadding-left: 1px;\n\t\t}\n\n\t\t.automatewoo-help-link {\n\t\t\tposition: relative;\n\t\t\ttop: 2px;\n\t\t\tleft: -11px;\n\t\t}\n\t}\n}\n\nbody.wc-wp-version-gte-55 {\n\n\t.automatewoo-metabox.postbox {\n\n\t\th2.hndle {\n\n\t\t\tsmall {\n\t\t\t\tfont-weight: normal;\n\t\t\t\tpadding-left: 6px;\n\t\t\t\tflex-grow: 1;\n\t\t\t}\n\n\t\t\t.automatewoo-help-link {\n\t\t\t\ttop: 1px;\n\t\t\t\tleft: 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Make Backbone.View wrappers inert\n// for AutomateWoo.Modal content's grid layout.\n.aw-view-trigger-preset-activation-modal,\n.aw-view-trigger-compatibility-modal {\n\tdisplay: contents;\n}\n","$gutter: 20px;\n\n$color-dashboard-text-light-grey: #aaa;\n$color-dashboard-light-border: #e5e5e5;\n$color-dashboard-light-grey-bg: #fafafa;\n\n\n%box-style {\n\tbackground: $white;\n\tborder: 1px solid $color-dashboard-light-border;\n\tbox-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);\n}\n\n%box-style-link-hover {\n\tdisplay: block;\n\ttext-decoration: none;\n\n\t&:hover {\n\t\tbackground: $color-dashboard-light-grey-bg;\n\t}\n}\n\n\n.automatewoo-page--dashboard {\n\toverflow: hidden;\n}\n\n.automatewoo-dashboard {\n\n\t&-header {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tflex-wrap: wrap;\n\t}\n\n\t// DATE RANGE\n\t&-date-nav__tab {\n\t\tposition: relative;\n\t\tline-height: 1;\n\n\t\t&::after {\n\t\t\tcontent: \"\";\n\t\t\tposition: absolute;\n\t\t\tbottom: 0;\n\t\t\tleft: 0;\n\t\t\tright: 0;\n\t\t\theight: 0;\n\t\t\tbackground-color: var(--wp-admin-theme-color);\n\t\t}\n\n\t\t&--current::after {\n\t\t\theight: var(--wp-admin-border-width-focus);\n\t\t}\n\t}\n\n\t&-widgets {\n\t\tmargin-top: 20px;\n\t\tmargin-right: -$gutter;\n\t}\n\n\t&-widget-sizer {\n\t\twidth: calc(100% - #{$gutter});\n\n\t\t@media ( min-width: 800px ) {\n\t\t\twidth: calc(50% - #{$gutter});\n\t\t}\n\n\t\t@media ( min-width: 1200px ) {\n\t\t\twidth: calc(33.33% - #{$gutter});\n\t\t}\n\n\t\t@media ( min-width: 1750px ) {\n\t\t\twidth: calc(25% - #{$gutter});\n\t\t}\n\t}\n\n\t// WIDGETS\n\n\t&-widget {\n\t\tmargin-bottom: $gutter;\n\t\twidth: calc(100% - #{$gutter});\n\n\t\t@media ( min-width: 800px ) {\n\t\t\twidth: calc(50% - #{$gutter});\n\t\t}\n\n\t\t@media ( min-width: 1200px ) {\n\t\t\twidth: calc(33.33% - #{$gutter});\n\t\t}\n\n\t\t@media ( min-width: 1750px ) {\n\t\t\twidth: calc(25% - #{$gutter});\n\t\t}\n\t}\n\n\t&-widget__content {\n\n\t}\n\n\n\t// KEY FIGURES\n\n\t&-widget--key-figures {\n\t\tmargin-bottom: 0;\n\t}\n\n\t&__figures {\n\t\tmargin: 0 calc(-1 * $gutter / 2);\n\n\t\t@include clearfix;\n\t}\n\n\t&__figure {\n\n\t\t@extend %box-style;\n\t\t@extend %box-style-link-hover;\n\t\tdisplay: block;\n\t\tmargin: 0 calc($gutter / 2) $gutter;\n\t\tfloat: left;\n\t\twidth: calc(50% - #{$gutter});\n\t\ttext-align: center;\n\t\tbackground-color: #fff;\n\t\tbox-sizing: border-box;\n\t\tpadding: 17px 10px 21px;\n\t}\n\n\t&__figure-name {\n\t\tcolor: $color-dashboard-text-light-grey;\n\t\twhite-space: nowrap;\n\t\ttext-overflow: ellipsis;\n\t\toverflow: hidden;\n\t\tfont-size: 12.5px;\n\t}\n\n\t&__figure-value {\n\t\tcolor: $color-dark-grey;\n\t\tfont-size: 21px;\n\t\tfont-weight: 300;\n\t\tline-height: 1.3;\n\t}\n\n\n\t// FEATURED WORKFLOWS\n\n\t&__workflows {\n\n\t\t@extend %box-style;\n\t}\n\n\t&__workflow {\n\n\t\t@extend %box-style-link-hover;\n\t\tpadding: 17px 17px;\n\n\t\t&:not(:last-child) {\n\t\t\tborder-bottom: 1px solid $color-dashboard-light-border;\n\t\t}\n\t}\n\n\t&__workflow-title {\n\t\tfont-size: 17px;\n\t\ttext-decoration: none;\n\t}\n\n\t&__workflow-description {\n\t\tcolor: $color-dashboard-text-light-grey;\n\t}\n\n\n\t// CHARTS\n\n\t&-chart {\n\n\t\t@extend %box-style;\n\t\tdisplay: block;\n\t\tposition: relative;\n\n\t\t&[aw-loading] .aw-loader {\n\t\t\topacity: 0.4;\n\t\t}\n\t}\n\n\t&-chart__flot {\n\t\tdisplay: block;\n\t\theight: 150px;\n\t\tmargin: 12px 14px 20px;\n\n\t\t@media ( min-width: 800px ) {\n\t\t\theight: 190px;\n\t\t}\n\n\t\t@media ( min-width: 1200px ) {\n\t\t\theight: 200px;\n\t\t}\n\n\t\t@media ( min-width: 1400px ) {\n\t\t\theight: 220px;\n\t\t}\n\n\n\t\t.flot-x-axis > div {\n\t\t\tmargin-top: 11px;\n\t\t}\n\t}\n\n\t&-chart__tooltip {\n\t\tz-index: 10;\n\t\tposition: absolute;\n\t\tdisplay: none;\n\t\tbackground: $black;\n\t\topacity: 0.75;\n\t\tcolor: $white;\n\t\tpadding: 3px 5px 4px;\n\t\tfont-weight: 500;\n\t\tborder-radius: 3px;\n\t\tfont-size: 11px;\n\t\tline-height: 1;\n\t}\n\n\t&-chart__header {\n\t\tborder-bottom: 1px solid $grey-very-light-border;\n\t\tposition: relative;\n\t\theight: 73px;\n\n\t\toverflow: hidden;\n\n\t\t@include clearfix;\n\t}\n\n\t&-chart__header-group {\n\t\tpadding: 16px 20px;\n\t\tfloat: left;\n\n\t\t&:not(:first-child) {\n\t\t\tborder-left: 1px solid $grey-very-light-border;\n\t\t}\n\t}\n\n\t&-chart__header .automatewoo-arrow-link {\n\t\tposition: absolute;\n\t\tright: 20px;\n\t\ttop: 28px;\n\t}\n\n\t&-chart__header-figure {\n\t\tcolor: $color-dark-grey;\n\t\tfont-size: 21px;\n\t\tfont-weight: 300;\n\t\tline-height: 1.1;\n\t}\n\n\t&-chart__header-text {\n\t\tcolor: $color-dashboard-text-light-grey;\n\t\tfont-size: 12.5px;\n\t}\n\n\t&-chart__legend {\n\t\tdisplay: inline-block;\n\t\twidth: 4px;\n\t\theight: 4px;\n\t\tborder: 2px solid $grey-light-border;\n\t\tmargin-right: 1px;\n\t\tborder-radius: 50%;\n\t}\n\n\t&-chart__legend--blue {\n\t\tborder-color: #3498db;\n\t}\n\n\t&-chart__legend--purple {\n\t\tborder-color: #d0a0e4;\n\t}\n\n\t&-chart__legend--green {\n\t\tborder-color: #72c9b2;\n\t}\n\n\n\t// LIST TABLE\n\n\t&-list {\n\n\t\t@extend %box-style;\n\t}\n\n\t&-list__header {\n\t\tborder-bottom: 1px solid $grey-very-light-border;\n\t\tpadding: 22px 20px;\n\t}\n\n\t&-list__header .automatewoo-arrow-link {\n\t\tposition: absolute;\n\t\tright: 20px;\n\t\ttop: 22px;\n\t}\n\n\t&-list__heading {\n\t\tfont-weight: 500;\n\t\tcolor: $color-dark-grey;\n\t\tfont-size: 14px;\n\t}\n\n\t&-list__items {}\n\n\t&-list__item {\n\t\tpadding: 12px 20px;\n\t\tbackground: #f9f9f9;\n\n\t\t&:not(:last-child) {\n\t\t\tborder-bottom: 1px solid $grey-very-light-border;\n\t\t}\n\t}\n\n\t&-list__item-title {\n\t\ttext-decoration: none;\n\t\tfont-weight: 500;\n\t}\n\n\t&-list__item-text {\n\t\tfont-size: 12.5px;\n\t\tcolor: $color-dashboard-text-light-grey;\n\t}\n\n\t&-list__item-button {\n\t\tfloat: right;\n\t}\n\n\t&-list__empty {\n\t\ttext-align: center;\n\t\tbackground: #f9f9f9;\n\t\tpadding: 60px 20px;\n\t\tcolor: $color-dashboard-text-light-grey;\n\n\t}\n\n}\n",".automatewoo-welcome-notice {\n\tpadding: 25px 305px 20px 36px !important;\n\tborder-left-width: 1px;\n\tposition: relative;\n\n\t@media ( max-width: 800px ) {\n\t\tpadding: 20px !important;\n\t}\n\n\t&__image {\n\t\tposition: absolute;\n\t\twidth: 266px;\n\t\theight: 138px;\n\t\ttop: 7px;\n\t\tright: 40px;\n\t\tbackground-image: url(\"../img/presets.svg\");\n\t\tbackground-size: 266px 138px;\n\t\tbackground-repeat: no-repeat;\n\n\t\t@media ( max-width: 800px ) {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t&__heading {\n\t\tcolor: $color-g2-dark-grey;\n\t\tmargin: 0 0 0.25rem 2px;\n\t}\n\n\t&__text p {\n\t\tfont-size: 14px;\n\t\tline-height: 1.65;\n\t\tmargin: 0.5em 0 0;\n\t\tcolor: $color-brand-paragraph-grey;\n\t}\n}\n"]} \ No newline at end of file diff --git a/admin/assets/css/editor.css b/admin/assets/css/editor.css new file mode 100644 index 0000000..d432fdb --- /dev/null +++ b/admin/assets/css/editor.css @@ -0,0 +1 @@ +.aw-coupon-code{font-family:"Helvetica Neue",helvetica,sans-serif;font-weight:bold;display:inline-block;padding:12px 25px 13px;font-size:17px;color:#000;border:2px solid #000}a.aw-btn-1{font-family:"Helvetica Neue",helvetica,sans-serif;background-color:#000;text-decoration:none;border-radius:4px;font-weight:bold;display:inline-block;padding:14px 40px 15px;margin:10px auto;font-size:16px;color:#fff}/*# sourceMappingURL=editor.css.map */ diff --git a/admin/assets/css/editor.css.map b/admin/assets/css/editor.css.map new file mode 100644 index 0000000..9079f20 --- /dev/null +++ b/admin/assets/css/editor.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["editor.scss"],"names":[],"mappings":"AAEA,gBACC,YAHW,sCAIX,iBACA,qBACA,uBACA,eACA,WACA,sBAGD,WACC,YAbW,sCAcX,sBACA,qBACA,kBACA,iBACA,qBACA,uBACA,iBACA,eACA","file":"editor.css","sourcesContent":["$font-sans: \"Helvetica Neue\", helvetica, sans-serif;\n\n.aw-coupon-code {\n\tfont-family: $font-sans;\n\tfont-weight: bold;\n\tdisplay: inline-block;\n\tpadding: 12px 25px 13px;\n\tfont-size: 17px;\n\tcolor: #000;\n\tborder: 2px solid #000;\n}\n\na.aw-btn-1 {\n\tfont-family: $font-sans;\n\tbackground-color: #000;\n\ttext-decoration: none;\n\tborder-radius: 4px;\n\tfont-weight: bold;\n\tdisplay: inline-block;\n\tpadding: 14px 40px 15px;\n\tmargin: 10px auto;\n\tfont-size: 16px;\n\tcolor: #fff;\n}\n"]} \ No newline at end of file diff --git a/admin/assets/css/preview.css b/admin/assets/css/preview.css new file mode 100644 index 0000000..7b42579 --- /dev/null +++ b/admin/assets/css/preview.css @@ -0,0 +1 @@ +@keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.aw-loader::before{height:24px;width:24px;display:block;position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px;animation:spin .8s linear infinite;content:"";background:url("../img/loader.svg") center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75);z-index:10}.aw-loader--left::before{left:0;margin-left:0}#wpadminbar,#adminmenuwrap,#adminmenuback,#adminmenu,#wpfooter{display:none !important}html.wp-toolbar{padding:0 !important}#wpbody,#wpcontent{padding:0 !important;margin:0 !important}.aw-preview{position:relative;height:100%;overflow:hidden}.aw-preview iframe{height:100%}.aw-preview__header{position:relative;z-index:5;padding:19px 50px 24px;box-shadow:rgba(0,0,0,.05) 0 1px 2px 1px;border-bottom:1px solid #e4e4e4;background:#fff}.aw-preview__header-left{font-size:13px;color:#787878;display:inline-block}.aw-preview__header-right{margin:10px 0 0}@media(min-width: 800px){.aw-preview__header-right{margin:4px 0 0;float:right}}.aw-preview__send-test-form{margin:0;float:left}.aw-preview__send-test-form .email-input{font-size:13.5px;margin-top:0;padding:5px 8px 4px;vertical-align:top;width:220px;margin-right:-6px;height:29px}.aw-preview__send-test-form.aw-loading{opacity:.4}.aw-preview .from{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:430px}.aw-preview__loader-container{background:#fff;width:100%;height:100%;position:fixed;top:0;left:0}.wp-core-ui a.aw-preview-options-button{text-decoration:none;float:right;margin-left:9px}/*# sourceMappingURL=preview.css.map */ diff --git a/admin/assets/css/preview.css.map b/admin/assets/css/preview.css.map new file mode 100644 index 0000000..5052a6d --- /dev/null +++ b/admin/assets/css/preview.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["_loader.scss","preview.scss"],"names":[],"mappings":"AACA,gBAEC,KACC,iCACA,0BAMD,mBACC,OAHoB,KAIpB,MAJoB,KAKpB,cACA,kBACA,QACA,SACA,kBACA,iBACA,mCACA,WACA,kDACA,sBACA,cACA,kBACA,cACA,sBACA,WAUF,yBACC,OACA,cCrCD,+DAKC,wBAGD,gBACC,qBAGD,mBAEC,qBACA,oBAID,YACC,kBACA,YAEA,gBAEA,mBACC,YAID,oBACC,kBACA,UACA,uBACA,yCACA,gCACA,gBAID,yBACC,eACA,cACA,qBAGD,0BACC,gBAEA,yBAHD,0BAIE,eACA,aAKF,4BACC,SACA,WAEA,yCACC,iBACA,aACA,oBACA,mBACA,YACA,kBACA,YAGD,uCACC,WAIF,kBACC,mBACA,gBACA,uBACA,gBAMF,8BACC,gBACA,WACA,YACA,eACA,MACA,OAID,wCACC,qBACA,YACA","file":"preview.css","sourcesContent":["\n@keyframes spin {\n\n\t100% {\n\t\t-webkit-transform: rotate(360deg);\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n@mixin loader( $size: 24px ) {\n\n\t&::before {\n\t\theight: $size;\n\t\twidth: $size;\n\t\tdisplay: block;\n\t\tposition: absolute;\n\t\ttop: 50%;\n\t\tleft: 50%;\n\t\tmargin-left: calc(-1 * $size / 2);\n\t\tmargin-top: calc(-1 * $size / 2);\n\t\tanimation: spin 0.8s linear infinite;\n\t\tcontent: \"\";\n\t\tbackground: url(\"../img/loader.svg\") center center;\n\t\tbackground-size: cover;\n\t\tline-height: 1;\n\t\ttext-align: center;\n\t\tfont-size: 2em;\n\t\tcolor: rgba(#000, 0.75);\n\t\tz-index: 10;\n\t}\n}\n\n.aw-loader {\n\n\t@include loader();\n}\n\n\n.aw-loader--left::before {\n\tleft: 0;\n\tmargin-left: 0;\n}\n","@import \"loader\";\n\n// reset UI\n#wpadminbar,\n#adminmenuwrap,\n#adminmenuback,\n#adminmenu,\n#wpfooter {\n\tdisplay: none !important;\n}\n\nhtml.wp-toolbar {\n\tpadding: 0 !important;\n}\n\n#wpbody,\n#wpcontent {\n\tpadding: 0 !important;\n\tmargin: 0 !important;\n}\n\n\n.aw-preview {\n\tposition: relative;\n\theight: 100%;\n\n\toverflow: hidden;\n\n\tiframe {\n\t\theight: 100%;\n\t}\n\n\n\t&__header {\n\t\tposition: relative;\n\t\tz-index: 5;\n\t\tpadding: 19px 50px 24px;\n\t\tbox-shadow: rgba(0, 0, 0, 0.05) 0 1px 2px 1px;\n\t\tborder-bottom: 1px solid #e4e4e4;\n\t\tbackground: #fff;\n\t}\n\n\n\t&__header-left {\n\t\tfont-size: 13px;\n\t\tcolor: #787878;\n\t\tdisplay: inline-block;\n\t}\n\n\t&__header-right {\n\t\tmargin: 10px 0 0;\n\n\t\t@media (min-width: 800px) {\n\t\t\tmargin: 4px 0 0;\n\t\t\tfloat: right;\n\t\t}\n\t}\n\n\n\t&__send-test-form {\n\t\tmargin: 0;\n\t\tfloat: left;\n\n\t\t.email-input {\n\t\t\tfont-size: 13.5px;\n\t\t\tmargin-top: 0;\n\t\t\tpadding: 5px 8px 4px;\n\t\t\tvertical-align: top;\n\t\t\twidth: 220px;\n\t\t\tmargin-right: -6px;\n\t\t\theight: 29px;\n\t\t}\n\n\t\t&.aw-loading {\n\t\t\topacity: 0.4;\n\t\t}\n\t}\n\n\t.from {\n\t\twhite-space: nowrap;\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\tmax-width: 430px;\n\t}\n\n}\n\n\n.aw-preview__loader-container {\n\tbackground: #fff;\n\twidth: 100%;\n\theight: 100%;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n}\n\n\n.wp-core-ui a.aw-preview-options-button {\n\ttext-decoration: none;\n\tfloat: right;\n\tmargin-left: 9px;\n}\n"]} \ No newline at end of file diff --git a/admin/assets/img/blank.gif b/admin/assets/img/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff30c8bacd266ffa9c466f5c4e65a00fe0097b88 GIT binary patch literal 1101 zcmZ?wbhEHbWMp7uXkcLY|NlP&1B2p!?g-xi1((Eh1eo~=?wNlAf~zJ7Umxn8-k zUVc%!zM-Y1rM`iYzLAkGP=#)BWnM{Qg>GK4GRy>*)Z*l#%z~24{5%DaiHS-1r6smX zK$k+ikXryZHm_I@>>a)2{9OHt!~%UoJp+)JUEg{v+u2}(t{7puX=A(aKG z`a!A1`K3k4sX*n*AgcnUy@&(kzb(T>(sS9KFoU6e|}COG8s9a~BsUQ*%Q@R}%{}16M~!3nMo} zV+&JfBTJZGm;B_?+|;}hnBEkGURRuYK?x$a0BEyIYEfocYKmJ?ey#%8<5rot-QtAP zJgD9j+-`BksaGH97=2LmB1Jb$2$+UIOnBl2a^T57H4m8Pi-3un@&CWSe}4b^`Q!Vy zuU|fY`uO4fySHy%zk2!N`Lm}_9zS~c;Qqb4cW&RhdE@%Et5+^xx_IIIxwB_ZpE`Ns z__3o$4j(#rVE?|odv@>Ixnujbty?y4+PGo;y0vRouUffc`Ld-;7B5=3VE(+hb7s$) zIb-^?sZ%CTnmD1queYbWtFxoMt+l1Osj;EHuC}JSsEZK zEj1-MDKQ~FE;c4QDl#HGEHorIC@{d^&)3J>%hSW%&DF)($V~xOjJZzNKk;EkC%s=i<5($jg^I&i4j;r Y{A2-^6ATPGAOci&FfcK>Ffv#J05pVt@&Et; literal 0 HcmV?d00001 diff --git a/admin/assets/img/header-badge.svg b/admin/assets/img/header-badge.svg new file mode 100644 index 0000000..03904c8 --- /dev/null +++ b/admin/assets/img/header-badge.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/admin/assets/img/loader.svg b/admin/assets/img/loader.svg new file mode 100644 index 0000000..4107219 --- /dev/null +++ b/admin/assets/img/loader.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/admin/assets/img/presets.svg b/admin/assets/img/presets.svg new file mode 100644 index 0000000..9add0ad --- /dev/null +++ b/admin/assets/img/presets.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/assets/img/welcome-notice-robot.png b/admin/assets/img/welcome-notice-robot.png new file mode 100644 index 0000000000000000000000000000000000000000..456129307dcdf378b3926ff186b15a7746579f46 GIT binary patch literal 6457 zcmV-98OG*`P);bbgo2jEzvKJ+{kXB(<>L3kyy5lr z`|*@6Q`25+{?X|Ag zsiVxIoWzZXukGsjl#jNNi?itF_MMl&>gM~;$?2MuymfJwM>~#MRE39usg{ttKQE4n zgsV(Ki*IX>Q%Z>DA?g25PIL?b zaB@w>xw8rYkX7F&8i=kywR4>47Zv3=YU@P5GbmtW&_*~VX}a;~6asev6u5u!AJea; z@on=cT#(R(WbK`j=rB@HF1B{sjCyT$x0E3yaNw*iT0VCgqQ{I=52tWWE09JY#D8^A>PXVk4ZBPz#s$kimA;C%g9(3ETz1X9%7Or01<_7r(PX7Yc~1C`S_b48UgyxcJbhf_(C&c&qZDzm&*07B)D-f$SX0!y8%M&~^c%WuZKq7{I7~O?C zAFd&U{yM~=92mbz(;tl9jiH4kT)i`eFmJ*+MI<}+{Iw6rFhkxv_?G910&f8w(y8r_ zt3{!Iu?dl12bW0Pc%sI;AqVJA%y8UP`aREDA;SVJkPA<|VTH4Xn6B!t)h{;eCSZj$ zMT6HCk(?ajq+fVzWY@q2Yhj)XL^)M{iZ>mB8w74&@-+pzkDngyzb`+0v$$1Xfx8f*tRHcAXNvfuSHQe~zx;mx@aay7*kDK8PB2qkRzM&= zdZty6QQu(4AM(w0H*FXU!!g5FAcF{EqOcGY$f0CW(~1a9Y|)}gn}k$N8)$3q|4xQE z89EZ1*i2gc{OTXx;y0iD9US_AqE%8bi1#~gmDk3ogXr>y)zWwe9B93|95T1Vz(Z*3 zVZ{RO794=DtOi^!UQh7=rzU{a!)Lg64-bgrY;}G(K&>2_|j4O&58}FcQ28sUK zvdC~3InXyDaI05B0VxCVG}Sfbb)g*`dz! zO@*J&o)x6q&zkGcy8ou6?}8)x0&$E;9ui1IZkFb&`}!%1Wu6$krNHXhXIFV@_pYAO zdiyy7VP09r0EEgauAMLH1@w4B;jF?cH^(F8dNfg5q#+!Xo|c4o27SCNla^|P!V!@$e3R+jnE$IOuD#9BOS!U!9yv~E?W#amg5W+ULB3MDz1)OFGE}b5I9fSf5SYzPh@G)5$L80#8bNGgt&!vGIgBD()j{bfXnd8w&j zo-kyr1VKOiUTdfu8nq8N01OM6D(Y4RUZxPdBld0iVU*pcAJs6xxW`Lvh5%OX@n3-^XsBKF9gCTwFr!-VY=Uh94k+2HXzpJ(9 z{662tp~DL?o(VL$^<^*}OamPqE?Jsd`O2pxa0*ZdbnOBvcOH)lnjQS3eEM~EjCB03 zf!v;;Sh(FO^)FIurKp(0 zKr~Ssm-aFRH*Vb4>u~g-QDy~8UkR5_8Xzs6)=paVsZTAXYKlrj zhf`%zs)BIwQ~3P%YtazeK}hc7ba10c#`weDxiBS;1Ob>ac9Vb*Ud8|cMc$%B@wsyB zxmb6WcdNJesH?sI|3{7qOC|x5$pa*mepOq$RlD{w&Gd9nch5|{RjIUkWdNwg+FYyQ zBi+it8#*7Uvca%%N$*Vt30r4jfgR^(2duu~8eDkba`#7mcN zp_F%UlYqF6^W{Zz^ZBKg^}Yg%7k4-3=jXeVUpIFbl5G|Az5+^yl-*@gUWhZGF)2JZ zQe0mUXb;mtx&Q2DHL}HOF7D2EuO`F3nQ%V&=1hfiq%WWO9L;3e>q?#{2S&TlR*B+E3~r8;C$+?u8I*#zX-umFevEC^f! zscEL7RoN>8-}a=t$tdrPQQB?s#vHt;!%C!Z9FaF0PIj;R#<5gbTlMysD3>%>cK8Qz zLpP?%WZ>t_T5Zt58zv|X9j7wr;!Mh&vy>Yq#c>^QQy1ECd#=3HU@1BC1nD5;VA7g?Q&?x}+Eahq<1ss;ZTV5>w z+tMHq*VR~?H$tn!2iG0g?^n!xxn}$?tVT-E&CDOR)rr%{yqek^sE18A1!jM~Vur^- z-2D?)A>}V{j3qhfwb|LYW}#O{1n$9x@C^zNrKWohfQ_8X#S1uX2YpBp{{??OgfToa z&&KtQTZ(|WkaciW?^JGe1vtrk&qx(;k|Oz#qCwz%&S$eF3sI)$3wyMfv^HwxmU@3L zgL@sr$J}vtBEF=6&rAa27t4`eKqRUPYrQ1w49WdHuM1$uGcI9_9|aDOVyfXeiYcj069f|eTwa7czm-5fqWMdzSHvX8&e?XV{>uLL_yt;lqNcS z34HF&h7MTmJ&Eb($I)o?m|h5E*iP6b4d4-JScX+dQNZU;n4u+Tg;6fhmS{wn+l9Ou zN_Y+s@I8*>2IJA|Tt?>mp~^3&@!_VkTHY0?hggkob4HIv*|?;rqsj!?eNxX)@hMM! zRrvZ8HyPW1xc!}_68M$u;AL@C!%1QB06(3OB-2cc+O70~xsXwuG4iLsaombcgXuC$ zNAr?!{Hk~ZoTc1)l_E7Tctkq<+q~xvjCC+?(O*CfCZ6Ip#x^TXF$IRTVUY&Fp>0^y z!N=#2<`Dmh9WSkgJjU%j#ys;FpJS9@#H#mf;SXDo?Bgn=T>406Nm9wq&QT&u>{t95 z!%WBLdG+jn$MJcp2N^~Y2?s2^VPRclQuqR-onMbXe=dGDDHb!<2`Hm*lA)ab7pDX= z;^+7R{~cK0s6s-*PC+&S!%MkD@85vM@hUC6s$xFaRio_@Ue9y?A|3Z7tz$v< zgyR7xjPYl~Pw9k(be4Dlup^01M`Q{Fh-WDhSBj57dgsDIQZ+D|ZE11y1T3c4GA z(*Frb`@n}CKS#Y(2Pr#DO0cb*D2W=e9Q(xD+%yWj8GatS?gEpZ$6g=oh|>JPrHX=t z5>ASyAcT!ZrG~2Y%{cnlEgE@B!~$w?{OI&Z3m?EnVeX*nj@D!o$GeoFU5Yf3f`k&L zyd_qUGzMB%L9nzVEKg^pedeP_``|pM)xF zZ3QfMwSl^{9pTYTsCrGs*pt~$Pou|WvCqEG!9!W?cU!F%eId|dc59b{OwpeKXhqaU72X^AhO=zRnd>`=)2 zjHRWy5Ky7lf3chVHbibK-N-ZqgiHMrAW$ClJthU4(!xb$ST0l)@Vklon1YhjGef|h z-tc`c^WCq4VgZp|?_Cdix5WFaEe%973)m!JeYkqF0d{Fk_hP#$Pw8 zlI>vHtS(l7x)i-daCRtZ<7`b*=2DV=r14R{)>MRuyibW}z;#6(*aDMTs-kuBEjivIkk<1b}6V)JUx{0szxsM+S`6*E`>_1=!U4 z7$Gm0%QjVvKqc7Y90$w(nltL197v_0z!a^)J#L#>hJ6Ro()NH+OFa~Xk>$+UB6>kaQ@P>>A`MlMFR za@Ob}n8}X~__}mku+Yx2bQ@q-E2DA0XN1Wkno0C7>pV{9@<&If>((cmevI~sY$=~e9MDoooZYWWjk%Gx!U7Zxdk%qr|nh~OU1MmjY$myWKW@xpuVRAA)Yelj$* zQ(+02eRfF;(C;+j92uYUxb^bMFI zkTTF42n4D=t_IW9RA}w>D#Pywf-5O`OAMHjoK8Q%fun>a4ZEKWsl9ryP!h%8P6cJ^j&T**lf>_*0*B0T)I(@1!kOU8NqXvdk%R!I+M_Km-%bTC z2WN7G_rU+RcgCw}1VI>IZ!zpf)bp;#Rf}SdQsH_bPzb>$gbHo`D1i#a_kWd|8kj`T z9lcMyo4wy7e9YZ^GrK#p#mpHGJ@@58_e3&l?B>p&PBnw;ntZ@i5A2P>9Cho|-ggSk zp%xj~sUJ5R9=OuzPK_`4DP8GgWbVEd4UrOffRiOsZ}L zr{E0iem+Q5FpJ6_Xi^5|)Ks8%Gn7N5q!CsIN!q|sCN}7#TFg)IN;3$%Wde|vMp6=% z6M&Z?B7?ZO7{3uP2{oIr>NzCRZn}NU5CjrXk`2tAF)-|d#&D2;g7i~YC=26mWYK;V zAr@vsj0-?_A7RrBOeN{3E^}7^q9y{850qeFT-_K7K=f$n^?8yg{T!Ki0Q!On^DUL7 zpHi{I1EO*;IcX{XKT^=)0Wmq4zF}ed?Nl&KPBKdDE=%k0|6B@E9~D>!GdqH54K8Hy zGRfrPB-;h7d7AA@A60!5;!rR|c^LQdaU1ORf?@qW-&cB5pobyaG!~jL!Kz3lh2MsF zD+sgG4JNnd&*Qd)X{x7n{QK>AvOy^XYGO#i(ep4R4b!5?CRK0#F^FPAl_W3%ehd!aQAwhM83JemJ~GlUjZ**@!ft*m zLCism9&Ny9sRS{E==X`ALqz$QHC^0-DKC9Y)Q0B}H>0|B^7k+Wj??BdQDR77Bk?^o zg4eAUsvGU45xg7#cl+>pQc{T8z?}?y7D@_~LjaFM`20{(piV;h=UrYp=^=7E7oTyR z&*a|GLAn?|H?=(!-lhxM_PrL+%TlB_fVL9+>q$p#+?rM|Yq_|E>F2))=w&T8!zAIa zHaL)-U^5;M7-=KBp3m2y%jJ6RdU`6m^1=bLBRI75wK)0p%JhV zun~|$BVg5-fCOwRkw(Ddn4<*rwHq^q3Fv7*Fg{l$QoRkI#}S=NKrv?`7w755jA}Fb z-FYg9>IXLG!X-P>&CP_8XClqrm~t;QZQ$wkwgln>KOcH7yi!t_qb{gcxe)mWl}!!v TZ(UDW00000NkvXXu0mjf;LlVy literal 0 HcmV?d00001 diff --git a/admin/assets/js/automatewoo.js b/admin/assets/js/automatewoo.js new file mode 100644 index 0000000..d13020e --- /dev/null +++ b/admin/assets/js/automatewoo.js @@ -0,0 +1,414 @@ +/** + * AutomateWoo main - loaded on every admin page + */ +// Register eslint ignored glabals - to be revisited. +// https://github.com/woocommerce/automatewoo/issues/1212 +/* global automatewooLocalizeScript, ajaxurl */ + +const AutomateWoo = {}, + AW = {}; + +window.AutomateWoo = AutomateWoo; + +( function ( $ ) { + AW.init = function () { + AW.params = automatewooLocalizeScript; + + AW.initTooltips(); + AW.initWorkflowStatusSwitch(); + AW.initShowHide(); + AW.initHoverableDates(); + AW.initBeforeAfterDayField(); + + $( document.body ).on( 'wc-enhanced-select-init', function () { + AW.initEnhancedSelects(); + } ); + + $( document.body ).on( + 'automatewoo_trigger_changed', + AW.initBeforeAfterDayField + ); + }; + + /** + * Init tool tips + */ + AW.initTooltips = function () { + $( '.automatewoo-help-tip, .automatewoo-tiptip' ).tipTip( { + attribute: 'data-tip', + fadeIn: 50, + fadeOut: 50, + delay: 200, + } ); + }; + + /** + * Ajax search search box + */ + AW.initEnhancedSelects = function () { + $( 'select.automatewoo-json-search' ) + .filter( ':not(.enhanced)' ) + .each( function () { + const select2Args = { + allowClear: $( this ).data( 'allow_clear' ) ? true : false, + placeholder: $( this ).data( 'placeholder' ), + minimumInputLength: '1', + escapeMarkup( m ) { + return m; + }, + ajax: { + url: AW.params.url.ajax, + dataType: 'json', + quietMillis: 250, + data( params ) { + const data = { + term: params.term, + action: $( this ).data( 'action' ), + }; + + // pass in sibling field data + const sibling = $( this ).data( 'pass-sibling' ); + if ( sibling ) { + const $sibling = $( + '[name="' + sibling + '"]' + ); + + if ( $sibling.length ) { + data.sibling = $sibling.val(); + } + } + + return data; + }, + processResults( data ) { + const terms = []; + if ( data ) { + $.each( data, function ( id, text ) { + terms.push( { id, text } ); + } ); + } + return { + results: terms, + }; + }, + cache: true, + }, + }; + + $( this ).select2( select2Args ).addClass( 'enhanced' ); + } ); + }; + + AW.initBeforeAfterDayField = function () { + $( '.automatewoo-before-after-day-field-group__field--type' ) + .on( 'change', function () { + const $type = $( this ); + const $days = $type.siblings( + '.automatewoo-before-after-day-field-group__field--days' + ); + + if ( $type.val() === 'on_the_day' ) { + $days.hide(); + } else { + $days.show(); + } + } ) + .trigger( 'change' ); + }; + + AW.initWorkflowStatusSwitch = function () { + $( '.aw-switch.js-toggle-workflow-status' ).on( 'click', function () { + const $switch = $( this ); + + if ( $switch.is( '.aw-loading' ) ) { + return; + } + + const state = $switch.attr( 'data-aw-switch' ); + const newState = state === 'on' ? 'off' : 'on'; + + $switch.addClass( 'aw-loading' ); + $switch.attr( 'data-aw-switch', newState ); + + $.post( + ajaxurl, + { + action: 'aw_toggle_workflow_status', + workflow_id: $switch.attr( 'data-workflow-id' ), + new_state: newState, + nonce: AW.params.nonces.aw_toggle_workflow_status, + }, + function () { + $switch.removeClass( 'aw-loading' ); + } + ); + } ); + }; + + /** + * @param {number} float + * @return {string} Formatted price with the currency symbol. + */ + AW.price = function ( float ) { + let price = float + .toFixed( 2 ) + .replace( '.', AW.params.locale.currency_decimal_separator ) + .replace( + /\d(?=(\d{3})+(\D|$))/g, + '$&' + AW.params.locale.currency_thousand_separator + ); + const symbol = AW.params.locale.currency_symbol; + + switch ( AW.params.locale.currency_position ) { + case 'right': + price = price + symbol; + break; + case 'right_space': + price = price + ' ' + symbol; + break; + case 'left': + price = symbol + price; + break; + case 'left_space': + default: + price = symbol + ' ' + price; + break; + } + + return price; + }; + + AW.block = function ( $el ) { + $el.block( { + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6, + }, + } ); + }; + + /** + * Show / hide logic with data attributes + */ + AW.initShowHide = function () { + const update = function ( $el ) { + const id = $el.data( 'automatewoo-bind' ); + const value = $el.val(); + const isCheckbox = $el.is( 'input[type="checkbox"]' ); + + $( '[data-automatewoo-show]' ).each( function () { + if ( + isCheckbox && + $( this ).data( 'automatewoo-show' ) === id + ) { + if ( $el.is( ':checked' ) ) { + $( this ).show(); + } else { + $( this ).hide(); + } + } else { + const logic = $( this ) + .data( 'automatewoo-show' ) + .split( '=' ); + + if ( logic[ 0 ] !== id ) { + return; + } + + const possibleValues = logic[ 1 ].split( '|' ); + + if ( possibleValues.indexOf( value ) !== -1 ) { + $( this ).show(); + } else { + $( this ).hide(); + } + } + } ); + + $( '[data-automatewoo-hide]' ).each( function () { + if ( + isCheckbox && + $( this ).data( 'automatewoo-hide' ) === id + ) { + if ( $el.is( ':checked' ) ) { + $( this ).hide(); + } else { + $( this ).show(); + } + } else { + const logic = $( this ) + .data( 'automatewoo-hide' ) + .split( '=' ); + + if ( logic[ 0 ] !== id ) { + return; + } + + const possibleValues = logic[ 1 ].split( '|' ); + + if ( possibleValues.indexOf( value ) !== -1 ) { + $( this ).hide(); + } else { + $( this ).show(); + } + } + } ); + }; + + $( document ).on( 'change', '[data-automatewoo-bind]', function () { + update( $( this ) ); + } ); + + $( '[data-automatewoo-bind]' ).each( function () { + update( $( this ) ); + } ); + }; + + AW.initHoverableDates = function () { + const selector = '.automatewoo-hoverable-date'; + + $( document.body ) + .on( 'mouseenter', selector, function () { + $( this ).text( $( this ).data( 'automatewoo-date-no-diff' ) ); + } ) + .on( 'mouseleave', selector, function () { + $( this ).text( + $( this ).data( 'automatewoo-date-with-diff' ) + ); + } ); + }; + + $( function () { + AW.init(); + } ); +} )( jQuery ); + +jQuery( function ( $ ) { + Object.assign( AutomateWoo, { + _email_preview_window: null, + + init() { + this.init_notice_dismiss(); + this.init_date_pickers(); + }, + + notices: { + success( message, $location ) { + if ( ! $location.length ) { + return; + } + $location.before( + '

' + + message + + '

' + ); + }, + + error( message, $location ) { + if ( ! $location.length ) { + return; + } + $location.before( + '

' + + message + + '

' + ); + }, + + clear_all() { + $( '.automatewoo-notice' ).slideUp(); + }, + }, + + init_notice_dismiss() { + $( '.aw-notice-system-error' ).on( + 'click', + '.notice-dismiss', + function () { + $.ajax( { + url: ajaxurl, + data: { + action: 'aw_dismiss_system_error_notice', + nonce: AW.params.nonces + .aw_dismiss_system_error_notice, + }, + } ); + } + ); + + $( '[data-automatewoo-dismissible-notice]' ).on( + 'click', + '.notice-dismiss', + function () { + const $notice = $( this ).parents( + '[data-automatewoo-dismissible-notice]' + ); + + $.post( { + url: ajaxurl, + data: { + action: 'automatewoo_remove_notice', + notice: $notice.data( + 'automatewoo-dismissible-notice' + ), + nonce: AW.params.nonces.remove_notice, + }, + } ); + } + ); + }, + + init_date_pickers() { + $( '.automatewoo-date-picker' ).datepicker( { + dateFormat: 'yy-mm-dd', + numberOfMonths: 1, + showButtonPanel: true, + } ); + }, + + isEmailPreviewOpen() { + return ( + this._email_preview_window && + ! this._email_preview_window.closed + ); + }, + + openLoadingEmailPreview() { + this.openPreviewWindow( + AW.params.url.admin + + 'admin.php?page=automatewoo-preview&action=loading' + ); + }, + + /** + * @param {*} type + * @param {*} args + */ + open_email_preview( type, args ) { + const request = { + page: 'automatewoo-preview', + action: 'preview-ui', + type, + args, + }; + + this.openPreviewWindow( + AW.params.url.admin + 'admin.php?' + $.param( request ) + ); + }, + + /** + * @param {string | URL | undefined} url `window.open`'s url argument. + */ + openPreviewWindow( url ) { + this._email_preview_window = window.open( + url, + 'automatewoo_preview', + 'titlebar=no,toolbar=no,height=768,width=860,resizable=yes,status=no' + ); + }, + } ); + + AutomateWoo.init(); +} ); diff --git a/admin/assets/js/dashboard.js b/admin/assets/js/dashboard.js new file mode 100644 index 0000000..7c7c744 --- /dev/null +++ b/admin/assets/js/dashboard.js @@ -0,0 +1,210 @@ +// Register eslint ignored glabals - to be revisited. +// https://github.com/woocommerce/automatewoo/issues/1212 +/* global AW, automatewooDashboardLocalizeScript, _, HTMLElement */ + +( function ( $ ) { + const self = { + $el: $( '.automatewoo-dashboard-widgets' ), + + params: {}, + + init() { + self.params = automatewooDashboardLocalizeScript; + self.initMasonry(); + }, + + initMasonry() { + self.$el.masonry( { + itemSelector: '.automatewoo-dashboard-widget', + columnWidth: '.automatewoo-dashboard-widget-sizer', + percentPosition: true, + gutter: 20, + transitionDuration: '0.2s', + } ); + }, + /** + * Calls `drawGraph` with data translated from WC Analytics API reponse. + * + * @param {string|HTMLElement} container Chart container element or id, to be forwarded to drawGraph. + * @param {Array} intervals Intervals data object returned from Reports API. + * @param {Array} fields Fields/metrices to be extracted from the reponse. + * @param {Array} params Parameters to be forwarded, to be forwarded to drawGraph. + */ + drawGraphFromAnalyticsAPI( container, intervals, fields, params ) { + const translated = []; + for ( const field of fields ) { + translated.push( + intervals.map( ( row ) => [ + new Date( row.interval ).getTime(), + row.subtotals[ field ], + ] ) + ); + } + return self.drawGraph( container, translated, params ); + }, + + drawGraph( container, data, params ) { + const $chart = $( + typeof container === 'string' ? '#' + container : container + ); + const sets = []; + const setColors = [ '#3498db', '#d0a0e4', '#72c9b2' ]; + + _.each( data, function ( values, index ) { + const set = { + label: '', + data: values, + color: setColors.shift(), + points: { + show: true, + radius: 3, + lineWidth: 2, + fillColor: '#ffffff', + fill: true, + }, + lines: { + show: true, + lineWidth: 2, + fill: true, + fillColor: { + colors: [ { opacity: 0.02 }, { opacity: 0.16 } ], + }, + }, + shadowSize: 0, + isCurrency: + params.is_currency === true || + ( params.is_currency && params.is_currency[ index ] ), + }; + + if ( _.size( data ) > 1 ) { + set.lines.fill = false; + } + + sets.push( set ); + } ); + + const options = { + legend: { + show: false, + }, + grid: { + color: '#aaa', + borderColor: 'transparent', + borderWidth: 0, + hoverable: true, + }, + xaxis: { + color: '#e5e5e5', + position: 'bottom', + tickColor: 'transparent', + mode: 'time', + monthNames: AW.params.locale.month_abbrev, + tickLength: 1, + font: { + color: '#aaa', + }, + }, + yaxis: { + color: '#fff', + font: { + color: '#fff', + }, + }, + }; + + if ( Number( params.interval ) === 30 ) { + options.xaxis.minTickSize = [ 4, 'day' ]; + } + + $.plot( $chart, sets, options ); + + $chart.on( 'plothover', function ( event, pos, item ) { + const $wrap = $chart.parents( + '.automatewoo-dashboard-chart:first' + ); + const $tooltip = $chart.siblings( + '.automatewoo-dashboard-chart__tooltip:first' + ); + const wrapOffset = $wrap.offset(); + + if ( item && item.series.points.show ) { + let content = item.datapoint[ 1 ]; + + if ( item.series.isCurrency ) { + content = AW.price( content ); + } + + $tooltip + .html( content ) + .css( { + top: item.pageY - 9 - wrapOffset.top, + left: item.pageX + 12 - wrapOffset.left, + } ) + .fadeIn( 200 ); + } else { + $tooltip.hide(); + } + } ); + }, + }; + + AW.Dashboard = self; + self.init(); + + // This is overly simplified implementation. Follows the behavior of the previous jQuery widget. + // The element + // - Don't observe nor react to attribute changes. + // - Assumes upgrade scenario - attributes are already set once the element is connected; + // entire light DOM content is well structured and already present. + // - Do not stop, abort, or bother about `fetch` races if the element is reconnected. + window.customElements.define( + 'automatewoo-dashboard-chart', + class AWDashboardChart extends HTMLElement { + connectedCallback() { + this.setAttribute( 'aw-loading', '' ); + + const fields = this.getAttribute( 'fields' ).split( ',' ); + const isCurrency = JSON.parse( + `[${ this.getAttribute( 'is-currency' ) || '' }]` + ); + + const requestParams = new URLSearchParams( { + interval: 'day', + after: this.getAttribute( 'after' ), + before: this.getAttribute( 'before' ), + fields, + per_page: 100, + } ); + wp.apiFetch( { + path: + this.getAttribute( 'endpoint' ) + + '?' + + requestParams.toString(), + } ).then( ( response ) => { + this.removeAttribute( 'aw-loading' ); + // Draw chart. + AW.Dashboard.drawGraphFromAnalyticsAPI( + this.querySelector( + 'automatewoo-dashboard-chart__flot' + ), + response.intervals, + fields, + { + interval: this.getAttribute( 'interval' ), + is_currency: isCurrency, + } + ); + // Fill totals. + for ( let index = 0; index < fields.length; index++ ) { + const key = fields[ index ]; + this.querySelector( + `automatewoo-dashboard-chart__header-figure[name=${ key }]` + ).innerHTML = isCurrency[ index ] + ? AW.price( response.totals[ key ] ) + : response.totals[ key ]; + } + } ); + } + } + ); +} )( jQuery ); diff --git a/admin/assets/js/min/automatewoo.min.js b/admin/assets/js/min/automatewoo.min.js new file mode 100644 index 0000000..e5e703e --- /dev/null +++ b/admin/assets/js/min/automatewoo.min.js @@ -0,0 +1,2 @@ +const AutomateWoo={},AW={};window.AutomateWoo=AutomateWoo,function(t){AW.init=function(){AW.params=automatewooLocalizeScript,AW.initTooltips(),AW.initWorkflowStatusSwitch(),AW.initShowHide(),AW.initHoverableDates(),AW.initBeforeAfterDayField(),t(document.body).on("wc-enhanced-select-init",(function(){AW.initEnhancedSelects()})),t(document.body).on("automatewoo_trigger_changed",AW.initBeforeAfterDayField)},AW.initTooltips=function(){t(".automatewoo-help-tip, .automatewoo-tiptip").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})},AW.initEnhancedSelects=function(){t("select.automatewoo-json-search").filter(":not(.enhanced)").each((function(){const e={allowClear:!!t(this).data("allow_clear"),placeholder:t(this).data("placeholder"),minimumInputLength:"1",escapeMarkup(t){return t},ajax:{url:AW.params.url.ajax,dataType:"json",quietMillis:250,data(e){const o={term:e.term,action:t(this).data("action")},a=t(this).data("pass-sibling");if(a){const e=t('[name="'+a+'"]');e.length&&(o.sibling=e.val())}return o},processResults(e){const o=[];return e&&t.each(e,(function(t,e){o.push({id:t,text:e})})),{results:o}},cache:!0}};t(this).select2(e).addClass("enhanced")}))},AW.initBeforeAfterDayField=function(){t(".automatewoo-before-after-day-field-group__field--type").on("change",(function(){const e=t(this),o=e.siblings(".automatewoo-before-after-day-field-group__field--days");"on_the_day"===e.val()?o.hide():o.show()})).trigger("change")},AW.initWorkflowStatusSwitch=function(){t(".aw-switch.js-toggle-workflow-status").on("click",(function(){const e=t(this);if(e.is(".aw-loading"))return;const o="on"===e.attr("data-aw-switch")?"off":"on";e.addClass("aw-loading"),e.attr("data-aw-switch",o),t.post(ajaxurl,{action:"aw_toggle_workflow_status",workflow_id:e.attr("data-workflow-id"),new_state:o,nonce:AW.params.nonces.aw_toggle_workflow_status},(function(){e.removeClass("aw-loading")}))}))},AW.price=function(t){let e=t.toFixed(2).replace(".",AW.params.locale.currency_decimal_separator).replace(/\d(?=(\d{3})+(\D|$))/g,"$&"+AW.params.locale.currency_thousand_separator);const o=AW.params.locale.currency_symbol;switch(AW.params.locale.currency_position){case"right":e+=o;break;case"right_space":e=e+" "+o;break;case"left":e=o+e;break;default:e=o+" "+e}return e},AW.block=function(t){t.block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},AW.initShowHide=function(){const e=function(e){const o=e.data("automatewoo-bind"),a=e.val(),i=e.is('input[type="checkbox"]');t("[data-automatewoo-show]").each((function(){if(i&&t(this).data("automatewoo-show")===o)e.is(":checked")?t(this).show():t(this).hide();else{const e=t(this).data("automatewoo-show").split("=");if(e[0]!==o)return;-1!==e[1].split("|").indexOf(a)?t(this).show():t(this).hide()}})),t("[data-automatewoo-hide]").each((function(){if(i&&t(this).data("automatewoo-hide")===o)e.is(":checked")?t(this).hide():t(this).show();else{const e=t(this).data("automatewoo-hide").split("=");if(e[0]!==o)return;-1!==e[1].split("|").indexOf(a)?t(this).hide():t(this).show()}}))};t(document).on("change","[data-automatewoo-bind]",(function(){e(t(this))})),t("[data-automatewoo-bind]").each((function(){e(t(this))}))},AW.initHoverableDates=function(){const e=".automatewoo-hoverable-date";t(document.body).on("mouseenter",e,(function(){t(this).text(t(this).data("automatewoo-date-no-diff"))})).on("mouseleave",e,(function(){t(this).text(t(this).data("automatewoo-date-with-diff"))}))},t((function(){AW.init()}))}(jQuery),jQuery((function(t){Object.assign(AutomateWoo,{_email_preview_window:null,init(){this.init_notice_dismiss(),this.init_date_pickers()},notices:{success(t,e){e.length&&e.before('

'+t+"

")},error(t,e){e.length&&e.before('

'+t+"

")},clear_all(){t(".automatewoo-notice").slideUp()}},init_notice_dismiss(){t(".aw-notice-system-error").on("click",".notice-dismiss",(function(){t.ajax({url:ajaxurl,data:{action:"aw_dismiss_system_error_notice",nonce:AW.params.nonces.aw_dismiss_system_error_notice}})})),t("[data-automatewoo-dismissible-notice]").on("click",".notice-dismiss",(function(){const e=t(this).parents("[data-automatewoo-dismissible-notice]");t.post({url:ajaxurl,data:{action:"automatewoo_remove_notice",notice:e.data("automatewoo-dismissible-notice"),nonce:AW.params.nonces.remove_notice}})}))},init_date_pickers(){t(".automatewoo-date-picker").datepicker({dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0})},isEmailPreviewOpen(){return this._email_preview_window&&!this._email_preview_window.closed},openLoadingEmailPreview(){this.openPreviewWindow(AW.params.url.admin+"admin.php?page=automatewoo-preview&action=loading")},open_email_preview(e,o){const a={page:"automatewoo-preview",action:"preview-ui",type:e,args:o};this.openPreviewWindow(AW.params.url.admin+"admin.php?"+t.param(a))},openPreviewWindow(t){this._email_preview_window=window.open(t,"automatewoo_preview","titlebar=no,toolbar=no,height=768,width=860,resizable=yes,status=no")}}),AutomateWoo.init()})); +//# sourceMappingURL=automatewoo.min.js.map \ No newline at end of file diff --git a/admin/assets/js/min/automatewoo.min.js.map b/admin/assets/js/min/automatewoo.min.js.map new file mode 100644 index 0000000..7123338 --- /dev/null +++ b/admin/assets/js/min/automatewoo.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"automatewoo.min.js","mappings":"AAOA,MAAMA,YAAc,CAAC,EACpBC,GAAK,CAAC,EAEPC,OAAOF,YAAcA,YAErB,SAAaG,GACZF,GAAGG,KAAO,WACTH,GAAGI,OAASC,0BAEZL,GAAGM,eACHN,GAAGO,2BACHP,GAAGQ,eACHR,GAAGS,qBACHT,GAAGU,0BAEHR,EAAGS,SAASC,MAAOC,GAAI,2BAA2B,WACjDb,GAAGc,qBACJ,IAEAZ,EAAGS,SAASC,MAAOC,GAClB,8BACAb,GAAGU,wBAEL,EAKAV,GAAGM,aAAe,WACjBJ,EAAG,8CAA+Ca,OAAQ,CACzDC,UAAW,WACXC,OAAQ,GACRC,QAAS,GACTC,MAAO,KAET,EAKAnB,GAAGc,oBAAsB,WACxBZ,EAAG,kCACDkB,OAAQ,mBACRC,MAAM,WACN,MAAMC,EAAc,CACnBC,aAAYrB,EAAGsB,MAAOC,KAAM,eAC5BC,YAAaxB,EAAGsB,MAAOC,KAAM,eAC7BE,mBAAoB,IACpB,YAAAC,CAAcC,GACb,OAAOA,CACR,EACAC,KAAM,CACLC,IAAK/B,GAAGI,OAAO2B,IAAID,KACnBE,SAAU,OACVC,YAAa,IACb,IAAAR,CAAMrB,GACL,MAAMqB,EAAO,CACZS,KAAM9B,EAAO8B,KACbC,OAAQjC,EAAGsB,MAAOC,KAAM,WAInBW,EAAUlC,EAAGsB,MAAOC,KAAM,gBAChC,GAAKW,EAAU,CACd,MAAMC,EAAWnC,EAChB,UAAYkC,EAAU,MAGlBC,EAASC,SACbb,EAAKW,QAAUC,EAASE,MAE1B,CAEA,OAAOd,CACR,EACA,cAAAe,CAAgBf,GACf,MAAMgB,EAAQ,GAMd,OALKhB,GACJvB,EAAEmB,KAAMI,GAAM,SAAWiB,EAAIC,GAC5BF,EAAMG,KAAM,CAAEF,KAAIC,QACnB,IAEM,CACNE,QAASJ,EAEX,EACAK,OAAO,IAIT5C,EAAGsB,MAAOuB,QAASzB,GAAc0B,SAAU,WAC5C,GACF,EAEAhD,GAAGU,wBAA0B,WAC5BR,EAAG,0DACDW,GAAI,UAAU,WACd,MAAMoC,EAAQ/C,EAAGsB,MACX0B,EAAQD,EAAME,SACnB,0DAGoB,eAAhBF,EAAMV,MACVW,EAAME,OAENF,EAAMG,MAER,IACCC,QAAS,SACZ,EAEAtD,GAAGO,yBAA2B,WAC7BL,EAAG,wCAAyCW,GAAI,SAAS,WACxD,MAAM0C,EAAUrD,EAAGsB,MAEnB,GAAK+B,EAAQC,GAAI,eAChB,OAGD,MACMC,EAAqB,OADbF,EAAQG,KAAM,kBACM,MAAQ,KAE1CH,EAAQP,SAAU,cAClBO,EAAQG,KAAM,iBAAkBD,GAEhCvD,EAAEyD,KACDC,QACA,CACCzB,OAAQ,4BACR0B,YAAaN,EAAQG,KAAM,oBAC3BI,UAAWL,EACXM,MAAO/D,GAAGI,OAAO4D,OAAOC,4BAEzB,WACCV,EAAQW,YAAa,aACtB,GAEF,GACD,EAMAlE,GAAGmE,MAAQ,SAAWC,GACrB,IAAID,EAAQC,EACVC,QAAS,GACTC,QAAS,IAAKtE,GAAGI,OAAOmE,OAAOC,4BAC/BF,QACA,wBACA,KAAOtE,GAAGI,OAAOmE,OAAOE,6BAE1B,MAAMC,EAAS1E,GAAGI,OAAOmE,OAAOI,gBAEhC,OAAS3E,GAAGI,OAAOmE,OAAOK,mBACzB,IAAK,QACJT,GAAgBO,EAChB,MACD,IAAK,cACJP,EAAQA,EAAQ,IAAMO,EACtB,MACD,IAAK,OACJP,EAAQO,EAASP,EACjB,MAED,QACCA,EAAQO,EAAS,IAAMP,EAIzB,OAAOA,CACR,EAEAnE,GAAG6E,MAAQ,SAAWC,GACrBA,EAAID,MAAO,CACVE,QAAS,KACTC,WAAY,CACXC,WAAY,OACZC,QAAS,KAGZ,EAKAlF,GAAGQ,aAAe,WACjB,MAAM2E,EAAS,SAAWL,GACzB,MAAMpC,EAAKoC,EAAIrD,KAAM,oBACf2D,EAAQN,EAAIvC,MACZ8C,EAAaP,EAAItB,GAAI,0BAE3BtD,EAAG,2BAA4BmB,MAAM,WACpC,GACCgE,GACAnF,EAAGsB,MAAOC,KAAM,sBAAyBiB,EAEpCoC,EAAItB,GAAI,YACZtD,EAAGsB,MAAO6B,OAEVnD,EAAGsB,MAAO4B,WAEL,CACN,MAAMkC,EAAQpF,EAAGsB,MACfC,KAAM,oBACN8D,MAAO,KAET,GAAKD,EAAO,KAAQ5C,EACnB,QAKyC,IAFnB4C,EAAO,GAAIC,MAAO,KAErBC,QAASJ,GAC5BlF,EAAGsB,MAAO6B,OAEVnD,EAAGsB,MAAO4B,MAEZ,CACD,IAEAlD,EAAG,2BAA4BmB,MAAM,WACpC,GACCgE,GACAnF,EAAGsB,MAAOC,KAAM,sBAAyBiB,EAEpCoC,EAAItB,GAAI,YACZtD,EAAGsB,MAAO4B,OAEVlD,EAAGsB,MAAO6B,WAEL,CACN,MAAMiC,EAAQpF,EAAGsB,MACfC,KAAM,oBACN8D,MAAO,KAET,GAAKD,EAAO,KAAQ5C,EACnB,QAKyC,IAFnB4C,EAAO,GAAIC,MAAO,KAErBC,QAASJ,GAC5BlF,EAAGsB,MAAO4B,OAEVlD,EAAGsB,MAAO6B,MAEZ,CACD,GACD,EAEAnD,EAAGS,UAAWE,GAAI,SAAU,2BAA2B,WACtDsE,EAAQjF,EAAGsB,MACZ,IAEAtB,EAAG,2BAA4BmB,MAAM,WACpC8D,EAAQjF,EAAGsB,MACZ,GACD,EAEAxB,GAAGS,mBAAqB,WACvB,MAAMgF,EAAW,8BAEjBvF,EAAGS,SAASC,MACVC,GAAI,aAAc4E,GAAU,WAC5BvF,EAAGsB,MAAOmB,KAAMzC,EAAGsB,MAAOC,KAAM,4BACjC,IACCZ,GAAI,aAAc4E,GAAU,WAC5BvF,EAAGsB,MAAOmB,KACTzC,EAAGsB,MAAOC,KAAM,8BAElB,GACF,EAEAvB,GAAG,WACFF,GAAGG,MACJ,GACC,CAhRF,CAgRKuF,QAELA,QAAQ,SAAWxF,GAClByF,OAAOC,OAAQ7F,YAAa,CAC3B8F,sBAAuB,KAEvB,IAAA1F,GACCqB,KAAKsE,sBACLtE,KAAKuE,mBACN,EAEAC,QAAS,CACR,OAAAC,CAASlB,EAASmB,GACVA,EAAU5D,QAGjB4D,EAAUC,OACT,2DACCpB,EACA,sBAEH,EAEA,KAAAqB,CAAOrB,EAASmB,GACRA,EAAU5D,QAGjB4D,EAAUC,OACT,yDACCpB,EACA,sBAEH,EAEA,SAAAsB,GACCnG,EAAG,uBAAwBoG,SAC5B,GAGD,mBAAAR,GACC5F,EAAG,2BAA4BW,GAC9B,QACA,mBACA,WACCX,EAAE4B,KAAM,CACPC,IAAK6B,QACLnC,KAAM,CACLU,OAAQ,iCACR4B,MAAO/D,GAAGI,OAAO4D,OACfuC,iCAGL,IAGDrG,EAAG,yCAA0CW,GAC5C,QACA,mBACA,WACC,MAAM2F,EAAUtG,EAAGsB,MAAOiF,QACzB,yCAGDvG,EAAEyD,KAAM,CACP5B,IAAK6B,QACLnC,KAAM,CACLU,OAAQ,4BACRuE,OAAQF,EAAQ/E,KACf,kCAEDsC,MAAO/D,GAAGI,OAAO4D,OAAO2C,gBAG3B,GAEF,EAEA,iBAAAZ,GACC7F,EAAG,4BAA6B0G,WAAY,CAC3CC,WAAY,WACZC,eAAgB,EAChBC,iBAAiB,GAEnB,EAEA,kBAAAC,GACC,OACCxF,KAAKqE,wBACHrE,KAAKqE,sBAAsBoB,MAE/B,EAEA,uBAAAC,GACC1F,KAAK2F,kBACJnH,GAAGI,OAAO2B,IAAIqF,MACb,oDAEH,EAMA,kBAAAC,CAAoBC,EAAMC,GACzB,MAAMC,EAAU,CACfC,KAAM,sBACNtF,OAAQ,aACRmF,OACAC,QAGD/F,KAAK2F,kBACJnH,GAAGI,OAAO2B,IAAIqF,MAAQ,aAAelH,EAAEwH,MAAOF,GAEhD,EAKA,iBAAAL,CAAmBpF,GAClBP,KAAKqE,sBAAwB5F,OAAO0H,KACnC5F,EACA,sBACA,sEAEF,IAGDhC,YAAYI,MACb","sources":["webpack://automatewoo/./admin/assets/js/automatewoo.js"],"sourcesContent":["/**\n * AutomateWoo main - loaded on every admin page\n */\n// Register eslint ignored glabals - to be revisited.\n// https://github.com/woocommerce/automatewoo/issues/1212\n/* global automatewooLocalizeScript, ajaxurl */\n\nconst AutomateWoo = {},\n\tAW = {};\n\nwindow.AutomateWoo = AutomateWoo;\n\n( function ( $ ) {\n\tAW.init = function () {\n\t\tAW.params = automatewooLocalizeScript;\n\n\t\tAW.initTooltips();\n\t\tAW.initWorkflowStatusSwitch();\n\t\tAW.initShowHide();\n\t\tAW.initHoverableDates();\n\t\tAW.initBeforeAfterDayField();\n\n\t\t$( document.body ).on( 'wc-enhanced-select-init', function () {\n\t\t\tAW.initEnhancedSelects();\n\t\t} );\n\n\t\t$( document.body ).on(\n\t\t\t'automatewoo_trigger_changed',\n\t\t\tAW.initBeforeAfterDayField\n\t\t);\n\t};\n\n\t/**\n\t * Init tool tips\n\t */\n\tAW.initTooltips = function () {\n\t\t$( '.automatewoo-help-tip, .automatewoo-tiptip' ).tipTip( {\n\t\t\tattribute: 'data-tip',\n\t\t\tfadeIn: 50,\n\t\t\tfadeOut: 50,\n\t\t\tdelay: 200,\n\t\t} );\n\t};\n\n\t/**\n\t * Ajax search search box\n\t */\n\tAW.initEnhancedSelects = function () {\n\t\t$( 'select.automatewoo-json-search' )\n\t\t\t.filter( ':not(.enhanced)' )\n\t\t\t.each( function () {\n\t\t\t\tconst select2Args = {\n\t\t\t\t\tallowClear: $( this ).data( 'allow_clear' ) ? true : false,\n\t\t\t\t\tplaceholder: $( this ).data( 'placeholder' ),\n\t\t\t\t\tminimumInputLength: '1',\n\t\t\t\t\tescapeMarkup( m ) {\n\t\t\t\t\t\treturn m;\n\t\t\t\t\t},\n\t\t\t\t\tajax: {\n\t\t\t\t\t\turl: AW.params.url.ajax,\n\t\t\t\t\t\tdataType: 'json',\n\t\t\t\t\t\tquietMillis: 250,\n\t\t\t\t\t\tdata( params ) {\n\t\t\t\t\t\t\tconst data = {\n\t\t\t\t\t\t\t\tterm: params.term,\n\t\t\t\t\t\t\t\taction: $( this ).data( 'action' ),\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// pass in sibling field data\n\t\t\t\t\t\t\tconst sibling = $( this ).data( 'pass-sibling' );\n\t\t\t\t\t\t\tif ( sibling ) {\n\t\t\t\t\t\t\t\tconst $sibling = $(\n\t\t\t\t\t\t\t\t\t'[name=\"' + sibling + '\"]'\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tif ( $sibling.length ) {\n\t\t\t\t\t\t\t\t\tdata.sibling = $sibling.val();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn data;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tprocessResults( data ) {\n\t\t\t\t\t\t\tconst terms = [];\n\t\t\t\t\t\t\tif ( data ) {\n\t\t\t\t\t\t\t\t$.each( data, function ( id, text ) {\n\t\t\t\t\t\t\t\t\tterms.push( { id, text } );\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tresults: terms,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcache: true,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\t$( this ).select2( select2Args ).addClass( 'enhanced' );\n\t\t\t} );\n\t};\n\n\tAW.initBeforeAfterDayField = function () {\n\t\t$( '.automatewoo-before-after-day-field-group__field--type' )\n\t\t\t.on( 'change', function () {\n\t\t\t\tconst $type = $( this );\n\t\t\t\tconst $days = $type.siblings(\n\t\t\t\t\t'.automatewoo-before-after-day-field-group__field--days'\n\t\t\t\t);\n\n\t\t\t\tif ( $type.val() === 'on_the_day' ) {\n\t\t\t\t\t$days.hide();\n\t\t\t\t} else {\n\t\t\t\t\t$days.show();\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.trigger( 'change' );\n\t};\n\n\tAW.initWorkflowStatusSwitch = function () {\n\t\t$( '.aw-switch.js-toggle-workflow-status' ).on( 'click', function () {\n\t\t\tconst $switch = $( this );\n\n\t\t\tif ( $switch.is( '.aw-loading' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst state = $switch.attr( 'data-aw-switch' );\n\t\t\tconst newState = state === 'on' ? 'off' : 'on';\n\n\t\t\t$switch.addClass( 'aw-loading' );\n\t\t\t$switch.attr( 'data-aw-switch', newState );\n\n\t\t\t$.post(\n\t\t\t\tajaxurl,\n\t\t\t\t{\n\t\t\t\t\taction: 'aw_toggle_workflow_status',\n\t\t\t\t\tworkflow_id: $switch.attr( 'data-workflow-id' ),\n\t\t\t\t\tnew_state: newState,\n\t\t\t\t\tnonce: AW.params.nonces.aw_toggle_workflow_status,\n\t\t\t\t},\n\t\t\t\tfunction () {\n\t\t\t\t\t$switch.removeClass( 'aw-loading' );\n\t\t\t\t}\n\t\t\t);\n\t\t} );\n\t};\n\n\t/**\n\t * @param {number} float\n\t * @return {string} Formatted price with the currency symbol.\n\t */\n\tAW.price = function ( float ) {\n\t\tlet price = float\n\t\t\t.toFixed( 2 )\n\t\t\t.replace( '.', AW.params.locale.currency_decimal_separator )\n\t\t\t.replace(\n\t\t\t\t/\\d(?=(\\d{3})+(\\D|$))/g,\n\t\t\t\t'$&' + AW.params.locale.currency_thousand_separator\n\t\t\t);\n\t\tconst symbol = AW.params.locale.currency_symbol;\n\n\t\tswitch ( AW.params.locale.currency_position ) {\n\t\t\tcase 'right':\n\t\t\t\tprice = price + symbol;\n\t\t\t\tbreak;\n\t\t\tcase 'right_space':\n\t\t\t\tprice = price + ' ' + symbol;\n\t\t\t\tbreak;\n\t\t\tcase 'left':\n\t\t\t\tprice = symbol + price;\n\t\t\t\tbreak;\n\t\t\tcase 'left_space':\n\t\t\tdefault:\n\t\t\t\tprice = symbol + ' ' + price;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn price;\n\t};\n\n\tAW.block = function ( $el ) {\n\t\t$el.block( {\n\t\t\tmessage: null,\n\t\t\toverlayCSS: {\n\t\t\t\tbackground: '#fff',\n\t\t\t\topacity: 0.6,\n\t\t\t},\n\t\t} );\n\t};\n\n\t/**\n\t * Show / hide logic with data attributes\n\t */\n\tAW.initShowHide = function () {\n\t\tconst update = function ( $el ) {\n\t\t\tconst id = $el.data( 'automatewoo-bind' );\n\t\t\tconst value = $el.val();\n\t\t\tconst isCheckbox = $el.is( 'input[type=\"checkbox\"]' );\n\n\t\t\t$( '[data-automatewoo-show]' ).each( function () {\n\t\t\t\tif (\n\t\t\t\t\tisCheckbox &&\n\t\t\t\t\t$( this ).data( 'automatewoo-show' ) === id\n\t\t\t\t) {\n\t\t\t\t\tif ( $el.is( ':checked' ) ) {\n\t\t\t\t\t\t$( this ).show();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( this ).hide();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst logic = $( this )\n\t\t\t\t\t\t.data( 'automatewoo-show' )\n\t\t\t\t\t\t.split( '=' );\n\n\t\t\t\t\tif ( logic[ 0 ] !== id ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst possibleValues = logic[ 1 ].split( '|' );\n\n\t\t\t\t\tif ( possibleValues.indexOf( value ) !== -1 ) {\n\t\t\t\t\t\t$( this ).show();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( this ).hide();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( '[data-automatewoo-hide]' ).each( function () {\n\t\t\t\tif (\n\t\t\t\t\tisCheckbox &&\n\t\t\t\t\t$( this ).data( 'automatewoo-hide' ) === id\n\t\t\t\t) {\n\t\t\t\t\tif ( $el.is( ':checked' ) ) {\n\t\t\t\t\t\t$( this ).hide();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( this ).show();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst logic = $( this )\n\t\t\t\t\t\t.data( 'automatewoo-hide' )\n\t\t\t\t\t\t.split( '=' );\n\n\t\t\t\t\tif ( logic[ 0 ] !== id ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst possibleValues = logic[ 1 ].split( '|' );\n\n\t\t\t\t\tif ( possibleValues.indexOf( value ) !== -1 ) {\n\t\t\t\t\t\t$( this ).hide();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$( this ).show();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\n\t\t$( document ).on( 'change', '[data-automatewoo-bind]', function () {\n\t\t\tupdate( $( this ) );\n\t\t} );\n\n\t\t$( '[data-automatewoo-bind]' ).each( function () {\n\t\t\tupdate( $( this ) );\n\t\t} );\n\t};\n\n\tAW.initHoverableDates = function () {\n\t\tconst selector = '.automatewoo-hoverable-date';\n\n\t\t$( document.body )\n\t\t\t.on( 'mouseenter', selector, function () {\n\t\t\t\t$( this ).text( $( this ).data( 'automatewoo-date-no-diff' ) );\n\t\t\t} )\n\t\t\t.on( 'mouseleave', selector, function () {\n\t\t\t\t$( this ).text(\n\t\t\t\t\t$( this ).data( 'automatewoo-date-with-diff' )\n\t\t\t\t);\n\t\t\t} );\n\t};\n\n\t$( function () {\n\t\tAW.init();\n\t} );\n} )( jQuery );\n\njQuery( function ( $ ) {\n\tObject.assign( AutomateWoo, {\n\t\t_email_preview_window: null,\n\n\t\tinit() {\n\t\t\tthis.init_notice_dismiss();\n\t\t\tthis.init_date_pickers();\n\t\t},\n\n\t\tnotices: {\n\t\t\tsuccess( message, $location ) {\n\t\t\t\tif ( ! $location.length ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$location.before(\n\t\t\t\t\t'

' +\n\t\t\t\t\t\tmessage +\n\t\t\t\t\t\t'

'\n\t\t\t\t);\n\t\t\t},\n\n\t\t\terror( message, $location ) {\n\t\t\t\tif ( ! $location.length ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$location.before(\n\t\t\t\t\t'

' +\n\t\t\t\t\t\tmessage +\n\t\t\t\t\t\t'

'\n\t\t\t\t);\n\t\t\t},\n\n\t\t\tclear_all() {\n\t\t\t\t$( '.automatewoo-notice' ).slideUp();\n\t\t\t},\n\t\t},\n\n\t\tinit_notice_dismiss() {\n\t\t\t$( '.aw-notice-system-error' ).on(\n\t\t\t\t'click',\n\t\t\t\t'.notice-dismiss',\n\t\t\t\tfunction () {\n\t\t\t\t\t$.ajax( {\n\t\t\t\t\t\turl: ajaxurl,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\taction: 'aw_dismiss_system_error_notice',\n\t\t\t\t\t\t\tnonce: AW.params.nonces\n\t\t\t\t\t\t\t\t.aw_dismiss_system_error_notice,\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t);\n\n\t\t\t$( '[data-automatewoo-dismissible-notice]' ).on(\n\t\t\t\t'click',\n\t\t\t\t'.notice-dismiss',\n\t\t\t\tfunction () {\n\t\t\t\t\tconst $notice = $( this ).parents(\n\t\t\t\t\t\t'[data-automatewoo-dismissible-notice]'\n\t\t\t\t\t);\n\n\t\t\t\t\t$.post( {\n\t\t\t\t\t\turl: ajaxurl,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\taction: 'automatewoo_remove_notice',\n\t\t\t\t\t\t\tnotice: $notice.data(\n\t\t\t\t\t\t\t\t'automatewoo-dismissible-notice'\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tnonce: AW.params.nonces.remove_notice,\n\t\t\t\t\t\t},\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t);\n\t\t},\n\n\t\tinit_date_pickers() {\n\t\t\t$( '.automatewoo-date-picker' ).datepicker( {\n\t\t\t\tdateFormat: 'yy-mm-dd',\n\t\t\t\tnumberOfMonths: 1,\n\t\t\t\tshowButtonPanel: true,\n\t\t\t} );\n\t\t},\n\n\t\tisEmailPreviewOpen() {\n\t\t\treturn (\n\t\t\t\tthis._email_preview_window &&\n\t\t\t\t! this._email_preview_window.closed\n\t\t\t);\n\t\t},\n\n\t\topenLoadingEmailPreview() {\n\t\t\tthis.openPreviewWindow(\n\t\t\t\tAW.params.url.admin +\n\t\t\t\t\t'admin.php?page=automatewoo-preview&action=loading'\n\t\t\t);\n\t\t},\n\n\t\t/**\n\t\t * @param {*} type\n\t\t * @param {*} args\n\t\t */\n\t\topen_email_preview( type, args ) {\n\t\t\tconst request = {\n\t\t\t\tpage: 'automatewoo-preview',\n\t\t\t\taction: 'preview-ui',\n\t\t\t\ttype,\n\t\t\t\targs,\n\t\t\t};\n\n\t\t\tthis.openPreviewWindow(\n\t\t\t\tAW.params.url.admin + 'admin.php?' + $.param( request )\n\t\t\t);\n\t\t},\n\n\t\t/**\n\t\t * @param {string | URL | undefined} url `window.open`'s url argument.\n\t\t */\n\t\topenPreviewWindow( url ) {\n\t\t\tthis._email_preview_window = window.open(\n\t\t\t\turl,\n\t\t\t\t'automatewoo_preview',\n\t\t\t\t'titlebar=no,toolbar=no,height=768,width=860,resizable=yes,status=no'\n\t\t\t);\n\t\t},\n\t} );\n\n\tAutomateWoo.init();\n} );\n"],"names":["AutomateWoo","AW","window","$","init","params","automatewooLocalizeScript","initTooltips","initWorkflowStatusSwitch","initShowHide","initHoverableDates","initBeforeAfterDayField","document","body","on","initEnhancedSelects","tipTip","attribute","fadeIn","fadeOut","delay","filter","each","select2Args","allowClear","this","data","placeholder","minimumInputLength","escapeMarkup","m","ajax","url","dataType","quietMillis","term","action","sibling","$sibling","length","val","processResults","terms","id","text","push","results","cache","select2","addClass","$type","$days","siblings","hide","show","trigger","$switch","is","newState","attr","post","ajaxurl","workflow_id","new_state","nonce","nonces","aw_toggle_workflow_status","removeClass","price","float","toFixed","replace","locale","currency_decimal_separator","currency_thousand_separator","symbol","currency_symbol","currency_position","block","$el","message","overlayCSS","background","opacity","update","value","isCheckbox","logic","split","indexOf","selector","jQuery","Object","assign","_email_preview_window","init_notice_dismiss","init_date_pickers","notices","success","$location","before","error","clear_all","slideUp","aw_dismiss_system_error_notice","$notice","parents","notice","remove_notice","datepicker","dateFormat","numberOfMonths","showButtonPanel","isEmailPreviewOpen","closed","openLoadingEmailPreview","openPreviewWindow","admin","open_email_preview","type","args","request","page","param","open"],"sourceRoot":""} \ No newline at end of file diff --git a/admin/assets/js/min/dashboard.min.js b/admin/assets/js/min/dashboard.min.js new file mode 100644 index 0000000..9a2ad3b --- /dev/null +++ b/admin/assets/js/min/dashboard.min.js @@ -0,0 +1,2 @@ +!function(t){const e={$el:t(".automatewoo-dashboard-widgets"),params:{},init(){e.params=automatewooDashboardLocalizeScript,e.initMasonry()},initMasonry(){e.$el.masonry({itemSelector:".automatewoo-dashboard-widget",columnWidth:".automatewoo-dashboard-widget-sizer",percentPosition:!0,gutter:20,transitionDuration:"0.2s"})},drawGraphFromAnalyticsAPI(t,o,a,r){const i=[];for(const t of a)i.push(o.map((e=>[new Date(e.interval).getTime(),e.subtotals[t]])));return e.drawGraph(t,i,r)},drawGraph(e,o,a){const r=t("string"==typeof e?"#"+e:e),i=[],s=["#3498db","#d0a0e4","#72c9b2"];_.each(o,(function(t,e){const r={label:"",data:t,color:s.shift(),points:{show:!0,radius:3,lineWidth:2,fillColor:"#ffffff",fill:!0},lines:{show:!0,lineWidth:2,fill:!0,fillColor:{colors:[{opacity:.02},{opacity:.16}]}},shadowSize:0,isCurrency:!0===a.is_currency||a.is_currency&&a.is_currency[e]};_.size(o)>1&&(r.lines.fill=!1),i.push(r)}));const n={legend:{show:!1},grid:{color:"#aaa",borderColor:"transparent",borderWidth:0,hoverable:!0},xaxis:{color:"#e5e5e5",position:"bottom",tickColor:"transparent",mode:"time",monthNames:AW.params.locale.month_abbrev,tickLength:1,font:{color:"#aaa"}},yaxis:{color:"#fff",font:{color:"#fff"}}};30===Number(a.interval)&&(n.xaxis.minTickSize=[4,"day"]),t.plot(r,i,n),r.on("plothover",(function(t,e,o){const a=r.parents(".automatewoo-dashboard-chart:first"),i=r.siblings(".automatewoo-dashboard-chart__tooltip:first"),s=a.offset();if(o&&o.series.points.show){let t=o.datapoint[1];o.series.isCurrency&&(t=AW.price(t)),i.html(t).css({top:o.pageY-9-s.top,left:o.pageX+12-s.left}).fadeIn(200)}else i.hide()}))}};AW.Dashboard=e,e.init(),window.customElements.define("automatewoo-dashboard-chart",class extends HTMLElement{connectedCallback(){this.setAttribute("aw-loading","");const t=this.getAttribute("fields").split(","),e=JSON.parse(`[${this.getAttribute("is-currency")||""}]`),o=new URLSearchParams({interval:"day",after:this.getAttribute("after"),before:this.getAttribute("before"),fields:t,per_page:100});wp.apiFetch({path:this.getAttribute("endpoint")+"?"+o.toString()}).then((o=>{this.removeAttribute("aw-loading"),AW.Dashboard.drawGraphFromAnalyticsAPI(this.querySelector("automatewoo-dashboard-chart__flot"),o.intervals,t,{interval:this.getAttribute("interval"),is_currency:e});for(let a=0;a} intervals Intervals data object returned from Reports API.\n\t\t * @param {Array} fields Fields/metrices to be extracted from the reponse.\n\t\t * @param {Array} params Parameters to be forwarded, to be forwarded to drawGraph.\n\t\t */\n\t\tdrawGraphFromAnalyticsAPI( container, intervals, fields, params ) {\n\t\t\tconst translated = [];\n\t\t\tfor ( const field of fields ) {\n\t\t\t\ttranslated.push(\n\t\t\t\t\tintervals.map( ( row ) => [\n\t\t\t\t\t\tnew Date( row.interval ).getTime(),\n\t\t\t\t\t\trow.subtotals[ field ],\n\t\t\t\t\t] )\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn self.drawGraph( container, translated, params );\n\t\t},\n\n\t\tdrawGraph( container, data, params ) {\n\t\t\tconst $chart = $(\n\t\t\t\ttypeof container === 'string' ? '#' + container : container\n\t\t\t);\n\t\t\tconst sets = [];\n\t\t\tconst setColors = [ '#3498db', '#d0a0e4', '#72c9b2' ];\n\n\t\t\t_.each( data, function ( values, index ) {\n\t\t\t\tconst set = {\n\t\t\t\t\tlabel: '',\n\t\t\t\t\tdata: values,\n\t\t\t\t\tcolor: setColors.shift(),\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\tshow: true,\n\t\t\t\t\t\tradius: 3,\n\t\t\t\t\t\tlineWidth: 2,\n\t\t\t\t\t\tfillColor: '#ffffff',\n\t\t\t\t\t\tfill: true,\n\t\t\t\t\t},\n\t\t\t\t\tlines: {\n\t\t\t\t\t\tshow: true,\n\t\t\t\t\t\tlineWidth: 2,\n\t\t\t\t\t\tfill: true,\n\t\t\t\t\t\tfillColor: {\n\t\t\t\t\t\t\tcolors: [ { opacity: 0.02 }, { opacity: 0.16 } ],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tshadowSize: 0,\n\t\t\t\t\tisCurrency:\n\t\t\t\t\t\tparams.is_currency === true ||\n\t\t\t\t\t\t( params.is_currency && params.is_currency[ index ] ),\n\t\t\t\t};\n\n\t\t\t\tif ( _.size( data ) > 1 ) {\n\t\t\t\t\tset.lines.fill = false;\n\t\t\t\t}\n\n\t\t\t\tsets.push( set );\n\t\t\t} );\n\n\t\t\tconst options = {\n\t\t\t\tlegend: {\n\t\t\t\t\tshow: false,\n\t\t\t\t},\n\t\t\t\tgrid: {\n\t\t\t\t\tcolor: '#aaa',\n\t\t\t\t\tborderColor: 'transparent',\n\t\t\t\t\tborderWidth: 0,\n\t\t\t\t\thoverable: true,\n\t\t\t\t},\n\t\t\t\txaxis: {\n\t\t\t\t\tcolor: '#e5e5e5',\n\t\t\t\t\tposition: 'bottom',\n\t\t\t\t\ttickColor: 'transparent',\n\t\t\t\t\tmode: 'time',\n\t\t\t\t\tmonthNames: AW.params.locale.month_abbrev,\n\t\t\t\t\ttickLength: 1,\n\t\t\t\t\tfont: {\n\t\t\t\t\t\tcolor: '#aaa',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tyaxis: {\n\t\t\t\t\tcolor: '#fff',\n\t\t\t\t\tfont: {\n\t\t\t\t\t\tcolor: '#fff',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tif ( Number( params.interval ) === 30 ) {\n\t\t\t\toptions.xaxis.minTickSize = [ 4, 'day' ];\n\t\t\t}\n\n\t\t\t$.plot( $chart, sets, options );\n\n\t\t\t$chart.on( 'plothover', function ( event, pos, item ) {\n\t\t\t\tconst $wrap = $chart.parents(\n\t\t\t\t\t'.automatewoo-dashboard-chart:first'\n\t\t\t\t);\n\t\t\t\tconst $tooltip = $chart.siblings(\n\t\t\t\t\t'.automatewoo-dashboard-chart__tooltip:first'\n\t\t\t\t);\n\t\t\t\tconst wrapOffset = $wrap.offset();\n\n\t\t\t\tif ( item && item.series.points.show ) {\n\t\t\t\t\tlet content = item.datapoint[ 1 ];\n\n\t\t\t\t\tif ( item.series.isCurrency ) {\n\t\t\t\t\t\tcontent = AW.price( content );\n\t\t\t\t\t}\n\n\t\t\t\t\t$tooltip\n\t\t\t\t\t\t.html( content )\n\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\ttop: item.pageY - 9 - wrapOffset.top,\n\t\t\t\t\t\t\tleft: item.pageX + 12 - wrapOffset.left,\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.fadeIn( 200 );\n\t\t\t\t} else {\n\t\t\t\t\t$tooltip.hide();\n\t\t\t\t}\n\t\t\t} );\n\t\t},\n\t};\n\n\tAW.Dashboard = self;\n\tself.init();\n\n\t// This is overly simplified implementation. Follows the behavior of the previous jQuery widget.\n\t// The element\n\t// - Don't observe nor react to attribute changes.\n\t// - Assumes upgrade scenario - attributes are already set once the element is connected;\n\t//\t\tentire light DOM content is well structured and already present.\n\t// - Do not stop, abort, or bother about `fetch` races if the element is reconnected.\n\twindow.customElements.define(\n\t\t'automatewoo-dashboard-chart',\n\t\tclass AWDashboardChart extends HTMLElement {\n\t\t\tconnectedCallback() {\n\t\t\t\tthis.setAttribute( 'aw-loading', '' );\n\n\t\t\t\tconst fields = this.getAttribute( 'fields' ).split( ',' );\n\t\t\t\tconst isCurrency = JSON.parse(\n\t\t\t\t\t`[${ this.getAttribute( 'is-currency' ) || '' }]`\n\t\t\t\t);\n\n\t\t\t\tconst requestParams = new URLSearchParams( {\n\t\t\t\t\tinterval: 'day',\n\t\t\t\t\tafter: this.getAttribute( 'after' ),\n\t\t\t\t\tbefore: this.getAttribute( 'before' ),\n\t\t\t\t\tfields,\n\t\t\t\t\tper_page: 100,\n\t\t\t\t} );\n\t\t\t\twp.apiFetch( {\n\t\t\t\t\tpath:\n\t\t\t\t\t\tthis.getAttribute( 'endpoint' ) +\n\t\t\t\t\t\t'?' +\n\t\t\t\t\t\trequestParams.toString(),\n\t\t\t\t} ).then( ( response ) => {\n\t\t\t\t\tthis.removeAttribute( 'aw-loading' );\n\t\t\t\t\t// Draw chart.\n\t\t\t\t\tAW.Dashboard.drawGraphFromAnalyticsAPI(\n\t\t\t\t\t\tthis.querySelector(\n\t\t\t\t\t\t\t'automatewoo-dashboard-chart__flot'\n\t\t\t\t\t\t),\n\t\t\t\t\t\tresponse.intervals,\n\t\t\t\t\t\tfields,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinterval: this.getAttribute( 'interval' ),\n\t\t\t\t\t\t\tis_currency: isCurrency,\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\t// Fill totals.\n\t\t\t\t\tfor ( let index = 0; index < fields.length; index++ ) {\n\t\t\t\t\t\tconst key = fields[ index ];\n\t\t\t\t\t\tthis.querySelector(\n\t\t\t\t\t\t\t`automatewoo-dashboard-chart__header-figure[name=${ key }]`\n\t\t\t\t\t\t).innerHTML = isCurrency[ index ]\n\t\t\t\t\t\t\t? AW.price( response.totals[ key ] )\n\t\t\t\t\t\t\t: response.totals[ key ];\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t);\n} )( jQuery );\n"],"names":["$","self","$el","params","init","automatewooDashboardLocalizeScript","initMasonry","masonry","itemSelector","columnWidth","percentPosition","gutter","transitionDuration","drawGraphFromAnalyticsAPI","container","intervals","fields","translated","field","push","map","row","Date","interval","getTime","subtotals","drawGraph","data","$chart","sets","setColors","_","each","values","index","set","label","color","shift","points","show","radius","lineWidth","fillColor","fill","lines","colors","opacity","shadowSize","isCurrency","is_currency","size","options","legend","grid","borderColor","borderWidth","hoverable","xaxis","position","tickColor","mode","monthNames","AW","locale","month_abbrev","tickLength","font","yaxis","Number","minTickSize","plot","on","event","pos","item","$wrap","parents","$tooltip","siblings","wrapOffset","offset","series","content","datapoint","price","html","css","top","pageY","left","pageX","fadeIn","hide","Dashboard","window","customElements","define","HTMLElement","connectedCallback","this","setAttribute","getAttribute","split","JSON","parse","requestParams","URLSearchParams","after","before","per_page","wp","apiFetch","path","toString","then","response","removeAttribute","querySelector","length","key","innerHTML","totals","jQuery"],"sourceRoot":""} \ No newline at end of file diff --git a/admin/assets/js/min/modal.min.js b/admin/assets/js/min/modal.min.js new file mode 100644 index 0000000..3eb10ba --- /dev/null +++ b/admin/assets/js/min/modal.min.js @@ -0,0 +1,2 @@ +AutomateWoo.Modal={triggerClasses:{close:"js-close-automatewoo-modal",openLink:"js-open-automatewoo-modal"}},jQuery((function(o){Object.assign(AutomateWoo.Modal,{init(){const t=o(document.body);t.on("click",`.${this.triggerClasses.close}`,(()=>{this.close("dismiss")})),t.on("click",".automatewoo-modal-overlay",(()=>{this.close("dismiss")})),t.on("click",`.${this.triggerClasses.openLink}`,this.handle_link),o(document).on("keydown",(function(o){27===o.keyCode&&AutomateWoo.Modal.close("dismiss")}))},handle_link(t){t.preventDefault();const a=o(this),e=a.data("automatewoo-modal-size");AutomateWoo.Modal.open(e),AutomateWoo.Modal.loading(),o.post(a.attr("href"),{},(function(o){AutomateWoo.Modal.contents(o)}))},open(t){let a="";t&&(a="automatewoo-modal--size-"+t),document.body.classList.add("automatewoo-modal-open"),o(document.body).append(`
`)},loading(){document.body.classList.add("automatewoo-modal-loading")},contents(t){document.body.classList.remove("automatewoo-modal-loading"),o(".automatewoo-modal__contents").html(t),AW.initTooltips()},close(t=""){document.body.classList.remove("automatewoo-modal-open","automatewoo-modal-loading"),o(".automatewoo-modal-container").remove();const a=new CustomEvent("awmodal-close",{detail:{closedBy:t}});document.body.dispatchEvent(a)}}),AutomateWoo.Modal.init()})); +//# sourceMappingURL=modal.min.js.map \ No newline at end of file diff --git a/admin/assets/js/min/modal.min.js.map b/admin/assets/js/min/modal.min.js.map new file mode 100644 index 0000000..e1e10c5 --- /dev/null +++ b/admin/assets/js/min/modal.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"modal.min.js","mappings":"AAMAA,YAAYC,MAAQ,CAInBC,eAAgB,CAEfC,MAAO,6BAIPC,SAAU,8BAGZC,QAAQ,SAAWC,GAClBC,OAAOC,OAAQR,YAAYC,MAAO,CACjC,IAAAQ,GACC,MAAMC,EAAQJ,EAAGK,SAASC,MAC1BF,EAAMG,GAAI,QAAS,IAAKC,KAAKZ,eAAeC,SAAU,KACrDW,KAAKX,MAAO,UAAW,IAExBO,EAAMG,GAAI,QAAS,8BAA8B,KAChDC,KAAKX,MAAO,UAAW,IAExBO,EAAMG,GACL,QACA,IAAKC,KAAKZ,eAAeE,WACzBU,KAAKC,aAGNT,EAAGK,UAAWE,GAAI,WAAW,SAAWG,GACpB,KAAdA,EAAEC,SACNjB,YAAYC,MAAME,MAAO,UAE3B,GACD,EAEA,WAAAY,CAAaC,GACZA,EAAEE,iBAEF,MAAMC,EAAKb,EAAGQ,MACRM,EAAOD,EAAGE,KAAM,0BAEtBrB,YAAYC,MAAMqB,KAAMF,GACxBpB,YAAYC,MAAMsB,UAElBjB,EAAEkB,KAAML,EAAGM,KAAM,QAAU,CAAC,GAAG,SAAWC,GACzC1B,YAAYC,MAAM0B,SAAUD,EAC7B,GACD,EAEA,IAAAJ,CAAMF,GACL,IAAIQ,EAAY,GAEXR,IACJQ,EAAY,2BAA6BR,GAG1CT,SAASC,KAAKiB,UAAUC,IAAK,0BAE7BxB,EAAGK,SAASC,MAAOmB,OAClB,wHAAyHH,qIAA+Id,KAAKZ,eAAeC,4BAE9R,EAEA,OAAAoB,GACCZ,SAASC,KAAKiB,UAAUC,IAAK,4BAC9B,EAEA,QAAAH,CAAUA,GACThB,SAASC,KAAKiB,UAAUG,OAAQ,6BAChC1B,EAAG,gCAAiC2B,KAAMN,GAE1CO,GAAGC,cACJ,EASA,KAAAhC,CAAOiC,EAAW,IACjBzB,SAASC,KAAKiB,UAAUG,OACvB,yBACA,6BAED1B,EAAG,gCAAiC0B,SAEpC,MACMK,EAAa,IAAIC,YAAa,gBAAiB,CAAEC,OADxC,CAAEH,cAGjBzB,SAASC,KAAK4B,cAAeH,EAC9B,IAGDrC,YAAYC,MAAMQ,MACnB","sources":["webpack://automatewoo/./admin/assets/js/modal.js"],"sourcesContent":["// Register eslint ignored glabals - to be revisited.\n// https://github.com/woocommerce/automatewoo/issues/1212\n/* global AutomateWoo, AW */\n/**\n * AutomateWoo Modal\n */\nAutomateWoo.Modal = {\n\t/**\n\t * A set of classes to be used to interact with the modal singleton.\n\t */\n\ttriggerClasses: {\n\t\t/** Clicking on such element closes the modal. */\n\t\tclose: 'js-close-automatewoo-modal',\n\t\t/**\n\t\t * To be used on `HTMLAnchorElement`, to load ajax content fetched from `href`.\n\t\t */\n\t\topenLink: 'js-open-automatewoo-modal',\n\t},\n};\njQuery( function ( $ ) {\n\tObject.assign( AutomateWoo.Modal, {\n\t\tinit() {\n\t\t\tconst $body = $( document.body );\n\t\t\t$body.on( 'click', `.${ this.triggerClasses.close }`, () => {\n\t\t\t\tthis.close( 'dismiss' );\n\t\t\t} );\n\t\t\t$body.on( 'click', '.automatewoo-modal-overlay', () => {\n\t\t\t\tthis.close( 'dismiss' );\n\t\t\t} );\n\t\t\t$body.on(\n\t\t\t\t'click',\n\t\t\t\t`.${ this.triggerClasses.openLink }`,\n\t\t\t\tthis.handle_link\n\t\t\t);\n\n\t\t\t$( document ).on( 'keydown', function ( e ) {\n\t\t\t\tif ( e.keyCode === 27 ) {\n\t\t\t\t\tAutomateWoo.Modal.close( 'dismiss' );\n\t\t\t\t}\n\t\t\t} );\n\t\t},\n\n\t\thandle_link( e ) {\n\t\t\te.preventDefault();\n\n\t\t\tconst $a = $( this );\n\t\t\tconst size = $a.data( 'automatewoo-modal-size' );\n\n\t\t\tAutomateWoo.Modal.open( size );\n\t\t\tAutomateWoo.Modal.loading();\n\n\t\t\t$.post( $a.attr( 'href' ), {}, function ( response ) {\n\t\t\t\tAutomateWoo.Modal.contents( response );\n\t\t\t} );\n\t\t},\n\n\t\topen( size ) {\n\t\t\tlet sizeClass = '';\n\n\t\t\tif ( size ) {\n\t\t\t\tsizeClass = 'automatewoo-modal--size-' + size;\n\t\t\t}\n\n\t\t\tdocument.body.classList.add( 'automatewoo-modal-open' );\n\n\t\t\t$( document.body ).append(\n\t\t\t\t`
`\n\t\t\t);\n\t\t},\n\n\t\tloading() {\n\t\t\tdocument.body.classList.add( 'automatewoo-modal-loading' );\n\t\t},\n\n\t\tcontents( contents ) {\n\t\t\tdocument.body.classList.remove( 'automatewoo-modal-loading' );\n\t\t\t$( '.automatewoo-modal__contents' ).html( contents );\n\n\t\t\tAW.initTooltips();\n\t\t},\n\n\t\t/**\n\t\t * Closes modal, by changin classes on `document.body` and removing modal elements.\n\t\t *\n\t\t * @param {string} [closedBy=''] - Identifier for what closed the modal which will be included in the event detail.\n\t\t *\n\t\t * @fires CustomEvent with event name 'awmodal-close' on the `document.body`.\n\t\t */\n\t\tclose( closedBy = '' ) {\n\t\t\tdocument.body.classList.remove(\n\t\t\t\t'automatewoo-modal-open',\n\t\t\t\t'automatewoo-modal-loading'\n\t\t\t);\n\t\t\t$( '.automatewoo-modal-container' ).remove();\n\n\t\t\tconst detail = { closedBy };\n\t\t\tconst modalClose = new CustomEvent( 'awmodal-close', { detail } );\n\n\t\t\tdocument.body.dispatchEvent( modalClose );\n\t\t},\n\t} );\n\n\tAutomateWoo.Modal.init();\n} );\n"],"names":["AutomateWoo","Modal","triggerClasses","close","openLink","jQuery","$","Object","assign","init","$body","document","body","on","this","handle_link","e","keyCode","preventDefault","$a","size","data","open","loading","post","attr","response","contents","sizeClass","classList","add","append","remove","html","AW","initTooltips","closedBy","modalClose","CustomEvent","detail","dispatchEvent"],"sourceRoot":""} \ No newline at end of file diff --git a/admin/assets/js/min/preview.min.js b/admin/assets/js/min/preview.min.js new file mode 100644 index 0000000..d2bfa4a --- /dev/null +++ b/admin/assets/js/min/preview.min.js @@ -0,0 +1,2 @@ +jQuery((function(e){function a(){e(".aw-preview__email-iframe").height(e(window).height()-e(".aw-preview__header").outerHeight())}e("form.aw-preview__send-test-form").on("submit",(function(a){a.preventDefault();const n=e(this);n.addClass("aw-loading"),n.find("button").trigger("blur");const t={action:"aw_send_test_email",type:n.find('[name="type"]').val(),to_emails:n.find('[name="to_emails"]').val(),args:JSON.parse(n.find('[name="args"]').val()),nonce:automatewooPreviewLocalizeScript.nonce};return e.post(ajaxurl,t,(function(e){alert(e.data.message),n.removeClass("aw-loading")})),!1})),a(),e(window).on("resize",(function(){a()}))})); +//# sourceMappingURL=preview.min.js.map \ No newline at end of file diff --git a/admin/assets/js/min/preview.min.js.map b/admin/assets/js/min/preview.min.js.map new file mode 100644 index 0000000..014180e --- /dev/null +++ b/admin/assets/js/min/preview.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"preview.min.js","mappings":"AAGAA,QAAQ,SAAWC,GAClB,SAASC,IACRD,EAAG,6BAA8BE,OAChCF,EAAGG,QAASD,SAAWF,EAAG,uBAAwBI,cAEpD,CAEAJ,EAAG,mCAAoCK,GAAI,UAAU,SAAWC,GAC/DA,EAAEC,iBAEF,MAAMC,EAAQR,EAAGS,MAEjBD,EAAME,SAAU,cAChBF,EAAMG,KAAM,UAAWC,QAAS,QAEhC,MAAMC,EAAO,CACZC,OAAQ,qBACRC,KAAMP,EAAMG,KAAM,iBAAkBK,MACpCC,UAAWT,EAAMG,KAAM,sBAAuBK,MAC9CE,KAAMC,KAAKC,MAAOZ,EAAMG,KAAM,iBAAkBK,OAChDK,MAAOC,iCAAiCD,OASzC,OANArB,EAAEuB,KAAMC,QAASX,GAAM,SAAWY,GAEjCC,MAAOD,EAASZ,KAAKc,SACrBnB,EAAMoB,YAAa,aACpB,KAEO,CACR,IAMC3B,IAEAD,EAAGG,QAASE,GAAI,UAAU,WACzBJ,GACD,GAIF","sources":["webpack://automatewoo/./admin/assets/js/preview.js"],"sourcesContent":["// Register eslint ignored glabals - to be revisited.\n// https://github.com/woocommerce/automatewoo/issues/1212\n/* global ajaxurl, alert, automatewooPreviewLocalizeScript */\njQuery( function ( $ ) {\n\tfunction setIframeHeight() {\n\t\t$( '.aw-preview__email-iframe' ).height(\n\t\t\t$( window ).height() - $( '.aw-preview__header' ).outerHeight()\n\t\t);\n\t}\n\n\t$( 'form.aw-preview__send-test-form' ).on( 'submit', function ( e ) {\n\t\te.preventDefault();\n\n\t\tconst $form = $( this );\n\n\t\t$form.addClass( 'aw-loading' );\n\t\t$form.find( 'button' ).trigger( 'blur' );\n\n\t\tconst data = {\n\t\t\taction: 'aw_send_test_email',\n\t\t\ttype: $form.find( '[name=\"type\"]' ).val(),\n\t\t\tto_emails: $form.find( '[name=\"to_emails\"]' ).val(),\n\t\t\targs: JSON.parse( $form.find( '[name=\"args\"]' ).val() ),\n\t\t\tnonce: automatewooPreviewLocalizeScript.nonce,\n\t\t};\n\n\t\t$.post( ajaxurl, data, function ( response ) {\n\t\t\t// eslint-disable-next-line no-alert -- Pre eslint introduction code, to be revised.\n\t\t\talert( response.data.message );\n\t\t\t$form.removeClass( 'aw-loading' );\n\t\t} );\n\n\t\treturn false;\n\t} );\n\n\t/**\n\t * Init\n\t */\n\tfunction init() {\n\t\tsetIframeHeight();\n\n\t\t$( window ).on( 'resize', function () {\n\t\t\tsetIframeHeight();\n\t\t} );\n\t}\n\n\tinit();\n} );\n"],"names":["jQuery","$","setIframeHeight","height","window","outerHeight","on","e","preventDefault","$form","this","addClass","find","trigger","data","action","type","val","to_emails","args","JSON","parse","nonce","automatewooPreviewLocalizeScript","post","ajaxurl","response","alert","message","removeClass"],"sourceRoot":""} \ No newline at end of file diff --git a/admin/assets/js/min/rules.min.js b/admin/assets/js/min/rules.min.js new file mode 100644 index 0000000..557c92c --- /dev/null +++ b/admin/assets/js/min/rules.min.js @@ -0,0 +1,2 @@ +!function(e,t){AW.Rules=Backbone.Model.extend({initialize(){const e=[];this.get("rawRuleOptions")&&_.each(this.get("rawRuleOptions"),(t=>{const s=new AW.RuleGroup(this),i=[];_.each(t,(function(e){const t=new AW.Rule(s);t.set("name",e.name),t.resetOptions(),t.set("compare",e.compare),t.set("value",e.value),e.selected&&t.set("selected",e.selected),i.push(t)})),s.set("rules",i),e.push(s)})),this.set("ruleOptions",e),this.resetAvailableRules()},defaults(){return{allRules:{},availableRules:{},ruleOptions:[]}},resetAvailableRules(){const e=AW.workflow.get("trigger");this.set("availableRules",_.filter(this.get("allRules"),(function(t){return e&&-1!==e.supplied_data_items.indexOf(t.data_item)})));const t={};_.each(this.get("availableRules"),(function(e){t[e.group]||(t[e.group]=[]),t[e.group].push(e)})),this.set("groupedRules",t)},isRuleAvailable(e){const t=AW.rules.get("availableRules"),s=_.pluck(t,"name");return-1!==_.indexOf(s,e)},clearIncompatibleRules(){const e=[];_.each(AW.rules.get("ruleOptions"),(function(t){_.each(t.get("rules"),(function(t){t&&!AW.rules.isRuleAvailable(t.get("name"))&&e.push(t)}))})),_.each(e,(function(e){e.clear()}))},createGroup(){const e=this.get("ruleOptions"),t=new AW.RuleGroup(this);return t.createRule(),e.push(t),this.set("ruleOptions",e),this.trigger("ruleGroupChange"),t},removeGroup(e){const t=this.get("ruleOptions"),s=t.map((function(e){return e.id})).indexOf(e);t[s].destroy(),t.splice(s,1),this.set("ruleOptions",t),this.trigger("ruleGroupChange")}}),AW.Rule=Backbone.Model.extend({initialize(e){this.set("id",_.uniqueId("rule_")),this.set("group",e),this.resetOptions()},getRuleObject(){return t.allRules[this.get("name")]},resetOptions(){const e=this.get("name"),t=this.getRuleObject();return e?this.set("object",t):this.set("object",{}),this.set("compare",!1),this.set("value",!1),this.loadSelectOptions(),this},loadSelectOptions(){const t=this.getRuleObject();return!t||"select"!==t.type||t.select_choices||(this.set("isValueLoading",!0),e.getJSON(ajaxurl,{action:"aw_get_rule_select_choices",rule_name:t.name},(e=>{e.success&&(t.select_choices=e.data.select_choices,this.set("isValueLoading",!1),this.set("object",t),this.trigger("optionsLoaded"))}))),this},clear(){this.get("group").removeRule(this.id)},destroy(){this.trigger("destroy")}}),AW.RuleGroup=Backbone.Model.extend({initialize(e){this.set("id",_.uniqueId("rule_group_")),this.set("app",e),this.set("rules",[])},createRule(){const e=this.get("rules"),t=new AW.Rule(this);return e.push(t),this.set("rules",e),t},removeRule(e){const t=this.get("rules"),s=t.map((function(e){return e.id})).indexOf(e);t.length>1?(t[s].destroy(),t.splice(s,1),this.set("rules",t)):(t[s].destroy(),this.clear())},clear(){this.get("app").removeGroup(this.id)},destroy(){this.trigger("destroy")}}),AW.RuleView=Backbone.View.extend({className:"automatewoo-rule-container",template:wp.template("aw-rule"),events:{"change .js-rule-select":"updatedName","change .js-rule-compare-field":"updatedCompare","change .js-rule-value-field":"updatedValue","click .js-remove-rule":"clear","change .js-rule-value-from":"updateMinFromValueDate"},initialize(){this.listenTo(this.model,"change:id",this.render),this.listenTo(this.model,"change:group",this.render),this.listenTo(this.model,"optionsLoaded",this.render),this.listenTo(this.model,"destroy",this.remove)},render(){return this.$el.html(this.template({rule:this.model.toJSON(),groupedRules:AW.rules.get("groupedRules"),fieldNameBase:this.getFieldNameBase()})),this.setName(),this.setCompare(),this.setValue(),this.maybeToggleValueDisplay(),this.initDatepicker(),e(document.body).trigger("wc-enhanced-select-init"),this},setName(){this.$el.find(".js-rule-select").val(this.model.get("name"))},setCompare(){const e=this.$el.find(".js-rule-compare-field"),t=this.model.get("compare");if(e.filter("select").length&&!t){const t=e.find("option:first-child"),s=e.find("option:first-child").prop("value");t.prop("selected",!0),e.val(s),this.model.set("compare",s)}t&&(e.val(t),e.find('option[value~="'+t+'"]').prop("selected",!0))},setValue(){const t=this.model.get("selected"),s=this.model.get("value");let i;if(t&&(i=this.$el.find(".js-rule-value-field"),i.is("select")?_.isArray(s)?_.each(s,(function(s,l){i.append(e("